tycho_util/metrics/
histogram_guard.rs

1use std::time::{Duration, Instant};
2
3#[must_use = "The guard is used to update the histogram when it is dropped"]
4pub struct HistogramGuard {
5    name: Option<&'static str>,
6    started_at: Instant,
7}
8
9impl HistogramGuard {
10    pub fn begin(name: &'static str) -> Self {
11        Self {
12            name: Some(name),
13            started_at: Instant::now(),
14        }
15    }
16
17    pub fn begin_with_labels<'a, T>(
18        name: &'static str,
19        labels: &'a T,
20    ) -> HistogramGuardWithLabels<'a, T>
21    where
22        &'a T: metrics::IntoLabels,
23    {
24        HistogramGuardWithLabels::begin(name, labels)
25    }
26
27    pub fn finish(mut self) -> Duration {
28        let duration = self.started_at.elapsed();
29        if let Some(name) = self.name.take() {
30            metrics::histogram!(name).record(duration);
31        }
32        duration
33    }
34}
35
36impl Drop for HistogramGuard {
37    fn drop(&mut self) {
38        if let Some(name) = self.name.take() {
39            metrics::histogram!(name).record(self.started_at.elapsed());
40        }
41    }
42}
43
44#[must_use = "The guard is used to update the histogram when it is dropped"]
45pub struct HistogramGuardWithLabels<'a, T: 'static>
46where
47    &'a T: metrics::IntoLabels,
48{
49    name: Option<&'static str>,
50    started_at: Instant,
51    labels: &'a T,
52}
53
54impl<'a, T> HistogramGuardWithLabels<'a, T>
55where
56    &'a T: metrics::IntoLabels,
57{
58    pub fn begin(name: &'static str, labels: &'a T) -> Self {
59        Self {
60            name: Some(name),
61            started_at: Instant::now(),
62            labels,
63        }
64    }
65
66    pub fn finish(mut self) -> Duration {
67        let duration = self.started_at.elapsed();
68        if let Some(name) = self.name.take() {
69            metrics::histogram!(name, self.labels).record(duration);
70        }
71        duration
72    }
73}
74
75impl<'a, T> Drop for HistogramGuardWithLabels<'a, T>
76where
77    &'a T: metrics::IntoLabels,
78{
79    fn drop(&mut self) {
80        if let Some(name) = self.name.take() {
81            metrics::histogram!(name, self.labels).record(self.started_at.elapsed());
82        }
83    }
84}