snapshot of https://github.com/ThreeDotsLabs/watermill.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
master / ci (push) Failing after 0s
Some checks failed
master / ci (push) Failing after 0s
This commit is contained in:
92
components/metrics/handler.go
Normal file
92
components/metrics/handler.go
Normal file
@@ -0,0 +1,92 @@
|
||||
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
|
||||
additionalLabels []MetricLabel
|
||||
}
|
||||
|
||||
// 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),
|
||||
}
|
||||
for _, lb := range m.additionalLabels {
|
||||
labels[lb.Label] = lb.ComputeValueFn(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{
|
||||
additionalLabels: b.additionalLabels,
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
toLabelsSlice(handlerLabelKeys, b.additionalLabels),
|
||||
))
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "could not register handler execution time metric"))
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
Reference in New Issue
Block a user