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});