Skip to main content

commonware_runtime/telemetry/metrics/
status.rs

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