@@ -30,29 +30,24 @@ import (
30
30
"github.com/prometheus/client_golang/prometheus/promhttp"
31
31
)
32
32
33
- func main () {
34
- var (
35
- addr = flag .String ("listen-address" , ":8080" , "The address to listen on for HTTP requests." )
36
- uniformDomain = flag .Float64 ("uniform.domain" , 0.0002 , "The domain for the uniform distribution." )
37
- normDomain = flag .Float64 ("normal.domain" , 0.0002 , "The domain for the normal distribution." )
38
- normMean = flag .Float64 ("normal.mean" , 0.00001 , "The mean for the normal distribution." )
39
- oscillationPeriod = flag .Duration ("oscillation-period" , 10 * time .Minute , "The duration of the rate oscillation period." )
40
- )
41
-
42
- flag .Parse ()
33
+ type metrics struct {
34
+ rpcDurations * prometheus.SummaryVec
35
+ rpcDurationsHistogram prometheus.Histogram
36
+ }
43
37
44
- var (
45
- // Create a summary to track fictional interservice RPC latencies for three
38
+ func NewMetrics (reg prometheus.Registerer , normMean , normDomain float64 ) * metrics {
39
+ m := & metrics {
40
+ // Create a summary to track fictional inter service RPC latencies for three
46
41
// distinct services with different latency distributions. These services are
47
42
// differentiated via a "service" label.
48
- rpcDurations = prometheus .NewSummaryVec (
43
+ rpcDurations : prometheus .NewSummaryVec (
49
44
prometheus.SummaryOpts {
50
45
Name : "rpc_durations_seconds" ,
51
46
Help : "RPC latency distributions." ,
52
47
Objectives : map [float64 ]float64 {0.5 : 0.05 , 0.9 : 0.01 , 0.99 : 0.001 },
53
48
},
54
49
[]string {"service" },
55
- )
50
+ ),
56
51
// The same as above, but now as a histogram, and only for the
57
52
// normal distribution. The histogram features both conventional
58
53
// buckets as well as sparse buckets, the latter needed for the
@@ -64,19 +59,36 @@ func main() {
64
59
// buckets are always centered on zero, with a growth factor of
65
60
// one bucket to the text of (at most) 1.1. (The precise factor
66
61
// is 2^2^-3 = 1.0905077...)
67
- rpcDurationsHistogram = prometheus .NewHistogram (prometheus.HistogramOpts {
62
+ rpcDurationsHistogram : prometheus .NewHistogram (prometheus.HistogramOpts {
68
63
Name : "rpc_durations_histogram_seconds" ,
69
64
Help : "RPC latency distributions." ,
70
- Buckets : prometheus .LinearBuckets (* normMean - 5 * * normDomain , .5 * * normDomain , 20 ),
65
+ Buckets : prometheus .LinearBuckets (normMean - 5 * normDomain , .5 * normDomain , 20 ),
71
66
NativeHistogramBucketFactor : 1.1 ,
72
- })
67
+ }),
68
+ }
69
+ reg .MustRegister (m .rpcDurations )
70
+ reg .MustRegister (m .rpcDurationsHistogram )
71
+ return m
72
+ }
73
+
74
+ func main () {
75
+ var (
76
+ addr = flag .String ("listen-address" , ":8080" , "The address to listen on for HTTP requests." )
77
+ uniformDomain = flag .Float64 ("uniform.domain" , 0.0002 , "The domain for the uniform distribution." )
78
+ normDomain = flag .Float64 ("normal.domain" , 0.0002 , "The domain for the normal distribution." )
79
+ normMean = flag .Float64 ("normal.mean" , 0.00001 , "The mean for the normal distribution." )
80
+ oscillationPeriod = flag .Duration ("oscillation-period" , 10 * time .Minute , "The duration of the rate oscillation period." )
73
81
)
74
82
75
- // Register the summary and the histogram with Prometheus's default registry.
76
- prometheus .MustRegister (rpcDurations )
77
- prometheus .MustRegister (rpcDurationsHistogram )
83
+ flag .Parse ()
84
+
85
+ // Create a non-global registry.
86
+ reg := prometheus .NewRegistry ()
87
+
88
+ // Create new metrics and register them using the custom registry.
89
+ m := NewMetrics (reg , * normMean , * normDomain )
78
90
// Add Go module build info.
79
- prometheus .MustRegister (collectors .NewBuildInfoCollector ())
91
+ reg .MustRegister (collectors .NewBuildInfoCollector ())
80
92
81
93
start := time .Now ()
82
94
@@ -88,22 +100,22 @@ func main() {
88
100
go func () {
89
101
for {
90
102
v := rand .Float64 () * * uniformDomain
91
- rpcDurations .WithLabelValues ("uniform" ).Observe (v )
103
+ m . rpcDurations .WithLabelValues ("uniform" ).Observe (v )
92
104
time .Sleep (time .Duration (100 * oscillationFactor ()) * time .Millisecond )
93
105
}
94
106
}()
95
107
96
108
go func () {
97
109
for {
98
110
v := (rand .NormFloat64 () * * normDomain ) + * normMean
99
- rpcDurations .WithLabelValues ("normal" ).Observe (v )
111
+ m . rpcDurations .WithLabelValues ("normal" ).Observe (v )
100
112
// Demonstrate exemplar support with a dummy ID. This
101
113
// would be something like a trace ID in a real
102
114
// application. Note the necessary type assertion. We
103
115
// already know that rpcDurationsHistogram implements
104
116
// the ExemplarObserver interface and thus don't need to
105
117
// check the outcome of the type assertion.
106
- rpcDurationsHistogram .(prometheus.ExemplarObserver ).ObserveWithExemplar (
118
+ m . rpcDurationsHistogram .(prometheus.ExemplarObserver ).ObserveWithExemplar (
107
119
v , prometheus.Labels {"dummyID" : fmt .Sprint (rand .Intn (100000 ))},
108
120
)
109
121
time .Sleep (time .Duration (75 * oscillationFactor ()) * time .Millisecond )
@@ -113,17 +125,19 @@ func main() {
113
125
go func () {
114
126
for {
115
127
v := rand .ExpFloat64 () / 1e6
116
- rpcDurations .WithLabelValues ("exponential" ).Observe (v )
128
+ m . rpcDurations .WithLabelValues ("exponential" ).Observe (v )
117
129
time .Sleep (time .Duration (50 * oscillationFactor ()) * time .Millisecond )
118
130
}
119
131
}()
120
132
121
133
// Expose the registered metrics via HTTP.
122
134
http .Handle ("/metrics" , promhttp .HandlerFor (
123
- prometheus . DefaultGatherer ,
135
+ reg ,
124
136
promhttp.HandlerOpts {
125
137
// Opt into OpenMetrics to support exemplars.
126
138
EnableOpenMetrics : true ,
139
+ // Pass custom registry
140
+ Registry : reg ,
127
141
},
128
142
))
129
143
log .Fatal (http .ListenAndServe (* addr , nil ))
0 commit comments