hyperlight_host/metrics/
histogram_vec.rs1use prometheus::{register_histogram_vec_with_registry, HistogramVec as PHistogramVec};
18use tracing::{instrument, Span};
19
20use super::{
21 get_histogram_opts, get_metrics_registry, GetHyperlightMetric, HyperlightMetric,
22 HyperlightMetricOps,
23};
24use crate::{new_error, HyperlightError, Result};
25
26#[derive(Debug)]
28pub struct HistogramVec {
29 histogram: PHistogramVec,
30 pub name: &'static str,
32}
33
34impl HistogramVec {
35 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
37 pub fn new(name: &'static str, help: &str, labels: &[&str], buckets: Vec<f64>) -> Result<Self> {
38 let registry = get_metrics_registry();
39 let opts = get_histogram_opts(name, help, buckets);
40 let histogram = register_histogram_vec_with_registry!(opts, labels, registry)?;
41 Ok(Self { histogram, name })
42 }
43
44 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
46 pub fn observe(&self, label_vals: &[&str], val: f64) -> Result<()> {
47 self.histogram
48 .get_metric_with_label_values(label_vals)?
49 .observe(val);
50 Ok(())
51 }
52
53 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
55 pub fn get_sample_sum(&self, label_vals: &[&str]) -> Result<f64> {
56 Ok(self
57 .histogram
58 .get_metric_with_label_values(label_vals)?
59 .get_sample_sum())
60 }
61
62 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
64 pub fn get_sample_count(&self, label_vals: &[&str]) -> Result<u64> {
65 Ok(self
66 .histogram
67 .get_metric_with_label_values(label_vals)?
68 .get_sample_count())
69 }
70}
71
72impl<S: HyperlightMetricOps> GetHyperlightMetric<HistogramVec> for S {
73 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
74 fn metric(&self) -> Result<&HistogramVec> {
75 let metric = self.get_metric()?;
76 <&HyperlightMetric as TryInto<&HistogramVec>>::try_into(metric)
77 }
78}
79
80impl<'a> TryFrom<&'a HyperlightMetric> for &'a HistogramVec {
81 type Error = HyperlightError;
82 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
83 fn try_from(metric: &'a HyperlightMetric) -> Result<Self> {
84 match metric {
85 HyperlightMetric::HistogramVec(histogram) => Ok(histogram),
86 _ => Err(new_error!("metric is not a HistogramVec")),
87 }
88 }
89}
90
91impl From<HistogramVec> for HyperlightMetric {
92 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
93 fn from(histogram_vec: HistogramVec) -> Self {
94 HyperlightMetric::HistogramVec(histogram_vec)
95 }
96}
97
98#[macro_export]
100macro_rules! histogram_vec_observe {
101 ($metric:expr, $label_vals:expr, $val:expr) => {{
102 match $crate::metrics::GetHyperlightMetric::<$crate::metrics::HistogramVec>::metric($metric)
103 {
104 Ok(val) => {
105 if let Err(e) = val.observe($label_vals, $val) {
106 log::error!(
107 "error calling observe with {} on metric with labels: {} {:?}",
108 $val,
109 e,
110 $label_vals
111 )
112 }
113 }
114 Err(e) => log::error!("error getting metric: {}", e),
115 };
116 }};
117}
118
119#[macro_export]
122macro_rules! histogram_vec_sample_sum {
123 ($metric:expr, $label_vals:expr) => {{
124 match $crate::metrics::GetHyperlightMetric::<$crate::metrics::HistogramVec>::metric($metric)
125 {
126 Ok(val) => match val.get_sample_sum($label_vals) {
127 Ok(val) => val,
128 Err(e) => {
129 log::error!(
130 "error getting samples sum of metric with labels: {} {:?}",
131 e,
132 $label_vals
133 );
134 0.0
135 }
136 },
137
138 Err(e) => {
139 log::error!("error getting metric: {}", e);
140 0.0
141 }
142 }
143 }};
144}
145
146#[macro_export]
149macro_rules! histogram_vec_sample_count {
150 ($metric:expr, $label_vals:expr) => {{
151 match $crate::metrics::GetHyperlightMetric::<$crate::metrics::HistogramVec>::metric($metric)
152 {
153 Ok(val) => match val.get_sample_count($label_vals) {
154 Ok(val) => val,
155 Err(e) => {
156 log::error!(
157 "error getting samples count of metric with labels: {} {:?}",
158 e,
159 $label_vals
160 );
161 0
162 }
163 },
164
165 Err(e) => {
166 log::error!("error getting metric: {}", e);
167 0
168 }
169 }
170 }};
171}
172
173#[macro_export]
176macro_rules! histogram_vec_time_micros {
177 ($metric:expr, $label_vals:expr, $expr:expr) => {{
178 let start = std::time::Instant::now();
179 let result = $expr;
180 $crate::histogram_vec_observe!($metric, $label_vals, start.elapsed().as_micros() as f64);
181 result
182 }};
183}