fuel_core_metrics/
futures.rs

1use crate::global_registry;
2use prometheus_client::{
3    encoding::text::encode,
4    metrics::counter::Counter,
5};
6use std::ops::Deref;
7
8pub mod future_tracker;
9pub mod metered_future;
10
11/// The statistic of the futures life cycle.
12#[derive(Default, Debug, Clone)]
13pub struct FuturesMetrics {
14    /// The time spent for real actions by the future.
15    ///
16    /// Time is in nanoseconds.
17    // TODO: Use `AtomicU128` when it is stable, otherwise, the field can overflow at some point.
18    pub busy: Counter,
19    /// The idle time of awaiting sub-tasks or any action from the system/user.
20    ///
21    /// Time is in nanoseconds.
22    // TODO: Use `AtomicU128` when it is stable, otherwise, the field can overflow at some point.
23    pub idle: Counter,
24}
25
26impl FuturesMetrics {
27    pub fn obtain_futures_metrics(futures_name: &str) -> FuturesMetrics {
28        let reg =
29            regex::Regex::new("^[a-zA-Z_:][a-zA-Z0-9_:]*$").expect("It is a valid Regex");
30        if !reg.is_match(futures_name) {
31            panic!("The futures metric {} has incorrect name.", futures_name);
32        }
33        let lifecycle = FuturesMetrics::default();
34        let mut lock = global_registry().registry.lock();
35
36        // Check that it is a unique futures.
37        let mut encoded_bytes = String::new();
38        encode(&mut encoded_bytes, lock.deref())
39            .expect("Unable to decode futures metrics");
40
41        let reg = regex::Regex::new(format!("\\b{}\\b", futures_name).as_str())
42            .expect("It is a valid Regex");
43        if reg.is_match(encoded_bytes.as_str()) {
44            tracing::warn!(
45                "Futures metrics with '{}' name is already registered",
46                futures_name
47            );
48        }
49
50        lock.register(
51            format!("{}_idle_ns", futures_name),
52            format!("The idle time of the {} future", futures_name),
53            lifecycle.idle.clone(),
54        );
55        lock.register(
56            format!("{}_busy_ns", futures_name),
57            format!("The busy time of the {} future", futures_name),
58            lifecycle.busy.clone(),
59        );
60
61        lifecycle
62    }
63}
64
65#[test]
66fn register_success() {
67    FuturesMetrics::obtain_futures_metrics("Foo");
68    FuturesMetrics::obtain_futures_metrics("Bar");
69}