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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
//! Metrics library for iroh
#![deny(missing_docs, rustdoc::broken_intra_doc_links)]
pub mod metrics;
/// Expose core types and traits
pub mod core;
/// Expose iroh metrics
#[cfg(feature = "metrics")]
mod service;
use core::UsageStatsReport;
use std::collections::HashMap;
/// Reexport to make matching versions easier.
pub use struct_iterable;
/// Increment the given counter by 1.
#[macro_export]
macro_rules! inc {
($m:ty, $f:ident) => {
<$m as $crate::core::Metric>::with_metric(|m| m.$f.inc());
};
}
/// Increment the given counter `n`.
#[macro_export]
macro_rules! inc_by {
($m:ty, $f:ident, $n:expr) => {
<$m as $crate::core::Metric>::with_metric(|m| m.$f.inc_by($n));
};
}
/// Set the given counter to `n`.
#[macro_export]
macro_rules! set {
($m:ty, $f:ident, $n:expr) => {
<$m as $crate::core::Metric>::with_metric(|m| m.$f.set($n));
};
}
/// Report usage statistics to the configured endpoint.
#[allow(unused_variables)]
pub async fn report_usage_stats(report: &UsageStatsReport) {
#[cfg(feature = "metrics")]
{
if let Some(core) = core::Core::get() {
core.usage_reporter()
.report_usage_stats(report)
.await
.unwrap_or_else(|e| {
tracing::error!("Failed to report usage stats: {}", e);
});
}
}
}
/// Parse Prometheus metrics from a string.
pub fn parse_prometheus_metrics(data: &str) -> anyhow::Result<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());
}
Ok(metrics)
}
/// Configuration for pushing metrics to a remote endpoint.
#[derive(PartialEq, Eq, Debug, Default, serde::Deserialize, Clone)]
pub struct PushMetricsConfig {
/// The push interval in seconds.
pub interval: u64,
/// The endpoint url for the push metrics collector.
pub endpoint: String,
/// The name of the service you're exporting metrics for.
///
/// Generally, `metrics_exporter` is good enough for use
/// outside of production deployments.
pub service_name: String,
/// The name of the instance you're exporting metrics for.
///
/// This should be device-unique. If not, this will sum up
/// metrics from different devices.
///
/// E.g. `username-laptop`, `username-phone`, etc.
///
/// Another potential scheme with good privacy would be a
/// keyed blake3 hash of the secret key. (This gives you
/// an identifier that is as unique as a `NodeID`, but
/// can't be correlated to `NodeID`s.)
pub instance_name: String,
/// The username for basic auth for the push metrics collector.
pub username: Option<String>,
/// The password for basic auth for the push metrics collector.
pub password: String,
}