sentry-tracing 0.49.4

Sentry integration for the tracing and tracing-subscriber crates.
Documentation

Sentry Rust SDK: sentry-tracing

Capture tracing spans and events as Sentry traces and structured logs.

For most applications, we recommend installing only these two layers:

  • [SpanLayer] captures tracing spans as Sentry transactions and spans.
  • [LogLayer] captures tracing events as Sentry structured logs. Requires the logs feature.

We also provide the following layers, but recommend the span and log layers above for most applications:

  • [ErrorLayer] captures tracing events as Sentry error events, with support for tags and exception information.
  • [BreadcrumbLayer] adds tracing events as breadcrumbs on subsequent Sentry error events.

For migration from the legacy combined layer, see [SentryLayer].

Getting started

Enable the tracing and logs features on sentry to use its tracing integration re-export. Set a traces sample rate to capture transactions, then install the span and log layers with explicit level filters:

use sentry::integrations::tracing::{LogLayer, SpanLayer};
use tracing_subscriber::filter::LevelFilter;
use tracing_subscriber::prelude::*;

let _guard = sentry::init(
    sentry::ClientOptions::new()
        // Use a lower sample rate in production.
        .traces_sample_rate(1.0),
);

tracing_subscriber::registry()
    .with(SpanLayer::new().with_filter(LevelFilter::INFO))
    .with(LogLayer::new().with_filter(LevelFilter::INFO))
    .init();

The layers do not filter by level internally. The filters above capture INFO, WARN, and ERROR telemetry, excluding DEBUG and TRACE. Adjust each layer's filter independently to control volume. Global subscriber filters also apply and can suppress telemetry before the Sentry layers receive it.

Spans

SpanLayer creates a Sentry transaction when no Sentry span is active, or a child span otherwise. For example, tracing::instrument creates spans for instrumented functions; arguments become span data unless skipped.

With the log layer installed, the info! event below produces a log associated with the same trace as the instrumented functions:

#[tracing::instrument]
async fn outer() {
    inner(42).await;
}

#[tracing::instrument]
async fn inner(value: i32) {
    tracing::info!(value, "completed step");
}

By default, the Sentry span name matches the tracing span name, and its operation is <target>::<span name>.

Special span fields

  • sentry.name overrides the Sentry span name, including when recorded after creation.
  • sentry.op overrides the Sentry span operation, including when recorded after creation.
  • sentry.trace continues the trace from a sentry-trace header. It must be set when a root Sentry span is created, meaning no Sentry span is active in the current scope. Applying it to a child Sentry span or recording it after creation has no effect.
#[tracing::instrument(skip_all, fields(
    sentry.name = "GET /payments",
    sentry.op = "http.server",
    sentry.trace = headers.get("sentry-trace").unwrap_or(&"".to_owned()),
))]
async fn handle_request(headers: std::collections::HashMap<String, String>) {
    // ...
}

Logs

LogLayer sends events accepted by its filter as structured logs. Event fields become log attributes.

tracing::info!(number = 42, my.key = "value", "Processed request");

Resources

License: MIT

  • Discord server for project discussions.
  • Follow @sentry on X for updates.