github.com/avenga/couper@v1.12.2/handler/middleware/metrics.go (about) 1 package middleware 2 3 import ( 4 "net/http" 5 "time" 6 7 "go.opentelemetry.io/otel/attribute" 8 "go.opentelemetry.io/otel/metric/instrument" 9 "go.opentelemetry.io/otel/metric/unit" 10 11 "github.com/avenga/couper/logging" 12 "github.com/avenga/couper/telemetry/instrumentation" 13 "github.com/avenga/couper/telemetry/provider" 14 ) 15 16 type MetricsHandler struct { 17 handler http.Handler 18 } 19 20 func NewMetricsHandler() Next { 21 return func(handler http.Handler) *NextHandler { 22 return NewHandler(&MetricsHandler{ 23 handler: handler, 24 }, handler) 25 } 26 } 27 28 func (mh *MetricsHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { 29 start := time.Now() 30 mh.handler.ServeHTTP(rw, req) 31 end := time.Since(start) 32 33 metricsAttrs := []attribute.KeyValue{ 34 attribute.String("host", req.Host), 35 attribute.String("method", req.Method), 36 } 37 38 if rsw, ok := rw.(logging.RecorderInfo); ok { 39 metricsAttrs = append(metricsAttrs, attribute.Int("code", rsw.StatusCode())) 40 } 41 42 meter := provider.Meter("couper/server") 43 44 counter, _ := meter.SyncInt64(). 45 Counter(instrumentation.ClientRequest, 46 instrument.WithDescription(string(unit.Dimensionless))) 47 duration, _ := meter.SyncFloat64(). 48 Histogram(instrumentation.ClientRequestDuration, 49 instrument.WithDescription(string(unit.Dimensionless))) 50 51 counter.Add(req.Context(), 1, metricsAttrs...) 52 duration.Record(req.Context(), end.Seconds(), metricsAttrs...) 53 }