solana_metrics/
lib.rs

1#![allow(clippy::arithmetic_side_effects)]
2pub mod counter;
3pub mod datapoint;
4pub mod metrics;
5pub mod poh_timing_point;
6pub use crate::metrics::{flush, query, set_host_id, set_panic_hook, submit};
7use std::sync::{
8    atomic::{AtomicU64, Ordering},
9    Arc,
10};
11
12// To track an external counter which cannot be reset and is always increasing
13#[derive(Default)]
14pub struct MovingStat {
15    value: AtomicU64,
16}
17
18impl MovingStat {
19    pub fn update_stat(&self, old_value: &MovingStat, new_value: u64) {
20        let old = old_value.value.swap(new_value, Ordering::Acquire);
21        self.value
22            .fetch_add(new_value.saturating_sub(old), Ordering::Release);
23    }
24
25    pub fn load_and_reset(&self) -> u64 {
26        self.value.swap(0, Ordering::Acquire)
27    }
28}
29
30/// A helper that sends the count of created tokens as a datapoint.
31#[allow(clippy::redundant_allocation)]
32pub struct TokenCounter(Arc<&'static str>);
33
34impl TokenCounter {
35    /// Creates a new counter with the specified metrics `name`.
36    pub fn new(name: &'static str) -> Self {
37        Self(Arc::new(name))
38    }
39
40    /// Creates a new token for this counter. The metric's value will be equal
41    /// to the number of `CounterToken`s.
42    pub fn create_token(&self) -> CounterToken {
43        // new_count = strong_count
44        //    - 1 (in TokenCounter)
45        //    + 1 (token that's being created)
46        datapoint_info!(*self.0, ("count", Arc::strong_count(&self.0), i64));
47        CounterToken(self.0.clone())
48    }
49}
50
51/// A token for `TokenCounter`.
52#[allow(clippy::redundant_allocation)]
53pub struct CounterToken(Arc<&'static str>);
54
55impl Clone for CounterToken {
56    fn clone(&self) -> Self {
57        // new_count = strong_count
58        //    - 1 (in TokenCounter)
59        //    + 1 (token that's being created)
60        datapoint_info!(*self.0, ("count", Arc::strong_count(&self.0), i64));
61        CounterToken(self.0.clone())
62    }
63}
64
65impl Drop for CounterToken {
66    fn drop(&mut self) {
67        // new_count = strong_count
68        //    - 1 (in TokenCounter, if it still exists)
69        //    - 1 (token that's being dropped)
70        datapoint_info!(
71            *self.0,
72            ("count", Arc::strong_count(&self.0).saturating_sub(2), i64)
73        );
74    }
75}
76
77impl Drop for TokenCounter {
78    fn drop(&mut self) {
79        datapoint_info!(
80            *self.0,
81            ("count", Arc::strong_count(&self.0).saturating_sub(2), i64)
82        );
83    }
84}