darkwing/server/utils/metrics.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
use anyhow::Context as _;
use metrics_exporter_prometheus::{PrometheusBuilder, PrometheusHandle};
const QUANTILES: &[f64] =
&[0.0, 0.1, 0.3, 0.5, 0.6, 0.8, 0.9, 0.95, 0.99, 0.999, 1.0];
/// Measures the execution time of a code block and records it as a histogram
/// metric.
///
/// # Arguments
///
/// * `$name` - The name of the metric to record the timing under
/// * `$body` - The code block or expression to measure
///
/// # Example
///
/// ```
/// let result = measure_time!("my_operation", db.fetch_user(id));
/// ```
/// Or:
/// ```
/// let result = measure_time!("my_operation", {
/// db.fetch_user(id)
/// });
/// ```
///
/// This will record the execution time of the code block under the metric name
/// `darkwing_time_my_operation_duration_seconds` as a histogram in seconds.
#[macro_export]
macro_rules! measure_time {
($name:expr, $body:expr) => {{
let name = format!("darkwing_time_{}_duration_seconds", $name);
let start = std::time::Instant::now();
let result = $body;
let duration = start.elapsed();
metrics::histogram!(name).record(duration.as_secs_f64());
result
}};
}
/// Builds and installs a Prometheus metrics recorder with custom histogram
/// buckets.
///
/// Configures buckets for:
/// * HTTP request durations (exponential)
/// * Diff and data directory sizes (size-based)
/// * Size reduction ratios
/// * All duration metrics (exponential)
///
/// # Errors
/// Returns an error if bucket configuration or recorder installation fails
pub fn build_recorder() -> anyhow::Result<PrometheusHandle> {
PrometheusBuilder::new()
.set_quantiles(QUANTILES)?
.install_recorder()
.context("could not install metrics recorder")
}