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}