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