datadog_tracing/
init.rs

1use crate::formatter::DatadogFormatter;
2use crate::shutdown::TracerShutdown;
3use crate::tracer::build_tracer;
4use opentelemetry::trace::TraceError;
5use std::env;
6use tracing::Subscriber;
7use tracing_appender::non_blocking::{NonBlocking, WorkerGuard};
8use tracing_subscriber::layer::SubscriberExt;
9use tracing_subscriber::registry::LookupSpan;
10use tracing_subscriber::util::SubscriberInitExt;
11use tracing_subscriber::{EnvFilter, Layer, Registry};
12
13fn loglevel_filter_layer(dd_enabled: bool) -> EnvFilter {
14    let log_level = env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string());
15
16    // `axum_tracing_opentelemetry` should be a level info to emit opentelemetry trace & span
17    let axum_tracing_log_level = env::var("AXUM_TRACING_LOG_LEVEL").unwrap_or_else(|_| {
18        if dd_enabled {
19            "trace".to_string()
20        } else {
21            "off".to_string()
22        }
23    });
24
25    // `otel::setup` set to debug to log detected resources, configuration read and infered
26    let otel_log_level = env::var("OTEL_LOG_LEVEL").unwrap_or_else(|_| "debug".to_string());
27
28    env::set_var(
29        "RUST_LOG",
30        format!("{log_level},otel::tracing={axum_tracing_log_level},otel={otel_log_level}"),
31    );
32
33    EnvFilter::from_default_env()
34}
35
36fn log_layer<S>(
37    dd_enabled: bool,
38    non_blocking: NonBlocking,
39) -> Box<dyn Layer<S> + Send + Sync + 'static>
40where
41    S: Subscriber + for<'a> LookupSpan<'a>,
42{
43    if dd_enabled {
44        Box::new(
45            tracing_subscriber::fmt::layer()
46                .json()
47                .event_format(DatadogFormatter)
48                .with_writer(non_blocking),
49        )
50    } else {
51        Box::new(tracing_subscriber::fmt::layer().with_writer(non_blocking))
52    }
53}
54
55pub fn init() -> Result<(WorkerGuard, TracerShutdown), TraceError> {
56    let (non_blocking, guard) = tracing_appender::non_blocking(std::io::stdout());
57
58    let dd_enabled = env::var("DD_ENABLED").map(|s| s == "true").unwrap_or(false);
59
60    let tracer = if dd_enabled {
61        Some(build_tracer()?)
62    } else {
63        None
64    };
65    let telemetry_layer = tracer.map(|tracer| tracing_opentelemetry::layer().with_tracer(tracer));
66
67    Registry::default()
68        .with(loglevel_filter_layer(dd_enabled))
69        .with(log_layer(dd_enabled, non_blocking))
70        .with(telemetry_layer)
71        .init();
72
73    Ok((guard, TracerShutdown {}))
74}