iroh_metrics/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! Metrics library for iroh

#![deny(missing_docs, rustdoc::broken_intra_doc_links)]
#![cfg_attr(iroh_docsrs, feature(doc_auto_cfg))]

mod base;
pub use base::*;

mod metrics;
pub use metrics::*;

pub mod iterable;

#[cfg(feature = "static_core")]
pub mod static_core;

#[cfg(feature = "service")]
pub mod service;

/// Derives [`MetricsGroup`], [`Iterable`] and [`Default`] for a struct.
///
/// This derive macro only works on structs with named fields.
///
/// It will generate a [`Default`] impl which expects all fields to be of a type
/// that has a public `new` method taking a single `&'static str` argument.
/// The [`Default::default`] method will call each field's `new` method with the
/// first line of the field's doc comment as argument. Alternatively, you can override
/// the value passed to `new` by setting a `#[metrics(help = "my help")]`
/// attribute on the field.
///
/// It will also generate a [`MetricsGroup`] impl. By default, the struct's name,
/// converted to `camel_case` will be used as the return value of the [`MetricsGroup::name`]
/// method. The name can be customized by setting a `#[metrics(name = "my-name")]` attribute.
///
/// It will also generate a [`Iterable`] impl.
///
/// [`Iterable`]: iterable::Iterable
pub use iroh_metrics_derive::MetricsGroup;

// This lets us use the derive metrics in the lib tests within this crate.
extern crate self as iroh_metrics;

use std::collections::HashMap;

/// Potential errors from this library.
#[derive(Debug, thiserror::Error)]
pub enum Error {
    /// Indicates that the metrics have not been enabled.
    #[error("Metrics not enabled")]
    NoMetrics,
    /// Any IO related error.
    #[error("IO: {0}")]
    Io(#[from] std::io::Error),
}

/// Parses Prometheus metrics from a string.
pub fn parse_prometheus_metrics(data: &str) -> HashMap<String, f64> {
    let mut metrics = HashMap::new();
    for line in data.lines() {
        if line.starts_with('#') {
            continue;
        }
        let parts: Vec<&str> = line.split_whitespace().collect();
        if parts.len() < 2 {
            continue;
        }
        let metric = parts[0];
        let value = parts[1].parse::<f64>();
        if value.is_err() {
            continue;
        }
        metrics.insert(metric.to_string(), value.unwrap());
    }
    metrics
}