Skip to content

Commit 31192dc

Browse files
committed
Cleanup Prometheus metrics
1 parent 59a6214 commit 31192dc

File tree

8 files changed

+62
-40
lines changed

8 files changed

+62
-40
lines changed

bot/config/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ type Config struct {
4646
viper *viper.Viper `mapstructure:"-"`
4747
}
4848

49-
// LoadCustom does a dynamic config lookup with a given key and unmarshals it into the value
49+
// LoadCustom does a dynamic config lookup with a given key and unmarshal it into the value
5050
func (c *Config) LoadCustom(key string, value any) error {
5151
if c.viper == nil {
5252
return nil
5353
}
5454
return c.viper.UnmarshalKey(key, value)
5555
}
5656

57+
// Set a dynamic config value...please only set it in tests!
5758
func (c *Config) Set(key string, value any) {
5859
if c.viper == nil {
5960
c.viper = viper.New()

bot/config/metrics.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ type Metrics struct {
44
// e.g. use ":8082" to expose metrics on all interfaces
55
PrometheusListener string `mapstructure:"prometheus_listener"`
66
}
7+
8+
// IsEnabled returns true if the metrics are enabled by config
9+
func (c *Metrics) IsEnabled() bool {
10+
return c.PrometheusListener != ""
11+
}

bot/listener.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os/signal"
66
"syscall"
77

8+
"github.com/innogames/slack-bot/v2/bot/stats"
89
"github.com/innogames/slack-bot/v2/bot/util"
910
"github.com/innogames/slack-bot/v2/client"
1011
log "github.com/sirupsen/logrus"
@@ -13,18 +14,9 @@ import (
1314
"github.com/slack-go/slack/socketmode"
1415
)
1516

16-
func (b *Bot) startRunnables(ctx *util.ServerContext) {
17-
for _, cmd := range b.commands.commands {
18-
if runnable, ok := cmd.(Runnable); ok {
19-
go runnable.RunAsync(ctx)
20-
}
21-
}
22-
}
23-
2417
// Run is blocking method to handle new incoming events...from different sources
2518
func (b *Bot) Run(ctx *util.ServerContext) {
2619
b.startRunnables(ctx)
27-
initMetrics(b.config, ctx)
2820

2921
// initialize Socket Mode:
3022
// https://api.slack.com/apis/connections/socket
@@ -54,6 +46,19 @@ func (b *Bot) Run(ctx *util.ServerContext) {
5446
}
5547
}
5648

49+
// startRunnables starts all background tasks and ctx.StopTheWorld() will stop them then properly
50+
func (b *Bot) startRunnables(ctx *util.ServerContext) {
51+
// each command can have a background task which is executed in the background
52+
for _, cmd := range b.commands.commands {
53+
if runnable, ok := cmd.(Runnable); ok {
54+
go runnable.RunAsync(ctx)
55+
}
56+
}
57+
58+
// special handler which are executed in the background
59+
stats.InitMetrics(b.config, ctx)
60+
}
61+
5762
func (b *Bot) handleSocketModeEvent(event socketmode.Event) {
5863
if event.Request != nil && event.Type != socketmode.EventTypeHello {
5964
b.slackClient.Socket.Ack(*event.Request)

bot/metrics.go renamed to bot/stats/metrics.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
package bot
1+
package stats
22

33
import (
44
"net/http"
55
"strings"
66
"time"
77

88
"github.com/innogames/slack-bot/v2/bot/config"
9-
"github.com/innogames/slack-bot/v2/bot/stats"
109
"github.com/innogames/slack-bot/v2/bot/util"
1110
"github.com/prometheus/client_golang/prometheus"
1211
"github.com/prometheus/client_golang/prometheus/collectors"
@@ -23,19 +22,20 @@ func (c *statRegistry) Describe(_ chan<- *prometheus.Desc) {
2322

2423
// Collect returns the current state of all metrics of our slack-bot stats
2524
func (c *statRegistry) Collect(ch chan<- prometheus.Metric) {
26-
for _, key := range stats.GetKeys() {
27-
metric := prometheus.NewGauge(prometheus.GaugeOpts{
25+
for _, key := range GetKeys() {
26+
metric := prometheus.NewCounter(prometheus.CounterOpts{
2827
Namespace: "slack_bot",
2928
Name: strings.ReplaceAll(key, "-", "_"),
3029
})
31-
value, _ := stats.Get(key)
32-
metric.Set(float64(value))
30+
value, _ := Get(key)
31+
metric.Add(float64(value))
3332
metric.Collect(ch)
3433
}
3534
}
3635

37-
func initMetrics(cfg config.Config, ctx *util.ServerContext) {
38-
if cfg.Metrics.PrometheusListener == "" {
36+
func InitMetrics(cfg config.Config, ctx *util.ServerContext) {
37+
if !cfg.Metrics.IsEnabled() {
38+
// prometheus is disabled...skip here
3939
return
4040
}
4141

@@ -64,7 +64,10 @@ func initMetrics(cfg config.Config, ctx *util.ServerContext) {
6464
)
6565

6666
go func() {
67-
_ = server.ListenAndServe()
67+
err := server.ListenAndServe()
68+
if err != nil {
69+
log.Warnf("Failed to start prometheus server: %s", err)
70+
}
6871
}()
6972

7073
<-ctx.Done()

bot/metrics_test.go renamed to bot/stats/metrics_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package bot
1+
package stats
22

33
import (
44
"io"
@@ -8,7 +8,6 @@ import (
88
"time"
99

1010
"github.com/innogames/slack-bot/v2/bot/config"
11-
"github.com/innogames/slack-bot/v2/bot/stats"
1211
"github.com/innogames/slack-bot/v2/bot/util"
1312

1413
"github.com/stretchr/testify/assert"
@@ -26,9 +25,9 @@ func TestMetrics(t *testing.T) {
2625
},
2726
}
2827

29-
stats.Set("test_value", 500)
28+
Set("test_value", 500)
3029

31-
initMetrics(cfg, ctx)
30+
InitMetrics(cfg, ctx)
3231
time.Sleep(time.Millisecond * 100)
3332

3433
resp, err := http.Get("http://" + metricsPort + "/metrics")

bot/stats/stats_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ func TestStats(t *testing.T) {
2626
assert.Nil(t, err)
2727
assert.Equal(t, value, uint(42))
2828

29-
Increase("test", 2)
29+
Increase("test", int64(1))
30+
Increase("test", int8(1))
31+
Increase("test", 1)
3032
value, err = Get("test")
3133
assert.Nil(t, err)
32-
assert.Equal(t, value, uint(44))
34+
assert.Equal(t, value, uint(45))
3335

3436
IncreaseOne("test")
3537
value, err = Get("test")
3638
assert.Nil(t, err)
37-
assert.Equal(t, value, uint(45))
39+
assert.Equal(t, value, uint(46))
3840
}

command/openai/chatgpt.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package openai
33
import (
44
"bufio"
55
"encoding/json"
6+
"fmt"
67
"io"
78
"net/http"
89
"strings"
@@ -42,12 +43,15 @@ func CallChatGPT(cfg Config, inputMessages []ChatMessage, stream bool) (<-chan s
4243
var chatResponse ChatResponse
4344
err = json.Unmarshal(body, &chatResponse)
4445
if err != nil {
45-
messageUpdates <- err.Error()
46+
log.Warnf("Openai Error %d: %s", resp.StatusCode, err)
47+
48+
messageUpdates <- fmt.Sprintf("Error %d: %s", resp.StatusCode, err)
4649
return
4750
}
4851

4952
if err = chatResponse.GetError(); err != nil {
50-
messageUpdates <- chatResponse.GetError().Error()
53+
log.Warn("Openai Error: ", err, chatResponse, body)
54+
messageUpdates <- err.Error()
5155
return
5256
}
5357

command/openai/command.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -241,24 +241,27 @@ func (c *chatGPTCommand) callAndStore(messages []ChatMessage, storageIdentifier
241241
log.Warnf("Error while storing openai history: %s", err)
242242
}
243243

244+
// log some stats in the end
245+
outputTokens := estimateTokensForMessage(responseText.String())
244246
stats.IncreaseOne("openai_calls")
245247
stats.Increase("openai_input_tokens", inputTokens)
246-
stats.Increase("openai_output_tokens", estimateTokensForMessage(responseText.String()))
248+
stats.Increase("openai_output_tokens", outputTokens)
247249

248-
log.Infof(
249-
"Openai %s call took %s with %d sub messages (%d tokens).",
250-
c.cfg.Model,
250+
logFields := log.Fields{
251+
"input_tokens": inputTokens,
252+
"output_tokens": outputTokens,
253+
"model": c.cfg.Model,
254+
}
255+
if c.cfg.LogTexts {
256+
logFields["input_text"] = inputText
257+
logFields["output_text"] = responseText.String()
258+
}
259+
260+
log.WithFields(logFields).Infof(
261+
"Openai call took %s with %d context messages.",
251262
util.FormatDuration(time.Since(startTime)),
252263
len(messages),
253-
inputTokens,
254264
)
255-
if c.cfg.LogTexts {
256-
log.Infof(
257-
"Openai texts. Input: '%s'. Response: '%s'",
258-
inputText,
259-
responseText.String(),
260-
)
261-
}
262265
}()
263266
}
264267

0 commit comments

Comments
 (0)