commonware_runtime/telemetry/metrics/
histogram.rs1use crate::Clock;
4use prometheus_client::metrics::histogram::Histogram;
5use std::{sync::Arc, time::SystemTime};
6
7pub struct Buckets;
11
12impl Buckets {
13 pub const NETWORK: [f64; 13] = [
18 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,
19 ];
20
21 pub const LOCAL: [f64; 12] = [
26 3e-6, 1e-5, 3e-5, 1e-4, 3e-4, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1.0,
27 ];
28
29 pub const CRYPTOGRAPHY: [f64; 16] = [
34 3e-6, 1e-5, 3e-5, 1e-4, 3e-4, 0.001, 0.002, 0.003, 0.005, 0.01, 0.015, 0.02, 0.025, 0.03,
35 0.1, 0.2,
36 ];
37}
38
39pub trait HistogramExt {
41 fn observe_between(&self, start: SystemTime, end: SystemTime);
45}
46
47impl HistogramExt for Histogram {
48 fn observe_between(&self, start: SystemTime, end: SystemTime) {
49 let duration = end.duration_since(start).map_or(
50 0.0,
52 |duration| duration.as_secs_f64(),
53 );
54 self.observe(duration);
55 }
56}
57
58#[derive(Clone)]
60pub struct Timed<C: Clock> {
61 histogram: Histogram,
63
64 clock: Arc<C>,
66}
67
68impl<C: Clock> Timed<C> {
69 pub const fn new(histogram: Histogram, clock: Arc<C>) -> Self {
71 Self { histogram, clock }
72 }
73
74 pub fn timer(&self) -> Timer<C> {
76 let start = self.clock.current();
77 Timer {
78 histogram: self.histogram.clone(),
79 clock: self.clock.clone(), start,
81 canceled: false,
82 }
83 }
84
85 pub fn time_some<T, F: FnOnce() -> Option<T>>(&self, f: F) -> Option<T> {
87 let start = self.clock.current();
88 let result = f();
89 if result.is_some() {
90 self.histogram.observe_between(start, self.clock.current());
91 }
92 result
93 }
94}
95
96pub struct Timer<C: Clock> {
98 histogram: Histogram,
100
101 clock: Arc<C>,
103
104 start: SystemTime,
106
107 canceled: bool,
109}
110
111impl<C: Clock> Timer<C> {
112 pub fn observe(&mut self) {
114 self.canceled = true;
115 let end = self.clock.current();
116 self.histogram.observe_between(self.start, end);
117 }
118
119 pub fn cancel(mut self) {
121 self.canceled = true;
122 }
123}
124
125impl<C: Clock> Drop for Timer<C> {
126 fn drop(&mut self) {
127 if self.canceled {
128 return;
129 }
130 self.observe();
131 }
132}