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  }