Snippets: Tracing in Rust
September 13, 2025 · 2 min
This is for future me when I’m starting a new Rust project, want to use the tracing library, and don’t want to spend an hour remembering how the hell they expect you to use this library.
Should you just use log with env_logger instead? Maybe!
Dependencies
Tracing requires a “subscriber” that will listen to tracing events and then actually do things with it. In most cases, you want tracing-subscriber.
1cargo add tracing tracing-subscriber
Configuring Logging
Here’s the snippet for setting up the tracing subscriber to print to stdout.
1let log_level = tracing::Level::INFO;
2let subscriber = tracing_subscriber::FmtSubscriber::builder()
3 // Include the file name and line number for the log call
4 .with_line_number(true)
5 .with_file(true)
6 // Minimum Log level that will be logged
7 // ex. when set to INFO, this will log INFO, WARN, and ERROR
8 .with_max_level(log_level)
9 .finish();
10
11// Set this subscriber as the default
12tracing::subscriber::set_global_default(subscriber)
13 .expect("setting default subscriber failed");
Why use tracing if you’re just logging?
Tracing subscribers can be MUCH more than just logging.
Sentry
Crate: sentry_tracing
1cargo add sentry_tracing
1// NOTE: This is from the Sentry crate docs
2use tracing_subscriber::prelude::*;
3
4let _guard = sentry::init(sentry::ClientOptions {
5 // Enable capturing of traces; set this a to lower value in production
6 traces_sample_rate: 1.0,
7 ..sentry::ClientOptions::default()
8});
9
10// Register the Sentry tracing layer to capture breadcrumbs, events, and spans
11tracing_subscriber::registry()
12 .with(tracing_subscriber::fmt::layer())
13 .with(sentry::integrations::tracing::layer())
14 .init();
Otel
Crate: tracing_opentelemetry
1cargo add tracing_opentelemetry
1// NOTE: This is from the Otel crate docs
2use opentelemetry_sdk::trace::SdkTracerProvider;
3use opentelemetry::trace::{Tracer, TracerProvider as _};
4use tracing::{error, span};
5use tracing_subscriber::layer::SubscriberExt;
6use tracing_subscriber::Registry;
7
8// Create a new OpenTelemetry trace pipeline that prints to stdout
9let provider = SdkTracerProvider::builder()
10 .with_simple_exporter(opentelemetry_stdout::SpanExporter::default())
11 .build();
12let tracer = provider.tracer("readme_example");
13
14// Create a tracing layer with the configured tracer
15let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
16
17// Use the tracing subscriber `Registry`, or any other subscriber
18// that impls `LookupSpan`
19let subscriber = Registry::default().with(telemetry);
20
21// Trace executed code
22tracing::subscriber::with_default(subscriber, || {
23 // Spans will be sent to the configured OpenTelemetry exporter
24 let root = span!(tracing::Level::TRACE, "app_start", work_units = 2);
25 let _enter = root.enter();
26
27 error!("This event will be logged in the root span.");
28});