52 releases (26 breaking)
| new 0.32.3 | Jan 12, 2026 |
|---|---|
| 0.32.2 | Nov 3, 2025 |
| 0.32.1 | Oct 14, 2025 |
| 0.29.0 | Jun 3, 2025 |
| 0.2.1 | Jun 11, 2022 |
#563 in Profiling
233,478 downloads per month
Used in 21 crates
(17 directly)
54KB
792 lines
axum-tracing-opentelemetry
Middlewares to integrate axum + tracing + opentelemetry.
- Read OpenTelemetry header from incoming request
- Start a new trace if no trace found in the incoming request
- Trace is attached into tracing'span
- OpenTelemetry Span is created on close of the tracing's span (behavior from [tracing-opentelemetry])
For examples, you can look at the examples folder.
//...
use axum_tracing_opentelemetry::middleware::{OtelAxumLayer, OtelInResponseLayer};
#[tokio::main]
async fn main() -> Result<(), axum::BoxError> {
// very opinionated init of tracing, look as is source to make your own
let _guard = init_tracing_opentelemetry::TracingConfig::production().init_subscriber()?;
let app = app();
// run it
let addr = &"0.0.0.0:3000".parse::<SocketAddr>()?;
tracing::warn!("listening on {}", addr);
let listener = tokio::net::TcpListener::bind(addr).await?;
axum::serve(listener, app.into_make_service()).await?;
Ok(())
}
fn app() -> Router {
Router::new()
.route("/", get(index)) // request processed inside span
// include trace context as header into the response
.layer(OtelInResponseLayer::default())
//start OpenTelemetry trace on incoming request
.layer(OtelAxumLayer::default())
.route("/health", get(health)) // request processed without span / trace
}
For more info about how to initialize, you can look at crate init-tracing-opentelemetry or tracing-opentelemetry.

Changelog - History
Dependencies
~13–26MB
~250K SLoC