tycho_util/metrics/
histogram_guard.rs1use 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}