gitlab.com/gitlab-org/labkit@v1.21.0/metrics/handler.go (about) 1 package metrics 2 3 import ( 4 "net/http" 5 6 "github.com/prometheus/client_golang/prometheus" 7 "github.com/prometheus/client_golang/prometheus/promhttp" 8 ) 9 10 // Metric names for the recorded metrics. 11 // These are the conventional names prometheus uses for these metrics. 12 const ( 13 httpInFlightRequestsMetricName = "in_flight_requests" 14 httpRequestsTotalMetricName = "requests_total" 15 httpRequestDurationSecondsMetricName = "request_duration_seconds" 16 httpRequestSizeBytesMetricName = "request_size_bytes" 17 httpResponseSizeBytesMetricName = "response_size_bytes" 18 httpTimeToWriteHeaderSecondsMetricName = "time_to_write_header_seconds" 19 ) 20 21 // HandlerFactory creates handler middleware instances. Created by NewHandlerFactory. 22 type HandlerFactory func(next http.Handler, opts ...HandlerOption) http.Handler 23 24 // NewHandlerFactory will create a function for creating metric middlewares. 25 // The resulting function can be called multiple times to obtain multiple middleware 26 // instances. 27 // Each instance can be configured with different options that will be applied to the 28 // same underlying metrics. 29 func NewHandlerFactory(opts ...HandlerFactoryOption) HandlerFactory { 30 factoryConfig := applyHandlerFactoryOptions(opts) 31 var ( 32 httpInFlightRequests = prometheus.NewGauge(prometheus.GaugeOpts{ 33 Namespace: factoryConfig.namespace, 34 Subsystem: factoryConfig.subsystem, 35 Name: httpInFlightRequestsMetricName, 36 Help: "A gauge of requests currently being served by the http server.", 37 }) 38 39 httpRequestsTotal = prometheus.NewCounterVec( 40 prometheus.CounterOpts{ 41 Namespace: factoryConfig.namespace, 42 Subsystem: factoryConfig.subsystem, 43 Name: httpRequestsTotalMetricName, 44 Help: "A counter for requests to the http server.", 45 }, 46 factoryConfig.labels, 47 ) 48 49 httpRequestDurationSeconds = prometheus.NewHistogramVec( 50 prometheus.HistogramOpts{ 51 Namespace: factoryConfig.namespace, 52 Subsystem: factoryConfig.subsystem, 53 Name: httpRequestDurationSecondsMetricName, 54 Help: "A histogram of latencies for requests to the http server.", 55 Buckets: factoryConfig.requestDurationBuckets, 56 }, 57 factoryConfig.labels, 58 ) 59 60 httpRequestSizeBytes = prometheus.NewHistogramVec( 61 prometheus.HistogramOpts{ 62 Namespace: factoryConfig.namespace, 63 Subsystem: factoryConfig.subsystem, 64 Name: httpRequestSizeBytesMetricName, 65 Help: "A histogram of sizes of requests to the http server.", 66 Buckets: factoryConfig.byteSizeBuckets, 67 }, 68 factoryConfig.labels, 69 ) 70 71 httpResponseSizeBytes = prometheus.NewHistogramVec( 72 prometheus.HistogramOpts{ 73 Namespace: factoryConfig.namespace, 74 Subsystem: factoryConfig.subsystem, 75 Name: httpResponseSizeBytesMetricName, 76 Help: "A histogram of response sizes for requests to the http server.", 77 Buckets: factoryConfig.byteSizeBuckets, 78 }, 79 factoryConfig.labels, 80 ) 81 82 httpTimeToWriteHeaderSeconds = prometheus.NewHistogramVec( 83 prometheus.HistogramOpts{ 84 Namespace: factoryConfig.namespace, 85 Subsystem: factoryConfig.subsystem, 86 Name: httpTimeToWriteHeaderSecondsMetricName, 87 Help: "A histogram of request durations until the response headers are written.", 88 Buckets: factoryConfig.timeToWriteHeaderDurationBuckets, 89 }, 90 factoryConfig.labels, 91 ) 92 ) 93 94 prometheus.MustRegister(httpInFlightRequests) 95 prometheus.MustRegister(httpRequestsTotal) 96 prometheus.MustRegister(httpRequestDurationSeconds) 97 prometheus.MustRegister(httpRequestSizeBytes) 98 prometheus.MustRegister(httpResponseSizeBytes) 99 prometheus.MustRegister(httpTimeToWriteHeaderSeconds) 100 101 return func(next http.Handler, handlerOpts ...HandlerOption) http.Handler { 102 handlerConfig := applyHandlerOptions(handlerOpts) 103 104 handler := next 105 106 handler = promhttp.InstrumentHandlerCounter(httpRequestsTotal.MustCurryWith(handlerConfig.labelValues), handler) 107 handler = promhttp.InstrumentHandlerDuration(httpRequestDurationSeconds.MustCurryWith(handlerConfig.labelValues), handler) 108 handler = promhttp.InstrumentHandlerInFlight(httpInFlightRequests, handler) 109 handler = promhttp.InstrumentHandlerRequestSize(httpRequestSizeBytes.MustCurryWith(handlerConfig.labelValues), handler) 110 handler = promhttp.InstrumentHandlerResponseSize(httpResponseSizeBytes.MustCurryWith(handlerConfig.labelValues), handler) 111 handler = promhttp.InstrumentHandlerTimeToWriteHeader(httpTimeToWriteHeaderSeconds.MustCurryWith(handlerConfig.labelValues), handler) 112 113 return handler 114 } 115 }