1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! 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:
//!
//! ```
//! # #[cfg(feature = "logs")]
//! # {
//! 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`](https://docs.rs/tracing/latest/tracing/attr.instrument.html) 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");
//! ```
pub use log_from_event;
pub use ;
pub use *;
const TAGS_PREFIX: &str = "tags.";
const SENTRY_OP_FIELD: &str = "sentry.op";
const SENTRY_NAME_FIELD: &str = "sentry.name";
const SENTRY_TRACE_FIELD: &str = "sentry.trace";