This repository has been archived by the owner on Aug 12, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
metric.go
121 lines (105 loc) · 3.63 KB
/
metric.go
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
116
117
118
119
120
121
package razorpay
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Ref: https://godoc.org/github.com/prometheus/client_golang/prometheus/promhttp#ex-InstrumentRoundTripperDuration.
// metricCollector implements prometheus.Collector interface.
type metricCollector struct {
inFlightGauge prometheus.Gauge
counter *prometheus.CounterVec
dnsLatencyVec *prometheus.HistogramVec
tlsLatencyVec *prometheus.HistogramVec
histVec *prometheus.HistogramVec
}
// NewPrometheusCollector configures and returns collector for http client.
func NewPrometheusCollector(client *http.Client, identifier string) prometheus.Collector {
m := &metricCollector{}
constLabels := map[string]string{"client_identifier": identifier}
m.inFlightGauge = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "client_in_flight_requests",
Help: "A gauge of in-flight requests for the wrapped client.",
ConstLabels: constLabels,
})
m.counter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "client_api_requests_total",
Help: "A counter for requests from the wrapped client.",
ConstLabels: constLabels,
},
[]string{"code", "method"},
)
// dnsLatencyVec uses custom buckets based on expected dns durations.
// It has an instance label "event", which is set in the
// DNSStart and DNSDonehook functions defined in the
// InstrumentTrace struct below.
m.dnsLatencyVec = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "dns_duration_seconds",
Help: "Trace dns latency histogram.",
ConstLabels: constLabels,
Buckets: []float64{.005, .01, .025, .05},
},
[]string{"event"},
)
// tlsLatencyVec uses custom buckets based on expected tls durations.
// It has an instance label "event", which is set in the
// TLSHandshakeStart and TLSHandshakeDone hook functions defined in the
// InstrumentTrace struct below.
m.tlsLatencyVec = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "tls_duration_seconds",
Help: "Trace tls latency histogram.",
ConstLabels: constLabels,
Buckets: []float64{.05, .1, .25, .5},
},
[]string{"event"},
)
// histVec has no labels, making it a zero-dimensional ObserverVec.
m.histVec = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "request_duration_seconds",
Help: "A histogram of request latencies.",
Buckets: prometheus.DefBuckets,
},
[]string{},
)
trace := &promhttp.InstrumentTrace{
DNSStart: func(t float64) {
m.dnsLatencyVec.WithLabelValues("dns_start").Observe(t)
},
DNSDone: func(t float64) {
m.dnsLatencyVec.WithLabelValues("dns_done").Observe(t)
},
TLSHandshakeStart: func(t float64) {
m.tlsLatencyVec.WithLabelValues("tls_handshake_start").Observe(t)
},
TLSHandshakeDone: func(t float64) {
m.tlsLatencyVec.WithLabelValues("tls_handshake_done").Observe(t)
},
}
// Instruments transport of client.
client.Transport = promhttp.InstrumentRoundTripperInFlight(m.inFlightGauge,
promhttp.InstrumentRoundTripperCounter(m.counter,
promhttp.InstrumentRoundTripperTrace(trace,
promhttp.InstrumentRoundTripperDuration(m.histVec, client.Transport),
),
),
)
return m
}
func (m *metricCollector) Describe(ch chan<- *prometheus.Desc) {
m.inFlightGauge.Describe(ch)
m.counter.Describe(ch)
m.dnsLatencyVec.Describe(ch)
m.tlsLatencyVec.Describe(ch)
m.histVec.Describe(ch)
}
func (m *metricCollector) Collect(ch chan<- prometheus.Metric) {
m.inFlightGauge.Collect(ch)
m.counter.Collect(ch)
m.dnsLatencyVec.Collect(ch)
m.tlsLatencyVec.Collect(ch)
m.histVec.Collect(ch)
}