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
#[allow(unused_imports)]
use std::any::Any;
#[macro_export]
macro_rules! record {
( $e:expr, $v:expr) => {
$e.record($v);
};
}
#[macro_export]
macro_rules! inc {
( $e:expr) => {
$e.record(1);
};
}
#[macro_export]
macro_rules! observe {
( $e:expr, $v:expr) => {
$e.observe($v);
};
}
#[macro_export]
macro_rules! make_metrics {
($module_name:ident, $($name:ident: $type:ident: $description:expr),+) => {
paste::paste! {
#[derive(Default, Clone)]
pub(crate) struct Metrics {
$(
[<$name:snake>]: $type,
)+
}
}
impl fmt::Debug for Metrics {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Store Metrics").finish()
}
}
paste::paste! {
$(
pub const [<METRICS_CNT_ $name:snake:upper>]: &str = stringify!([<$name:snake>]);
)+
impl Metrics {
pub(crate) fn new(registry: &mut Registry) -> Self {
let sub_registry = registry.sub_registry_with_prefix(stringify!([<$module_name:snake>]));
$(
let [<$name:snake>] = <$type>::default();
sub_registry.register(
stringify!([<$name:snake>]),
$description,
Box::new([<$name:snake>].clone())
);
)+
Self {
$(
[<$name:snake>],
)+
}
}
}
impl MetricsRecorder for Metrics {
fn record<M>(&self, m: M, value: u64)
where
M: MetricType + std::fmt::Display,
{
match m.name() {
$(
x if x == [<$module_name Metrics>]::$name.name() => {
self.[<$name:snake>].inc_by(value);
}
)+
name => {
error!("record ([<$module_name:snake>]): unknown metric {}", name);
}
}
}
fn observe<M>(&self, m: M, _value: f64)
where
M: HistogramType + std::fmt::Display,
{
error!("observe ([<$module_name:snake>]): unknown metric {}", m.name());
}
}
impl MetricType for [<$module_name Metrics>] {
fn name(&self) -> &'static str {
match self {
$(
[<$module_name Metrics>]::$name => {
[<METRICS_CNT_ $name:snake:upper>]
}
)+
}
}
}
impl MRecorder for [<$module_name Metrics>] {
fn record(&self, value: u64) {
$crate::record(Collector::$module_name, self.clone(), value);
}
}
impl std::fmt::Display for [<$module_name Metrics>] {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name())
}
}
#[derive(Debug, Copy, Clone)]
pub enum [<$module_name Metrics>] {
$(
$name,
)+
}
}
}
}