stratus/infra/metrics/
metrics_types.rs1use std::borrow::Cow;
2use std::time::Duration;
3
4use metrics::Label;
5use metrics::describe_counter;
6use metrics::describe_gauge;
7use metrics::describe_histogram;
8
9pub type HistogramInt = u32;
10pub type Sum = u64;
11pub type Count = u64;
12
13pub const LABEL_PRESENT: &str = "present";
19
20pub const LABEL_MISSING: &str = "missing";
22
23pub const LABEL_UNKNOWN: &str = "unknown";
25
26pub const LABEL_ERROR: &str = "error";
28
29pub(super) struct Metric {
35 pub(super) kind: &'static str,
36 pub(super) name: &'static str,
37 pub(super) description: &'static str,
38}
39
40impl Metric {
41 pub(super) fn register_description(&self) {
43 match self.kind {
44 "counter" => describe_counter!(self.name, self.description),
45 "histogram_duration" | "histogram_counter" => describe_histogram!(self.name, self.description),
46 "gauge" => describe_gauge!(self.name, self.description),
47 _ => {}
48 }
49 }
50}
51
52pub enum MetricLabelValue {
62 Some(String),
64 None,
66}
67
68impl From<Option<Cow<'static, str>>> for MetricLabelValue {
69 fn from(value: Option<Cow<'static, str>>) -> Self {
70 match value {
71 Some(str) => Self::Some(str.into_owned()),
72 None => Self::None,
73 }
74 }
75}
76
77impl From<&String> for MetricLabelValue {
78 fn from(value: &String) -> Self {
79 Self::Some(value.to_owned())
80 }
81}
82
83impl From<&str> for MetricLabelValue {
84 fn from(value: &str) -> Self {
85 Self::Some(value.to_owned())
86 }
87}
88
89impl From<Option<&str>> for MetricLabelValue {
90 fn from(value: Option<&str>) -> Self {
91 match value {
92 Some(value) => Self::Some(value.to_owned()),
93 None => Self::None,
94 }
95 }
96}
97
98impl From<String> for MetricLabelValue {
99 fn from(value: String) -> Self {
100 Self::Some(value)
101 }
102}
103
104impl From<bool> for MetricLabelValue {
105 fn from(value: bool) -> Self {
106 Self::Some(value.to_string())
107 }
108}
109
110impl From<i32> for MetricLabelValue {
111 fn from(value: i32) -> Self {
112 Self::Some(value.to_string())
113 }
114}
115
116pub(super) fn into_labels(labels: Vec<(&'static str, MetricLabelValue)>) -> Vec<Label> {
118 labels
119 .into_iter()
120 .filter_map(|(key, value)| match value {
121 MetricLabelValue::Some(value) => Some((key, value)),
122 MetricLabelValue::None => None,
123 })
124 .map(|(key, value)| Label::new(key, value))
125 .collect()
126}
127
128#[cfg(feature = "metrics")]
132pub fn timed<F, T>(f: F) -> Timed<T>
136where
137 F: FnOnce() -> T,
138{
139 let start = crate::infra::metrics::now();
140 let result = f();
141 Timed {
142 elapsed: start.elapsed(),
143 result,
144 }
145}
146
147#[cfg(not(feature = "metrics"))]
148pub fn timed<F, T>(f: F) -> Timed<T>
150where
151 F: FnOnce() -> T,
152{
153 let result = f();
154 Timed {
155 elapsed: Duration::default(),
156 result,
157 }
158}
159
160pub struct Timed<T> {
161 pub elapsed: Duration,
162 pub result: T,
163}
164
165impl<T> Timed<T> {
166 #[cfg(feature = "metrics")]
167 #[inline(always)]
168 pub fn with<F>(self, f: F) -> T
170 where
171 F: FnOnce(&Timed<T>),
172 {
173 f(&self);
174 self.result
175 }
176
177 #[cfg(not(feature = "metrics"))]
178 #[inline(always)]
179 pub fn with<F>(self, _: F) -> T
181 where
182 F: FnOnce(&Timed<T>),
183 {
184 self.result
185 }
186}