...
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
11 type HTTPHandlerOpts struct {
12 DurationBuckets []float64
13 RequestSizeBuckets []float64
14 ResponseSizeBuckets []float64
15 }
16
17 const (
18 InstrumentHandlerResponseSize = iota
19 InstrumentHandlerRequestSize
20 InstrumentHandlerDuration
21 InstrumentHandlerCounter
22 InstrumentHandlerInFlight
23 )
24
25 type HTTPMetric struct {
26 prometheus.Collector
27 handlerType int
28 }
29
30 var (
31 defaultDurationBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10, 25, 60}
32 defaultRequestSizeBuckets = prometheus.ExponentialBuckets(1024, 2, 22)
33 defaultResponseSizeBuckets = defaultRequestSizeBuckets
34 )
35
36
37
38 func Handler() http.Handler {
39 return promhttp.Handler()
40 }
41
42 func InstrumentHandler(metrics []*HTTPMetric, handler http.Handler) http.HandlerFunc {
43 return InstrumentHandlerFunc(metrics, handler.ServeHTTP)
44 }
45
46 func InstrumentHandlerFunc(metrics []*HTTPMetric, handlerFunc http.HandlerFunc) http.HandlerFunc {
47 var handler http.Handler
48 handler = http.HandlerFunc(handlerFunc)
49 for _, metric := range metrics {
50 switch metric.handlerType {
51 case InstrumentHandlerResponseSize:
52 if collector, ok := metric.Collector.(prometheus.ObserverVec); ok {
53 handler = promhttp.InstrumentHandlerResponseSize(collector, handler)
54 }
55 case InstrumentHandlerRequestSize:
56 if collector, ok := metric.Collector.(prometheus.ObserverVec); ok {
57 handler = promhttp.InstrumentHandlerRequestSize(collector, handler)
58 }
59 case InstrumentHandlerDuration:
60 if collector, ok := metric.Collector.(prometheus.ObserverVec); ok {
61 handler = promhttp.InstrumentHandlerDuration(collector, handler)
62 }
63 case InstrumentHandlerCounter:
64 if collector, ok := metric.Collector.(*prometheus.CounterVec); ok {
65 handler = promhttp.InstrumentHandlerCounter(collector, handler)
66 }
67 case InstrumentHandlerInFlight:
68 if collector, ok := metric.Collector.(prometheus.Gauge); ok {
69 handler = promhttp.InstrumentHandlerInFlight(collector, handler)
70 }
71 }
72 }
73 return handler.ServeHTTP
74 }
75
View as plain text