hyperlight_host/metrics/
histogram.rs1use prometheus::{register_histogram_with_registry, Histogram as PHistogram};
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 Histogram {
29 histogram: PHistogram,
30 pub name: &'static str,
32}
33
34impl Histogram {
35 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
37 pub fn new(name: &'static str, help: &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_with_registry!(opts, registry)?;
41 Ok(Self { histogram, name })
42 }
43 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
45 pub fn observe(&self, val: f64) {
46 self.histogram.observe(val)
47 }
48 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
50 pub fn get_sample_sum(&self) -> f64 {
51 self.histogram.get_sample_sum()
52 }
53 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
55 pub fn get_sample_count(&self) -> u64 {
56 self.histogram.get_sample_count()
57 }
58}
59
60impl<S: HyperlightMetricOps> GetHyperlightMetric<Histogram> for S {
61 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
62 fn metric(&self) -> Result<&Histogram> {
63 let metric = self.get_metric()?;
64 <&HyperlightMetric as TryInto<&Histogram>>::try_into(metric)
65 }
66}
67
68impl<'a> TryFrom<&'a HyperlightMetric> for &'a Histogram {
69 type Error = HyperlightError;
70 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
71 fn try_from(metric: &'a HyperlightMetric) -> Result<Self> {
72 match metric {
73 HyperlightMetric::Histogram(histogram) => Ok(histogram),
74 _ => Err(new_error!("metric is not a Histogram")),
75 }
76 }
77}
78
79impl From<Histogram> for HyperlightMetric {
80 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
81 fn from(histogram: Histogram) -> Self {
82 HyperlightMetric::Histogram(histogram)
83 }
84}
85
86#[macro_export]
88macro_rules! histogram_observe {
89 ($metric:expr, $val:expr) => {{
90 match $crate::metrics::GetHyperlightMetric::<$crate::metrics::Histogram>::metric($metric) {
91 Ok(val) => {
92 if let Err(e) = val.observe($val) {
93 log::error!("error calling observe with value {} on metric {} ", $val, e,)
94 }
95 }
96 Err(e) => log::error!("error getting metric: {}", e),
97 };
98 }};
99}
100
101#[macro_export]
104macro_rules! histogram_sample_sum {
105 ($metric:expr) => {{
106 match $crate::metrics::GetHyperlightMetric::<$crate::metrics::Histogram>::metric($metric) {
107 Ok(val) => match val.get_sample_sum() {
108 Ok(val) => val,
109 Err(e) => {
110 log::error!("error getting samples sum of metric {}", e,);
111 0.0
112 }
113 },
114
115 Err(e) => {
116 log::error!("error getting metric: {}", e);
117 0.0
118 }
119 }
120 }};
121}
122
123#[macro_export]
126macro_rules! histogram_sample_count {
127 ($metric:expr) => {{
128 match $crate::metrics::GetHyperlightMetric::<$crate::metrics::Histogram>::metric($metric) {
129 Ok(val) => match val.get_sample_count() {
130 Ok(val) => val,
131 Err(e) => {
132 log::error!("error getting samples count of metric {}", e,);
133 0
134 }
135 },
136
137 Err(e) => {
138 log::error!("error getting metric: {}", e);
139 0
140 }
141 }
142 }};
143}
144#[macro_export]
146macro_rules! histogram_time_micros {
147 ($metric:expr, $expr:expr) => {{
148 let start = std::time::Instant::now();
149 let result = $expr;
150 histogram_observe!($metric, start.elapsed().as_micros() as f64);
151 result
152 }};
153}