Skip to main content

commonware_runtime/telemetry/metrics/
status.rs

1//! Recording metrics with a status.
2
3use super::{EncodeLabelSet, EncodeLabelValue, Registered, raw};
4
5/// Metric label that indicates status.
6#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, EncodeLabelSet)]
7pub struct Label {
8    /// The value of the label.
9    status: Status,
10}
11
12/// Possible values for the status label.
13#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, EncodeLabelValue)]
14pub enum Status {
15    /// Processed successfully.
16    Success,
17    /// Processing produced one of multiple valid results but did not satisfy the request.
18    Ambiguous,
19    /// Processing failed.
20    Failure,
21    /// Input was malformed or invalid in some way. Indicates a client error.
22    Invalid,
23    /// Input was valid, but intentionally not processed.
24    /// For example due to a rate limit, being a duplicate, etc.
25    Dropped,
26    /// Processing returned no result before some deadline.
27    Timeout,
28}
29
30/// Raw family backing a status [`Counter`]. Construct this and pass it to
31/// [`crate::Metrics::register`].
32pub type Raw = raw::Family<Label, raw::Counter>;
33
34/// A registered counter metric with a status label.
35pub type Counter = Registered<Raw>;
36
37impl Counter {
38    /// Create a new CounterGuard with a given status.
39    pub fn guard(&self, status: Status) -> CounterGuard {
40        CounterGuard {
41            metric: self.clone(),
42            status,
43        }
44    }
45
46    /// Increment the metric with a given status.
47    pub fn inc(&self, status: Status) {
48        self.get_or_create(&Label { status }).inc();
49    }
50
51    /// Increment the metric with a given status.
52    pub fn inc_by(&self, status: Status, n: u64) {
53        self.get_or_create(&Label { status }).inc_by(n);
54    }
55}
56
57/// Increments a `Counter` metric when dropped.
58///
59/// Can be used to ensure that counters are incremented regardless of the control flow. For example,
60/// if a function returns early, the metric will still be incremented.
61pub struct CounterGuard {
62    /// The metric to increment.
63    metric: Counter,
64
65    /// The status at which the metric is set to be incremented.
66    status: Status,
67}
68
69impl CounterGuard {
70    /// Modify the status at which the metric will be incremented.
71    pub const fn set(&mut self, status: Status) {
72        self.status = status;
73    }
74}
75
76impl Drop for CounterGuard {
77    fn drop(&mut self) {
78        self.metric.inc(self.status);
79    }
80}