bothan_lib/metrics/
rest.rs

1//! Metrics collection for REST polling operations.
2//!
3//! This module provides the [`Metrics`] struct and related types for tracking REST polling statistics
4//! such as the number of polling requests and their durations. It leverages OpenTelemetry for metrics
5//! instrumentation, supporting monitoring and observability.
6
7use opentelemetry::metrics::{Counter, Histogram};
8use opentelemetry::{KeyValue, global};
9use strum_macros::Display;
10
11/// Holds counters and histograms for REST polling metrics.
12#[derive(Clone, Debug)]
13pub struct Metrics {
14    /// Counter tracking total polling requests.
15    polling_total: Counter<u64>,
16
17    /// Histogram recording polling durations in milliseconds.
18    polling_duration: Histogram<u64>,
19}
20
21impl Metrics {
22    /// Creates a new [`Metrics`] instance configured for a specified source.
23    ///
24    /// # Arguments
25    ///
26    /// * `source` - A string identifying the source whose metrics are being recorded.
27    ///
28    ///
29    /// # Examples
30    ///
31    /// ```rust
32    /// use bothan_lib::metrics::rest::Metrics;
33    /// use bothan_lib::metrics::rest::PollingResult;
34    ///
35    /// let metrics = Metrics::new("example_source");
36    /// metrics.update_rest_polling(123, PollingResult::Success);
37    /// ```
38    pub fn new(source: &'static str) -> Self {
39        let meter = global::meter(source);
40
41        let polling_total = meter
42            .u64_counter("rest_polling")
43            .with_description("Total number of polling requests sent by the worker to the source")
44            .build();
45
46        let polling_duration = meter
47            .u64_histogram("rest_polling_duration_milliseconds")
48            .with_description(
49                "Time taken by the worker to complete each polling request to fetch asset info",
50            )
51            .with_unit("milliseconds")
52            .build();
53
54        Self {
55            polling_total,
56            polling_duration,
57        }
58    }
59
60    /// Records a polling request result and duration.
61    ///
62    /// # Arguments
63    ///
64    /// * `elapsed_time` - Duration of the polling request in milliseconds.
65    /// * `status` - The result of the polling request (success, failure, or timeout).
66    pub fn update_rest_polling(&self, elapsed_time: u128, status: PollingResult) {
67        let labels = &[KeyValue::new("status", status.to_string())];
68        self.polling_total.add(1, labels);
69        self.polling_duration.record(elapsed_time as u64, labels);
70    }
71}
72
73/// Possible results for a REST polling operation.
74#[derive(Display)]
75#[strum(serialize_all = "snake_case")]
76pub enum PollingResult {
77    /// Indicates the polling request completed successfully.
78    Success,
79
80    /// Indicates the polling request encountered an error.
81    Failed,
82
83    /// Indicates the polling request did not complete within the expected polling duration.
84    Timeout,
85}