hyperlight_host/metrics/
int_counter.rs

1/*
2Copyright 2024 The Hyperlight Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17use prometheus::core::{AtomicU64, GenericCounter};
18use prometheus::register_int_counter_with_registry;
19use tracing::{instrument, Span};
20
21use super::{
22    get_metric_opts, get_metrics_registry, GetHyperlightMetric, HyperlightMetric,
23    HyperlightMetricOps,
24};
25use crate::{new_error, HyperlightError, Result};
26
27/// A named counter backed by an `AtomicU64`
28#[derive(Debug)]
29pub struct IntCounter {
30    counter: GenericCounter<AtomicU64>,
31    /// The name of the counter
32    pub name: &'static str,
33}
34
35impl IntCounter {
36    /// Creates a new counter and registers it with the metric registry
37    #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
38    pub fn new(name: &'static str, help: &str) -> Result<Self> {
39        let registry = get_metrics_registry();
40        let opts = get_metric_opts(name, help);
41        let counter = register_int_counter_with_registry!(opts, registry)?;
42        Ok(Self { counter, name })
43    }
44    /// Increments a counter by 1
45    #[instrument(skip_all, parent = Span::current(), level= "Trace")]
46    pub fn inc(&self) {
47        self.counter.inc();
48    }
49    /// Increments a counter by a value
50    #[instrument(skip_all, parent = Span::current(), level= "Trace")]
51    pub fn inc_by(&self, val: u64) {
52        self.counter.inc_by(val);
53    }
54    /// Gets the value of a counter
55    #[instrument(skip_all, parent = Span::current(), level= "Trace")]
56    pub fn get(&self) -> u64 {
57        self.counter.get()
58    }
59    /// Resets a counter
60    #[instrument(skip_all, parent = Span::current(), level= "Trace")]
61    pub fn reset(&self) {
62        self.counter.reset();
63    }
64}
65
66impl<S: HyperlightMetricOps> GetHyperlightMetric<IntCounter> for S {
67    #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
68    fn metric(&self) -> Result<&IntCounter> {
69        let metric = self.get_metric()?;
70        <&HyperlightMetric as TryInto<&IntCounter>>::try_into(metric)
71    }
72}
73
74impl<'a> TryFrom<&'a HyperlightMetric> for &'a IntCounter {
75    type Error = HyperlightError;
76    #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
77    fn try_from(metric: &'a HyperlightMetric) -> Result<Self> {
78        match metric {
79            HyperlightMetric::IntCounter(counter) => Ok(counter),
80            _ => Err(new_error!("metric is not a IntCounter")),
81        }
82    }
83}
84
85impl From<IntCounter> for HyperlightMetric {
86    #[instrument(skip_all, parent = Span::current(), level= "Trace")]
87    fn from(counter: IntCounter) -> Self {
88        HyperlightMetric::IntCounter(counter)
89    }
90}
91
92/// Increments an IntCounter by 1 or logs an error if the metric is not found
93#[macro_export]
94macro_rules! int_counter_inc {
95    ($metric:expr) => {{
96        match $crate::metrics::GetHyperlightMetric::<$crate::metrics::IntCounter>::metric($metric) {
97            Ok(val) => val.inc(),
98            Err(e) => log::error!("error getting metric: {}", e),
99        };
100    }};
101}
102
103/// Increments an IntCounter by a given value or logs an error if the metric is not found
104#[macro_export]
105macro_rules! int_counter_inc_by {
106    ($metric:expr, $val:expr) => {{
107        match $crate::metrics::GetHyperlightMetric::<$crate::metrics::IntCounter>::metric($metric) {
108            Ok(val) => val.inc_by($val),
109            Err(e) => log::error!("error getting metric: {}", e),
110        };
111    }};
112}
113
114/// Gets the value of an IntCounter or logs an error if the metric is not found
115#[macro_export]
116macro_rules! int_counter_get {
117    ($metric:expr) => {{
118        match $crate::metrics::GetHyperlightMetric::<$crate::metrics::IntCounter>::metric($metric) {
119            Ok(val) => val.get(),
120            Err(e) => {
121                log::error!("error getting metric: {}", e);
122                0
123            }
124        }
125    }};
126}
127
128/// Resets an IntCounter or logs an error if the metric is not found
129#[macro_export]
130macro_rules! int_counter_reset {
131    ($metric:expr) => {{
132        match $crate::metrics::GetHyperlightMetric::<$crate::metrics::IntCounter>::metric($metric) {
133            Ok(val) => val.reset(),
134            Err(e) => log::error!("error getting metric: {}", e),
135        };
136    }};
137}