Skip to main content

sentry_tracing/
lib.rs

1//! Capture `tracing` spans and events as Sentry traces and structured logs.
2//!
3//! For most applications, we recommend installing only these two layers:
4//!
5//! - [`SpanLayer`] captures `tracing` spans as Sentry transactions and spans.
6//! - [`LogLayer`] captures `tracing` events as Sentry structured logs. Requires the `logs` feature.
7//!
8//! We also provide the following layers, but recommend the span and log layers above for most
9//! applications:
10//!
11//! - [`ErrorLayer`] captures `tracing` events as Sentry error events, with support for tags and
12//!   exception information.
13//! - [`BreadcrumbLayer`] adds `tracing` events as breadcrumbs on subsequent Sentry error events.
14//!
15//! For migration from the legacy combined layer, see [`SentryLayer`].
16//!
17//! # Getting started
18//!
19//! Enable the `tracing` and `logs` features on `sentry` to use its tracing integration re-export.
20//! Set a traces sample rate to capture transactions, then install the span and log layers with
21//! explicit level filters:
22//!
23//! ```
24//! # #[cfg(feature = "logs")]
25//! # {
26//! use sentry::integrations::tracing::{LogLayer, SpanLayer};
27//! use tracing_subscriber::filter::LevelFilter;
28//! use tracing_subscriber::prelude::*;
29//!
30//! let _guard = sentry::init(
31//!     sentry::ClientOptions::new()
32//!         // Use a lower sample rate in production.
33//!         .traces_sample_rate(1.0),
34//! );
35//!
36//! tracing_subscriber::registry()
37//!     .with(SpanLayer::new().with_filter(LevelFilter::INFO))
38//!     .with(LogLayer::new().with_filter(LevelFilter::INFO))
39//!     .init();
40//! # }
41//! ```
42//!
43//! The layers do not filter by level internally. The filters above capture `INFO`, `WARN`, and
44//! `ERROR` telemetry, excluding `DEBUG` and `TRACE`. Adjust each layer's filter independently to
45//! control volume. Global subscriber filters also apply and can suppress telemetry before the
46//! Sentry layers receive it.
47//!
48//! # Spans
49//!
50//! `SpanLayer` creates a Sentry transaction when no Sentry span is active, or a child span
51//! otherwise. For example,
52//! [`tracing::instrument`](https://docs.rs/tracing/latest/tracing/attr.instrument.html) creates
53//! spans for instrumented functions; arguments become span data unless skipped.
54//!
55//! With the log layer installed, the `info!` event below produces a log associated with the same
56//! trace as the instrumented functions:
57//!
58//! ```
59//! #[tracing::instrument]
60//! async fn outer() {
61//!     inner(42).await;
62//! }
63//!
64//! #[tracing::instrument]
65//! async fn inner(value: i32) {
66//!     tracing::info!(value, "completed step");
67//! }
68//! ```
69//!
70//! By default, the Sentry span name matches the `tracing` span name, and its operation is
71//! `<target>::<span name>`.
72//!
73//! ## Special span fields
74//!
75//! - `sentry.name` overrides the Sentry span name, including when recorded after creation.
76//! - `sentry.op` overrides the Sentry span operation, including when recorded after creation.
77//! - `sentry.trace` continues the trace from a `sentry-trace` header. It must be set when a
78//!   **root Sentry span** is created, meaning no Sentry span is active in the current scope.
79//!   Applying it to a child Sentry span or recording it after creation has no effect.
80//!
81//! ```
82//! #[tracing::instrument(skip_all, fields(
83//!     sentry.name = "GET /payments",
84//!     sentry.op = "http.server",
85//!     sentry.trace = headers.get("sentry-trace").unwrap_or(&"".to_owned()),
86//! ))]
87//! async fn handle_request(headers: std::collections::HashMap<String, String>) {
88//!     // ...
89//! }
90//! ```
91//!
92//! # Logs
93//!
94//! `LogLayer` sends events accepted by its filter as structured logs. Event fields become log
95//! attributes.
96//!
97//! ```
98//! tracing::info!(number = 42, my.key = "value", "Processed request");
99//! ```
100
101#![cfg_attr(doc_cfg, feature(doc_cfg))]
102#![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")]
103#![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")]
104
105mod converters;
106mod layer;
107
108#[cfg(feature = "logs")]
109#[expect(deprecated, reason = "re-exporting deprecated legacy mapper helpers")]
110pub use converters::log_from_event;
111#[expect(deprecated, reason = "re-exporting deprecated legacy mapper helpers")]
112pub use converters::{breadcrumb_from_event, event_from_event};
113pub use layer::*;
114
115const TAGS_PREFIX: &str = "tags.";
116const SENTRY_OP_FIELD: &str = "sentry.op";
117const SENTRY_NAME_FIELD: &str = "sentry.name";
118const SENTRY_TRACE_FIELD: &str = "sentry.trace";