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}