Automatic Instrumentation

Learn what instrumentation automatically captures transactions.

The Rust SDK offers an integration for the tracing ecosystem that will track spans automatically for every function that is annotated with #[tracing::instrument].

The integration takes care of starting a new transaction or a new child span of an already running transaction, and it automatically sets the created span as the current span.

Copied
fn main() {
    tracing_subscriber::Registry::default()
        .with(sentry::integrations::tracing::layer())
        .init();

    let _sentry = sentry::init(sentry::ClientOptions {
        release: sentry::release_name!(),
        traces_sample_rate: 1.0,
        // Capture user IPs and potentially sensitive headers when using HTTP server integrations
        // see https://docs.sentry.io/platforms/rust/data-management/data-collected for more info
        send_default_pii: true,
        ..Default::default()
    });

    main_span1();
}

#[tracing::instrument]
fn main_span1() {
    thread::sleep(Duration::from_millis(50));

    main_span2()
}

#[tracing::instrument]
fn main_span2() {
    thread::sleep(Duration::from_millis(200));
}

The Rust SDK offers an integration for the OpenTelemetry ecosystem. The integration can automatically capture Sentry spans/transactions for every span created through the OpenTelemetry API, with support for distributed tracing. The integration also captures errors with the correct span and trace associations.

For this integration to work as intended, only the OpenTelemetry tracing API should be used to manage spans. Mixing it with the Sentry tracing API will result in incorrectly nested spans.

To get started using the OpenTelemetry integration for the Sentry Rust SDK, add the necessary dependencies to your Cargo.toml:

Cargo.toml
Copied
[dependencies]
sentry = "0.38.1"
opentelemetry = { version = "0.29.1", features = ["trace"] }
opentelemetry_sdk = { version = "0.29.0", features = ["trace"] }

Initialize the SDK, then create and register the SentryPropagator and SentrySpanProcessor:

Copied
use opentelemetry::{
    global,
    trace::{TraceContextExt, Tracer},
    KeyValue,
};
use opentelemetry_sdk::trace::SdkTracerProvider;
use sentry::integrations::opentelemetry as sentry_opentelemetry;

// Initialize the Sentry SDK
let _guard = sentry::init((
    "https://examplePublicKey@o0.ingest.sentry.io/0",
    sentry::ClientOptions {
        release: sentry::release_name!(),
        // Enable capturing of traces; set this a to lower value in production.
        traces_sample_rate: 1.0,
        ..sentry::ClientOptions::default()
    },
));

// Register the Sentry propagator for distributed tracing
global::set_text_map_propagator(sentry_opentelemetry::SentryPropagator::new());

let tracer_provider = SdkTracerProvider::builder()
    // Register the Sentry span processor to send OpenTelemetry spans to Sentry
    .with_span_processor(sentry_opentelemetry::SentrySpanProcessor::new())
    .build();

global::set_tracer_provider(tracer_provider);

Use the OpenTelemetry API to create spans. They will be captured by Sentry:

Copied
let tracer = global::tracer("tracer");
// Creates a Sentry span (transaction) with the name set to "example"
tracer.in_span("example", |_| {
    // Creates a Sentry child span with the name set to "child"
    tracer.in_span("child", |cx| {
        // OTEL span attributes are captured as data attributes on the Sentry span
        cx.span().set_attribute(KeyValue::new("my", "attribute"));

        // Captures a Sentry error message and associates it with the ongoing child span
        sentry::capture_message("Everything is on fire!", sentry::Level::Error);
    });
});

The Sentry SDK offers an integration for the tower ecosystem which can automatically continue a trace from an incoming HTTP request.

When combining both layers, order matters. For example, with tower::ServiceBuilder, you must define the Hub layer before the Http one, like so:

Copied
use sentry_tower::{NewSentryLayer, SentryHttpLayer};
use tower::ServiceBuilder;

let layer = ServiceBuilder::new()
    .layer(NewSentryLayer::new_from_top())
    .layer(SentryHttpLayer::with_transaction());
Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").