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
use prometheus::{
core::{Collector, Desc},
proto::MetricFamily,
Histogram, HistogramOpts, HistogramTimer, HistogramVec, IntCounterVec, IntGauge, IntGaugeVec,
Opts,
};
use std::time::Duration;
pub struct DurationHistogram {
histogram: Histogram,
}
impl DurationHistogram {
pub fn new(histogram: Histogram) -> DurationHistogram {
DurationHistogram { histogram }
}
pub fn observe_duration(&self, d: Duration) {
let v = d.as_secs() as f64 + f64::from(d.subsec_nanos()) / 1e9;
self.histogram.observe(v);
}
pub fn start_timer(&self) -> HistogramTimer {
self.histogram.start_timer()
}
}
#[derive(Clone)]
pub struct OpMetrics {
counters: IntCounterVec,
gauges: IntGaugeVec,
peer_gauges: IntGaugeVec,
duration_histograms: HistogramVec,
}
impl OpMetrics {
pub fn new<S: Into<String>>(name: S) -> OpMetrics {
let name_str = name.into();
OpMetrics {
counters: IntCounterVec::new(
Opts::new(name_str.clone(), format!("Counters for {}", name_str)),
&["op"],
)
.unwrap(),
gauges: IntGaugeVec::new(
Opts::new(
format!("{}_gauge", name_str),
format!("Gauges for {}", name_str),
),
&["op"],
)
.unwrap(),
peer_gauges: IntGaugeVec::new(
Opts::new(
format!("{}_peer_gauge", name_str),
format!("Gauges of each remote peer for {}", name_str),
),
&["op", "remote_peer_id"],
)
.unwrap(),
duration_histograms: HistogramVec::new(
HistogramOpts::new(
format!("{}_duration", name_str),
format!("Histogram values for {}", name_str),
),
&["op"],
)
.unwrap(),
}
}
pub fn new_and_registered<S: Into<String>>(name: S) -> OpMetrics {
let op_metrics = OpMetrics::new(name);
prometheus::register(Box::new(op_metrics.clone()))
.expect("OpMetrics registration on Prometheus failed.");
op_metrics
}
#[inline]
pub fn gauge(&self, name: &str) -> IntGauge {
self.gauges.with_label_values(&[name])
}
#[inline]
pub fn peer_gauge(&self, name: &str, remote_peer_id: &str) -> IntGauge {
self.peer_gauges.with_label_values(&[name, remote_peer_id])
}
#[inline]
pub fn inc(&self, op: &str) {
self.counters.with_label_values(&[op]).inc();
}
#[inline]
pub fn inc_by(&self, op: &str, v: usize) {
self.counters.with_label_values(&[op]).inc_by(v as u64);
}
#[inline]
pub fn set(&self, op: &str, v: usize) {
self.gauges.with_label_values(&[op]).set(v as i64);
}
#[inline]
pub fn observe(&self, op: &str, v: f64) {
self.duration_histograms.with_label_values(&[op]).observe(v);
}
pub fn observe_duration(&self, op: &str, d: Duration) {
let v = d.as_secs() as f64 + f64::from(d.subsec_nanos()) / 1e9;
self.duration_histograms.with_label_values(&[op]).observe(v);
}
pub fn timer(&self, op: &str) -> HistogramTimer {
self.duration_histograms
.with_label_values(&[op])
.start_timer()
}
}
impl Collector for OpMetrics {
fn desc(&self) -> Vec<&Desc> {
let mut ms = Vec::with_capacity(4);
ms.extend(self.counters.desc());
ms.extend(self.gauges.desc());
ms.extend(self.peer_gauges.desc());
ms.extend(self.duration_histograms.desc());
ms
}
fn collect(&self) -> Vec<MetricFamily> {
let mut ms = Vec::with_capacity(4);
ms.extend(self.counters.collect());
ms.extend(self.gauges.collect());
ms.extend(self.peer_gauges.collect());
ms.extend(self.duration_histograms.collect());
ms
}
}