Skip to content

doc(tracing): Add docs for errors and custom tags with tracing #586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sentry-tracing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ sentry-backtrace = { version = "0.31.3", path = "../sentry-backtrace", optional
log = "0.4"
sentry = { path = "../sentry", default-features = false, features = ["test"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3.1", features = ["fmt", "registry"] }
tokio = { version = "1.8", features = ["rt-multi-thread", "macros", "time"] }
168 changes: 114 additions & 54 deletions sentry-tracing/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,79 +1,139 @@
//! Adds support for automatic Breadcrumb, Event and Transaction capturing from
//! tracing events, similar to the `sentry-log` crate.
//! Support for automatic breadcrumb, event, and trace capturing from `tracing` events.
//!
//! The `tracing` crate is supported in three ways. First, events can be captured
//! as breadcrumbs for later. Secondly, error events can be captured as events
//! to Sentry. Finally, spans can be recorded as structured transaction events.
//! By default, events above `Info` are recorded as breadcrumbs, events above
//! `Error` are captured as error events, and spans above `Info` are recorded
//! as transactions.
//! The `tracing` crate is supported in three ways. First, events can be captured as breadcrumbs for
//! later. Secondly, error events can be captured as events to Sentry. Finally, spans can be
//! recorded as structured transaction events. By default, events above `Info` are recorded as
//! breadcrumbs, events above `Error` are captured as error events, and spans above `Info` are
//! recorded as transactions.
//!
//! By using this crate in combination with `tracing-subscriber` and its `log`
//! integration, `sentry-log` does not need to be used, as logs will be ingested
//! in the tracing system and generate events, thus be relayed to this crate. It
//! effectively replaces `sentry-log` when tracing is used.
//! # Configuration
//!
//! # Examples
//! To fully enable the tracing integration, set the traces sample rate and add a layer to the
//! tracing subscriber:
//!
//! ```rust
//! use std::time::Duration;
//! ```
//! use tracing_subscriber::prelude::*;
//!
//! let _guard = sentry::init(sentry::ClientOptions {
//! // Enable capturing of traces; set this a to lower value in production:
//! traces_sample_rate: 1.0,
//! ..sentry::ClientOptions::default()
//! });
//!
//! // Register the Sentry tracing layer to capture breadcrumbs, events, and spans:
//! tracing_subscriber::registry()
//! .with(tracing_subscriber::fmt::layer())
//! .with(sentry_tracing::layer())
//! .init();
//! ```
//!
//! use tokio::time::sleep;
//! It is also possible to set an explicit filter, to customize which log events are captured by
//! Sentry:
//!
//! ```
//! use sentry_tracing::EventFilter;
//! use tracing_subscriber::prelude::*;
//!
//! #[tokio::main]
//! async fn main() {
//! let _guard = sentry::init(sentry::ClientOptions {
//! // Set this a to lower value in production
//! traces_sample_rate: 1.0,
//! ..sentry::ClientOptions::default()
//! });
//! let sentry_layer = sentry_tracing::layer().event_filter(|md| match md.level() {
//! &tracing::Level::ERROR => EventFilter::Event,
//! _ => EventFilter::Ignore,
//! });
//!
//! tracing_subscriber::registry()
//! .with(tracing_subscriber::fmt::layer())
//! .with(sentry_tracing::layer())
//! .init();
//! tracing_subscriber::registry()
//! .with(tracing_subscriber::fmt::layer())
//! .with(sentry_layer)
//! .init();
//! ```
//!
//! outer().await;
//! }
//! # Logging Messages
//!
//! // Functions instrumented by tracing automatically report
//! // their span as transactions
//! #[tracing::instrument]
//! async fn outer() {
//! tracing::info!("Generates a breadcrumb");
//! Tracing events automatically create breadcrumbs that are attached to the current scope in
//! Sentry. They show up on errors and transactions captured within this scope as shown in the
//! examples below.
//!
//! for _ in 0..10 {
//! inner().await;
//! }
//! Fields passed to the event macro are automatically tracked as structured data in Sentry. For
//! breadcrumbs, they are shown directly with the breadcrumb message. For other types of data, read
//! below.
//!
//! tracing::error!("Generates an event");
//! ```
//! for i in 0..10 {
//! tracing::debug!(number = i, "Generates a breadcrumb");
//! }
//! ```
//!
//! #[tracing::instrument]
//! async fn inner() {
//! // Also works, since log events are ingested by the tracing system
//! log::info!("Generates a breadcrumb");
//! # Tracking Errors
//!
//! sleep(Duration::from_millis(100)).await;
//! The easiest way to emit errors is by logging an event with `ERROR` level. This will create a
//! grouped issue in Sentry. To add custom information, prepend the message with fields. It is also
//! possible to add Sentry tags if a field is prefixed with `"tags."`
//!
//! log::error!("Generates an event");
//! }
//! ```
//! tracing::error!(
//! field = "value", // will become a context field
//! tags.custom = "value", // will become a tag in Sentry
//! "this is an error with a custom tag",
//! );
//! ```
//!
//! Or one might also set an explicit filter, to customize how to treat log
//! records:
//! To track [error structs](std::error::Error), assign a reference to error trait object as field
//! in one of the logging macros. By convention, it is recommended to use the `ERROR` level and
//! assign it to a field called `error`, although the integration will also work with all other
//! levels and field names.
//!
//! All other fields passed to the macro are captured in a custom "Tracing Fields" context in
//! Sentry.
//!
//! ```
//! use std::error::Error;
//! use std::io;
//!
//! let custom_error = io::Error::new(io::ErrorKind::Other, "oh no");
//! tracing::error!(error = &custom_error as &dyn Error);
//! ```
//!
//! It is also possible to combine error messages with error structs. In Sentry, this creates issues
//! grouped by the message and location of the error log, and adds the passed error as nested
//! source.
//!
//! ```
//! use std::error::Error;
//! use std::io;
//!
//! let custom_error = io::Error::new(io::ErrorKind::Other, "oh no");
//! tracing::error!(error = &custom_error as &dyn Error, "my operation failed");
//! ```
//!
//! # Tracing Spans
//!
//! The integration automatically tracks `tracing` spans as spans in Sentry. A convenient way to do
//! this is with the `#[instrument]` attribute macro, which creates a transaction for the function
//! in Sentry.
//!
//! Function arguments are added as context fields automatically, which can be configured through
//! attribute arguments. Refer to documentation of the macro for more information.
//!
//! ```
//! use std::time::Duration;
//!
//! ```rust
//! use sentry_tracing::EventFilter;
//! use tracing_subscriber::prelude::*;
//!
//! let layer = sentry_tracing::layer().event_filter(|md| match md.level() {
//! &tracing::Level::ERROR => EventFilter::Event,
//! _ => EventFilter::Ignore,
//! });
//! // Functions instrumented by tracing automatically report
//! // their span as transactions.
//! #[tracing::instrument]
//! async fn outer() {
//! for i in 0..10 {
//! inner(i).await;
//! }
//! }
//!
//! // This creates spans inside the outer transaction, unless called directly.
//! #[tracing::instrument]
//! async fn inner(i: u32) {
//! // Also works, since log events are ingested by the tracing system
//! tracing::debug!(number = i, "Generates a breadcrumb");
//!
//! tracing_subscriber::registry().with(layer).init();
//! tokio::time::sleep(Duration::from_millis(100)).await;
//! }
//! ```

#![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")]
Expand Down