Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting started

The workspace packages are version 0.33.1. tracing-otel has no default features, so applications must enable the capability they use.

Application logging

Enable logger for code-based configuration:

[dependencies]
tracing-otel = { version = "0.33.1", features = ["logger"] }
anyhow = "1"
tracing = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use tracing_otel::{LogFormat, Logger};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let _guard = Logger::new("inventory-api")
        .with_format(LogFormat::Json)
        .with_ansi(false)
        .init()?;

    tracing::info!(component = "startup", "service ready");
    Ok(())
}

Keep the returned LoggerGuard alive for the whole application. Dropping it shuts down the OpenTelemetry providers and then releases any non-blocking file writer guard.

Environment-based configuration

Enable env when configuration should come from environment variables. It includes logger:

[dependencies]
tracing-otel = { version = "0.33.1", features = ["env"] }
#![allow(unused)]
fn main() {
use tracing_otel::Logger;

fn run() -> anyhow::Result<()> {
let _guard = Logger::from_env(Some("LOG"))?.init()?;
Ok(())
}
}

With the LOG prefix, fields map to names such as LOG_SERVICE_NAME, LOG_FORMAT, and LOG_SAMPLE_RATIO. See Logger configuration for the complete mapping used by the repository.

Axum middleware

axum-otel supplies the request-span callbacks; it does not replace subscriber initialization:

[dependencies]
axum-otel = "0.33.1"
tracing-otel = { version = "0.33.1", features = ["logger"] }
anyhow = "1"
axum = "0.8"
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] }
tower-http = { version = "0.6", features = ["trace"] }

Continue with Axum request tracing for a complete layer setup.