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