commonware_runtime/tokio/
telemetry.rs

1//! Utilities for collecting and reporting telemetry data.
2
3use super::{
4    tracing::{export, Config},
5    Context,
6};
7use crate::{telemetry::metrics, Metrics, Spawner};
8use std::net::SocketAddr;
9use tracing::Level;
10use tracing_subscriber::{layer::SubscriberExt, Registry};
11
12/// Initialize telemetry with the given configuration.
13pub fn init(context: Context, level: Level, metrics: Option<SocketAddr>, traces: Option<Config>) {
14    // Create fmt layer for logging
15    let fmt_layer = tracing_subscriber::fmt::layer()
16        .json()
17        .with_line_number(true)
18        .with_thread_ids(true)
19        .with_file(true)
20        .with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE);
21
22    // Create a filter layer to set the maximum level to INFO
23    let filter = tracing_subscriber::EnvFilter::new(level.to_string());
24
25    // Expose metrics over HTTP
26    if let Some(cfg) = metrics {
27        context
28            .with_label("metrics")
29            .spawn(move |context| async move { metrics::server::serve(context, cfg).await });
30    }
31
32    // Combine layers into a single subscriber
33    if let Some(cfg) = traces {
34        // Initialize tracing
35        let tracer = export(cfg).expect("Failed to initialize tracer");
36
37        // Create OpenTelemetry layer for tracing
38        let telemetry_layer = tracing_opentelemetry::layer().with_tracer(tracer);
39
40        // Set the global subscriber
41        let subscriber = Registry::default()
42            .with(filter)
43            .with(fmt_layer)
44            .with(telemetry_layer);
45        tracing::subscriber::set_global_default(subscriber).expect("Failed to set subscriber");
46    } else {
47        // Set the global subscriber
48        let subscriber = Registry::default().with(filter).with(fmt_layer);
49        tracing::subscriber::set_global_default(subscriber).expect("Failed to set subscriber");
50    };
51}