commonware_runtime/telemetry/
histogram.rs1use crate::Clock;
2use prometheus_client::metrics::histogram::Histogram;
3use std::{sync::Arc, time::SystemTime};
4
5pub struct Buckets;
9
10impl Buckets {
11    pub const NETWORK: [f64; 13] = [
16        0.010, 0.020, 0.050, 0.100, 0.200, 0.500, 1.0, 2.0, 5.0, 10.0, 30.0, 60.0, 300.0,
17    ];
18
19    pub const LOCAL: [f64; 12] = [
24        3e-6, 1e-5, 3e-5, 1e-4, 3e-4, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1.0,
25    ];
26}
27
28pub trait HistogramExt {
30    fn observe_between(&self, start: SystemTime, end: SystemTime);
34}
35
36impl HistogramExt for Histogram {
37    fn observe_between(&self, start: SystemTime, end: SystemTime) {
38        let duration = match end.duration_since(start) {
39            Ok(duration) => duration.as_secs_f64(),
40            Err(_) => 0.0, };
42        self.observe(duration);
43    }
44}
45
46pub struct Timed<C: Clock> {
48    histogram: Histogram,
50
51    clock: Arc<C>,
53}
54
55impl<C: Clock> Timed<C> {
56    pub fn new(histogram: Histogram, clock: Arc<C>) -> Self {
58        Self { histogram, clock }
59    }
60
61    pub fn timer(&self) -> Timer<C> {
63        let start = self.clock.current();
64        Timer {
65            histogram: self.histogram.clone(),
66            clock: self.clock.clone(), start,
68            canceled: false,
69        }
70    }
71}
72
73pub struct Timer<C: Clock> {
75    histogram: Histogram,
77
78    clock: Arc<C>,
80
81    start: SystemTime,
83
84    canceled: bool,
86}
87
88impl<C: Clock> Timer<C> {
89    pub fn observe(&mut self) {
91        self.canceled = true;
92        let end = self.clock.current();
93        self.histogram.observe_between(self.start, end);
94    }
95
96    pub fn cancel(mut self) {
98        self.canceled = true;
99    }
100}
101
102impl<C: Clock> Drop for Timer<C> {
103    fn drop(&mut self) {
104        if self.canceled {
105            return;
106        }
107        self.observe();
108    }
109}