forked from tangled.org/core
this repo has no description
1package telemetry 2 3import ( 4 "fmt" 5 "net/http" 6 "time" 7 8 "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" 9 otelmetric "go.opentelemetry.io/otel/metric" 10 "go.opentelemetry.io/otel/semconv/v1.13.0/httpconv" 11) 12 13func (t *Telemetry) RequestDuration() func(next http.Handler) http.Handler { 14 const ( 15 metricNameRequestDurationMs = "request_duration_millis" 16 metricUnitRequestDurationMs = "ms" 17 metricDescRequestDurationMs = "Measures the latency of HTTP requests processed by the server, in milliseconds." 18 ) 19 histogram, err := t.meter.Int64Histogram( 20 metricNameRequestDurationMs, 21 otelmetric.WithDescription(metricDescRequestDurationMs), 22 otelmetric.WithUnit(metricUnitRequestDurationMs), 23 ) 24 if err != nil { 25 panic(fmt.Sprintf("unable to create %s histogram: %v", metricNameRequestDurationMs, err)) 26 } 27 28 return func(next http.Handler) http.Handler { 29 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 30 // capture the start time of the request 31 startTime := time.Now() 32 33 // execute next http handler 34 next.ServeHTTP(w, r) 35 36 // record the request duration 37 duration := time.Since(startTime) 38 histogram.Record( 39 r.Context(), 40 int64(duration.Milliseconds()), 41 otelmetric.WithAttributes( 42 httpconv.ServerRequest(t.serviceName, r)..., 43 ), 44 ) 45 }) 46 } 47} 48 49func (t *Telemetry) RequestInFlight() func(next http.Handler) http.Handler { 50 const ( 51 metricNameRequestInFlight = "request_in_flight" 52 metricDescRequestInFlight = "Measures the number of concurrent HTTP requests being processed by the server." 53 metricUnitRequestInFlight = "1" 54 ) 55 56 // counter to capture requests in flight 57 counter, err := t.meter.Int64UpDownCounter( 58 metricNameRequestInFlight, 59 otelmetric.WithDescription(metricDescRequestInFlight), 60 otelmetric.WithUnit(metricUnitRequestInFlight), 61 ) 62 if err != nil { 63 panic(fmt.Sprintf("unable to create %s counter: %v", metricNameRequestInFlight, err)) 64 } 65 66 return func(next http.Handler) http.Handler { 67 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 68 attrs := otelmetric.WithAttributes(httpconv.ServerRequest(t.serviceName, r)...) 69 70 // increase the number of requests in flight 71 counter.Add(r.Context(), 1, attrs) 72 73 // execute next http handler 74 next.ServeHTTP(w, r) 75 76 // decrease the number of requests in flight 77 counter.Add(r.Context(), -1, attrs) 78 }) 79 } 80} 81 82func (t *Telemetry) WithRouteTag() func(next http.Handler) http.Handler { 83 return func(next http.Handler) http.Handler { 84 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 85 otelhttp.WithRouteTag(r.URL.Path, next) 86 }) 87 } 88}