-
Notifications
You must be signed in to change notification settings - Fork 0
/
prom.go
160 lines (138 loc) · 4.31 KB
/
prom.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package miso
import (
"fmt"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
manualBootstrapProm = false
)
func init() {
SetDefProp(PropMetricsEnabled, true)
SetDefProp(PropMetricsRoute, "/metrics")
RegisterBootstrapCallback(ComponentBootstrap{
Name: "Bootstrap Prometheus",
Bootstrap: PrometheusBootstrap,
Condition: PrometheusBootstrapCondition,
Order: BootstrapOrderL2,
})
}
// Default handler for prometheus metrics.
func PrometheusHandler() http.Handler {
if !GetPropBool(PropMetricsAuthEnabled) {
return promhttp.Handler()
}
return BearerAuth(promhttp.Handler(), func() string { return GetPropStr(PropMetricsAuthBearer) })
}
// Timer based on prometheus.Histogram.
//
// Duration is measured in millisecond.
//
// Use NewHistTimer to create a new one, and each timer can only be used for once.
type HistTimer struct {
hist prometheus.Histogram
begin time.Time
}
func (t *HistTimer) Reset() {
t.begin = time.Now()
}
func (t *HistTimer) ObserveDuration() time.Duration {
d := time.Since(t.begin)
t.hist.Observe(float64(d.Milliseconds()))
return d
}
// Create new timer that is backed by a prometheus.Histogram. Each timer can only be used for once.
func NewHistTimer(hist prometheus.Histogram) *HistTimer {
if hist == nil {
panic("prometheus.Histogram is nil")
}
return &HistTimer{
hist: hist,
begin: time.Now(),
}
}
// Create new Histogram.
//
// The created Histogram is automatically registered to the prometheus.DefaultRegisterer.
func NewPromHisto(name string) prometheus.Histogram {
hist := prometheus.NewHistogram(prometheus.HistogramOpts{Name: name})
if e := prometheus.DefaultRegisterer.Register(hist); e != nil {
panic(fmt.Errorf("failed to register histogram %v, %w", name, e))
}
return hist
}
// Create new Counter.
//
// The Counter with this name is automatically registered to the prometheus.DefaultRegisterer.
func NewPromCounter(name string) prometheus.Counter {
counter := prometheus.NewCounter(prometheus.CounterOpts{Name: name})
if e := prometheus.DefaultRegisterer.Register(counter); e != nil {
panic(fmt.Errorf("failed to register counter %v, %w", name, e))
}
return counter
}
func PrometheusBootstrapCondition(rail Rail) (bool, error) {
return GetPropBool(PropMetricsEnabled) && GetPropBool(PropServerEnabled), nil
}
func PrometheusBootstrap(rail Rail) error {
handler := PrometheusHandler()
if GetPropBool(PropMetricsAuthEnabled) {
if IsBlankStr(GetPropStr(PropMetricsAuthBearer)) {
return fmt.Errorf("metrics authorization enabled, but secret is missing, please configure property '%v'",
PropMetricsAuthBearer)
}
rail.Info("Enabled metrics authorization")
}
if !manualBootstrapProm {
RawGet(GetPropStr(PropMetricsRoute),
func(inb *Inbound) { handler.ServeHTTP(inb.Unwrap()) }).
Desc("Collect prometheus metrics information").
DocHeader("Authorization", "Basic authorization if enabled")
}
return nil
}
// Caller wants to bootstrap prometheus manually.
//
// This is mainly used for gateway that implements handler for all endpoints.
func ManualBootstrapPrometheus() {
manualBootstrapProm = true
}
// Timer based on prometheus.HistogramVec.
//
// Duration is measured in millisecond.
//
// Use NewVecTimer to create a new one, and each timer can only be used for once.
type VecTimer struct {
histVec *prometheus.HistogramVec
begin time.Time
}
func (t *VecTimer) Reset() {
t.begin = time.Now()
}
func (t *VecTimer) ObserveDuration(labels ...string) time.Duration {
d := time.Since(t.begin)
t.histVec.WithLabelValues(labels...).Observe(float64(d.Milliseconds()))
return d
}
// Create new timer that is back by prometheus HistogramVec. Each timer can only be used for once.
func NewVecTimer(vec *prometheus.HistogramVec) *VecTimer {
if vec == nil {
panic("prometheus.HistogramVec is nil")
}
return &VecTimer{
histVec: vec,
begin: time.Now(),
}
}
// Create new HistogramVec.
//
// The HistogramVec is automatically registered to the prometheus.DefaultRegisterer.
func NewPromHistoVec(name string, labels []string) *prometheus.HistogramVec {
vec := prometheus.NewHistogramVec(prometheus.HistogramOpts{Name: name}, labels)
if e := prometheus.DefaultRegisterer.Register(vec); e != nil {
panic(fmt.Errorf("failed to register HistogramVec %v, %v", name, e))
}
return vec
}