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
use crate::AtomicBucket;
use atomic_shim::AtomicU64;
use metrics::GaugeValue;
use std::sync::{atomic::Ordering, Arc};
#[derive(Debug, Clone)]
pub enum Handle {
Counter(Arc<AtomicU64>),
Gauge(Arc<AtomicU64>),
Histogram(Arc<AtomicBucket<f64>>),
}
impl Handle {
pub fn counter() -> Handle {
Handle::Counter(Arc::new(AtomicU64::new(0)))
}
pub fn gauge() -> Handle {
Handle::Gauge(Arc::new(AtomicU64::new(0)))
}
pub fn histogram() -> Handle {
Handle::Histogram(Arc::new(AtomicBucket::new()))
}
pub fn increment_counter(&self, value: u64) {
match self {
Handle::Counter(counter) => {
counter.fetch_add(value, Ordering::SeqCst);
}
_ => panic!("tried to increment as counter"),
}
}
pub fn update_gauge(&self, value: GaugeValue) {
match self {
Handle::Gauge(gauge) => {
let _ = gauge.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |curr| {
let input = f64::from_bits(curr);
let output = value.update_value(input);
Some(output.to_bits())
});
}
_ => panic!("tried to update as gauge"),
}
}
pub fn record_histogram(&self, value: f64) {
match self {
Handle::Histogram(bucket) => bucket.push(value),
_ => panic!("tried to record as histogram"),
}
}
pub fn read_counter(&self) -> u64 {
match self {
Handle::Counter(counter) => counter.load(Ordering::Relaxed),
_ => panic!("tried to read as counter"),
}
}
pub fn read_gauge(&self) -> f64 {
match self {
Handle::Gauge(gauge) => {
let unsigned = gauge.load(Ordering::Relaxed);
f64::from_bits(unsigned)
}
_ => panic!("tried to read as gauge"),
}
}
pub fn read_histogram(&self) -> Vec<f64> {
match self {
Handle::Histogram(bucket) => bucket.data(),
_ => panic!("tried to read as histogram"),
}
}
pub fn read_histogram_is_empty(&self) -> bool {
match self {
Handle::Histogram(bucket) => bucket.is_empty(),
_ => panic!("tried to read as histogram"),
}
}
pub fn read_histogram_with_clear<F>(&self, f: F)
where
F: FnMut(&[f64]),
{
match self {
Handle::Histogram(bucket) => bucket.clear_with(f),
_ => panic!("tried to read as histogram"),
}
}
}