-
Notifications
You must be signed in to change notification settings - Fork 416
/
Copy pathhandler.go
86 lines (73 loc) · 2.1 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package metrics
import (
"time"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/ThreeDotsLabs/watermill/message"
)
var (
handlerLabelKeys = []string{
labelKeyHandlerName,
labelSuccess,
}
// defaultHandlerExecutionTimeBuckets are one order of magnitude smaller than default buckets (5ms~10s),
// because the handler execution times are typically shorter (µs~ms range).
defaultHandlerExecutionTimeBuckets = []float64{
0.0005,
0.001,
0.0025,
0.005,
0.01,
0.025,
0.05,
0.1,
0.25,
0.5,
1,
}
)
// HandlerPrometheusMetricsMiddleware is a middleware that captures Prometheus metrics.
type HandlerPrometheusMetricsMiddleware struct {
handlerExecutionTimeSeconds *prometheus.HistogramVec
}
// Middleware returns the middleware ready to be used with watermill's Router.
func (m HandlerPrometheusMetricsMiddleware) Middleware(h message.HandlerFunc) message.HandlerFunc {
return func(msg *message.Message) (msgs []*message.Message, err error) {
now := time.Now()
ctx := msg.Context()
labels := prometheus.Labels{
labelKeyHandlerName: message.HandlerNameFromCtx(ctx),
}
defer func() {
if err != nil {
labels[labelSuccess] = "false"
} else {
labels[labelSuccess] = "true"
}
m.handlerExecutionTimeSeconds.With(labels).Observe(time.Since(now).Seconds())
}()
return h(msg)
}
}
// NewRouterMiddleware returns new middleware.
func (b PrometheusMetricsBuilder) NewRouterMiddleware() HandlerPrometheusMetricsMiddleware {
var err error
m := HandlerPrometheusMetricsMiddleware{}
if b.HandlerBuckets == nil {
b.HandlerBuckets = defaultHandlerExecutionTimeBuckets
}
m.handlerExecutionTimeSeconds, err = b.registerHistogramVec(prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: b.Namespace,
Subsystem: b.Subsystem,
Name: "handler_execution_time_seconds",
Help: "The total time elapsed while executing the handler function in seconds",
Buckets: b.HandlerBuckets,
},
handlerLabelKeys,
))
if err != nil {
panic(errors.Wrap(err, "could not register handler execution time metric"))
}
return m
}