### Basic Actix-Web Server with Sentry Middleware Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-actix/README.md Demonstrates how to initialize Sentry and add the sentry-actix middleware to an actix-web application. This example includes a failing endpoint to trigger error reporting. ```rust use std::io; use actix_web::{get, App, Error, HttpRequest, HttpServer}; #[get("/")] async fn failing(_req: HttpRequest) -> Result { Err(io::Error::new(io::ErrorKind::Other, "An error happens here").into()) } fn main() -> io::Result<()> { let _guard = sentry::init(sentry::ClientOptions { release: sentry::release_name!(), ..Default::default() }); std::env::set_var("RUST_BACKTRACE", "1"); let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() .build()?; runtime.block_on(async move { HttpServer::new(|| { App::new() .wrap(sentry_actix::Sentry::new()) .service(failing) }) .bind("127.0.0.1:3001")? .run() .await }) } ``` -------------------------------- ### Basic SentryLogger Setup with pretty_env_logger Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-log/README.md Initializes the Sentry logger with pretty_env_logger, setting log level filters and capturing info-level logs as breadcrumbs and error-level logs as events. ```rust let mut log_builder = pretty_env_logger::formatted_builder(); log_builder.parse_filters("info"); let logger = sentry_log::SentryLogger::with_dest(log_builder.build()); log::set_boxed_logger(Box::new(logger)).unwrap(); log::set_max_level(log::LevelFilter::Info); let _sentry = sentry::init(()); log::info!("Generates a breadcrumb"); log::error!("Generates an event"); ``` -------------------------------- ### Compose a Tower service with NewSentryLayer Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tower/README.md Use NewSentryLayer to ensure each request gets its own Sentry hub. This is a common setup for Tower services. ```rust use sentry_tower::NewSentryLayer; // Compose a Tower service where each request gets its own Sentry hub let service = ServiceBuilder::new() .layer(NewSentryLayer::::new_from_top()) .timeout(Duration::from_secs(30)) .service(tower::service_fn(|req: Request| format!("hello {}", req))); ``` -------------------------------- ### Default PanicIntegration with Custom Extractor Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-panic/README.md Installs a default panic handler that can be extended with a custom extractor function. The extractor can optionally create a Sentry Event from PanicHookInfo. Panics are forwarded to the previous hook. ```rust let integration = sentry_panic::PanicIntegration::default().add_extractor(|info| None); ``` -------------------------------- ### Initialize Sentry and OpenTelemetry Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-opentelemetry/README.md Initialize the Sentry SDK with tracing enabled and register the SentryPropagator and SentrySpanProcessor for distributed tracing. ```rust 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://your-dsn@sentry.io/0", sentry::ClientOptions { // Enable capturing of traces; set this a to lower value in production. // For more sophisticated behavior use a custom // [`sentry::ClientOptions::traces_sampler`] instead. // That's the equivalent of a tail sampling processor in OpenTelemetry. // These options will only affect sampling of the spans that are sent to Sentry, // not of the underlying OpenTelemetry spans. traces_sample_rate: 1.0, debug: true, ..sentry::ClientOptions::default() }, )); // Register the Sentry propagator to enable 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); ``` -------------------------------- ### Initialize Sentry with Context Integration Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-contexts/README.md Initialize the Sentry SDK with the ContextIntegration, optionally disabling the OS context. This is typically done once at application startup. ```rust let integration = sentry_contexts::ContextIntegration::new().add_os(false); let _sentry = sentry::init(sentry::ClientOptions::new().add_integration(integration)); ``` -------------------------------- ### Basic SentryDrain Usage Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-slog/README.md Demonstrates how to initialize Sentry, create a SentryDrain wrapping a discard drain, and use it with a slog logger. It shows how slog info and warn messages are captured as Sentry breadcrumbs and events respectively, and how KV pairs are mapped. ```rust use sentry_slog::SentryDrain; let _sentry = sentry::init(()); let drain = SentryDrain::new(slog::Discard); let root = slog::Logger::root(drain, slog::o!("global_kv" => 1234)); slog::info!(root, "recorded as breadcrumb"; "breadcrumb_kv" => Some("breadcrumb")); slog::warn!(root, "recorded as regular event"; "event_kv" => "event"); let breadcrumb = &captured_event.breadcrumbs.as_ref()[0]; assert_eq!( breadcrumb.message.as_deref(), Some("recorded as breadcrumb") ); assert_eq!(breadcrumb.data["breadcrumb_kv"], "breadcrumb"); assert_eq!(breadcrumb.data["global_kv"], 1234); assert_eq!( captured_event.message.as_deref(), Some("recorded as regular event") ); assert_eq!(captured_event.extra["event_kv"], "event"); assert_eq!(captured_event.extra["global_kv"], 1234); slog::crit!(root, "recorded as exception event"); assert_eq!( captured_event.message.as_deref(), Some("recorded as exception event") ); ``` -------------------------------- ### Initialize Sentry and Tracing Layer Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Configure Sentry with a traces sample rate and add the Sentry tracing layer to your tracing subscriber to capture events, breadcrumbs, and spans. ```rust 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::integrations::tracing::layer()) .init(); ``` -------------------------------- ### Parallel Multithreaded and Concurrent Futures Hub Management Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-core/README.md Demonstrates how to manage Hub instances for parallel multithreaded and concurrent futures code. A new Hub should be created and bound for each concurrent computation to avoid unexpected results or panics. ```rust use rayon::prelude::* use sentry::{Hub, SentryFutureExt} use std::sync::Arc // Parallel multithreaded code: let outer_hub = Hub::current(); let results: Vec<_> = [1_u32, 2, 3] .into_par_iter() .map(|num| { let thread_hub = Arc::new(Hub::new_from_top(&outer_hub)); Hub::run(thread_hub, || num * num) }) .collect(); assert_eq!(&results, &[1, 4, 9]); // Concurrent futures code: let futures = [1_u32, 2, 3] .into_iter() .map(|num| async move { num * num }.bind_hub(Hub::new_from_top(Hub::current()))); let results = futures::future::join_all(futures).await; assert_eq!(&results, &[1, 4, 9]); ``` -------------------------------- ### Create a Sentry Event with Default Values Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-types/README.md Demonstrates how to create a v7 Sentry Event using `Default::default()` to initialize missing fields. This is useful for setting up basic event structures. ```rust use sentry_types::protocol::v7; let event = v7::Event { message: Some("Hello World!".to_string()), culprit: Some("foo in bar".to_string()), level: v7::Level::Info, ..Default::default() }; ``` -------------------------------- ### Initialize Sentry and Capture Message Source: https://github.com/getsentry/sentry-rust/blob/master/sentry/README.md Initializes the Sentry client with a DSN and captures an informational message. The returned guard must be kept alive to ensure events are sent. ```rust let _guard = sentry::init("https://key@sentry.io/42"); sentry::capture_message("Hello World!", sentry::Level::Info); // when the guard goes out of scope here, the client will wait up to two // seconds to send remaining events to the service. ``` -------------------------------- ### Configure Sentry for Release Health with Request Sessions Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-actix/README.md Initializes Sentry with options for release health tracking, enabling automatic session tracking per request. ```rust let _sentry = sentry::init(sentry::ClientOptions { release: sentry::release_name!(), session_mode: sentry::SessionMode::Request, auto_session_tracking: true, ..Default::default() }); ``` -------------------------------- ### Configure Sentry Tracing Layer with Event Filters Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Set up a Sentry tracing subscriber layer to control which events and spans are sent to Sentry based on their log level. ```rust use sentry::integrations::tracing::EventFilter; use tracing_subscriber::prelude::*; let sentry_layer = sentry::integrations::tracing::layer() .event_filter(|md| match *md.level() { tracing::Level::ERROR => EventFilter::Event | EventFilter::Log, tracing::Level::TRACE => EventFilter::Ignore, _ => EventFilter::Log, }) .span_filter(|md| matches!(*md.level(), tracing::Level::ERROR | tracing::Level::WARN)); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer()) .with(sentry_layer) .init(); ``` -------------------------------- ### Add Dependencies to Cargo.toml Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-opentelemetry/README.md Include the necessary OpenTelemetry and Sentry SDK dependencies with the opentelemetry feature enabled for Sentry. ```toml [dependencies] opentelemetry = { version = "0.29.1", features = ["trace"] } opentelemetry_sdk = { version = "0.29.0", features = ["trace"] } sentry = { version = "0.38.0", features = ["opentelemetry"] } ``` -------------------------------- ### Configure DebugImagesIntegration with a Filter Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-debug-images/README.md Instantiates the `DebugImagesIntegration` and applies a filter to only include events with a level of Warning or higher. ```rust use sentry_core::Level; let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -------------------------------- ### Instrument Async Functions for Sentry Spans Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Use the `#[tracing::instrument]` macro to automatically create Sentry spans/transactions for async functions. Function arguments are captured as context fields. ```rust use std::time::Duration; use tracing_subscriber::prelude::*; // Functions instrumented by tracing automatically // create spans/transactions around their execution. #[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"); tokio::time::sleep(Duration::from_millis(100)).await; } ``` -------------------------------- ### Compose a Tower service with a closure-based Hub Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tower/README.md Use SentryLayer with a closure to dynamically select a Sentry hub based on the incoming request. This provides flexibility in hub assignment. ```rust use sentry::Hub; use sentry_tower::SentryLayer; // Compose a Tower service let hello = Arc::new(Hub::with(|hub| Hub::new_from_top(hub))); let other = Arc::new(Hub::with(|hub| Hub::new_from_top(hub))); let service = ServiceBuilder::new() .layer(SentryLayer::new(|req: &Request| match req.as_str() { "hello" => hello.clone(), _ => other.clone(), })) .timeout(Duration::from_secs(30)) .service(tower::service_fn(|req: Request| format!("{} world", req))); ``` -------------------------------- ### Compose a Tower service with a specific Hub Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tower/README.md Use SentryLayer to compose a Tower service with a pre-created hub dedicated to web requests. This allows for more control over hub management. ```rust use sentry::Hub; use sentry_tower::SentryLayer; // Create a hub dedicated to web requests let hub = Arc::new(Hub::with(|hub| Hub::new_from_top(hub))); // Compose a Tower service let service = ServiceBuilder::new() .layer(SentryLayer::<_, _, Request>::new(hub)) .timeout(Duration::from_secs(30)) .service(tower::service_fn(|req: Request| format!("hello {}", req))); ``` -------------------------------- ### Hub Management for Non-Concurrent Tasks Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-core/README.md Illustrates how to bind the current Hub for tasks that are not concurrent and do not outlive the current execution context. This is suitable for spawned threads that are joined or futures that are awaited. ```rust use sentry::{Hub, SentryFutureExt} // Spawned thread that is being joined: let hub = Hub::current(); let result = std::thread::spawn(|| Hub::run(hub, || 1_u32)).join(); assert_eq!(result.unwrap(), 1); // Spawned future that is being awaited: let result = tokio::spawn(async { 1_u32 }.bind_hub(Hub::current())).await; assert_eq!(result.unwrap(), 1); ``` -------------------------------- ### Integrate NewSentryLayer with Tonic server Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tower/README.md Directly use NewSentryLayer within a Tonic server's builder for automatic Sentry hub binding per request. This simplifies Sentry integration in gRPC services. ```rust use hello_world::{greeter_server::*}; use sentry_tower::NewSentryLayer; struct GreeterService; #[tonic::async_trait] impl Greeter for GreeterService { async fn say_hello( &self, req: Request, ) -> Result, Status> { let HelloRequest { name } = req.into_inner(); if name == "world" { capture_anyhow(&anyhow!("Trying to greet a planet")); return Err(Status::invalid_argument("Cannot greet a planet")); } Ok(Response::new(HelloReply { message: format!("Hello {}", name), })) } } Server::builder() .layer(NewSentryLayer::new_from_top()) .add_service(GreeterServer::new(GreeterService)) .serve("127.0.0.1:50051".parse().unwrap()) .await?; ``` -------------------------------- ### Capture Tracing Events as Structured Logs Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md With the `logs` feature enabled and `enable_logs: true` in `sentry::init`, tracing events can be captured as structured logs in Sentry. Fields are captured as attributes, and logs can be queried in the Logs explorer. ```rust // assuming `tracing::Level::INFO => EventFilter::Log` in your `event_filter` for i in 0..10 { tracing::info!(number = i, my.key = "val", my.num = 42, "This is a log"); } ``` -------------------------------- ### Combine Sentry Hub and HTTP layers with Axum router Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tower/README.md When using Axum, reorder Sentry layers to apply the Http layer before the Hub layer, as Axum applies middleware in the opposite order of tower::ServiceBuilder. Incorrect ordering can lead to memory leaks. ```rust let app = Router::new() .route("/", get(handler)) .layer(sentry_tower::SentryHttpLayer::new().enable_transaction()) .layer(sentry_tower::NewSentryLayer::::new_from_top()); ``` -------------------------------- ### Combined Log Filters for Multiple Sentry Items Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-log/README.md Sets up a Sentry logger that maps log records to multiple Sentry items. Errors are captured as events, warnings as both breadcrumbs and logs, and other levels are ignored. ```rust use sentry_log::LogFilter; let logger = sentry_log::SentryLogger::new().filter(|md| match md.level() { log::Level::Error => LogFilter::Event, log::Level::Warn => LogFilter::Breadcrumb | LogFilter::Log, _ => LogFilter::Ignore, }); ``` -------------------------------- ### Custom SentryDrain with Filter and Mapper Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-slog/README.md Shows how to customize the SentryDrain with a filter to control which log levels are sent to Sentry and a mapper to transform slog records into Sentry events. A filter and mapper should be provided together. ```rust use sentry_slog::{exception_from_record, LevelFilter, RecordMapping, SentryDrain}; let drain = SentryDrain::new(slog::Discard) .filter(|level| match level { slog::Level::Critical | slog::Level::Error => LevelFilter::Event, _ => LevelFilter::Ignore, }) .mapper(|record, kv| match record.level() { slog::Level::Critical | slog::Level::Error => { RecordMapping::Event(exception_from_record(record, kv)) } _ => RecordMapping::Ignore, }); ``` -------------------------------- ### Custom Record Mapper for Multiple Sentry Items Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-log/README.md Implements a custom mapper for the Sentry logger to send multiple Sentry items from a single log record. Errors are sent as both events and breadcrumbs, warnings as breadcrumbs, and others are ignored. ```rust use sentry_log::{RecordMapping, SentryLogger, event_from_record, breadcrumb_from_record}; let logger = SentryLogger::new().mapper(|record| { match record.level() { log::Level::Error => { // Send both an event and a breadcrumb for errors vec![ RecordMapping::Event(event_from_record(record)), RecordMapping::Breadcrumb(breadcrumb_from_record(record)), ] } log::Level::Warn => RecordMapping::Breadcrumb(breadcrumb_from_record(record)).into(), _ => RecordMapping::Ignore.into(), } }); ``` -------------------------------- ### Log an Error with Custom Fields and Tags Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Emit an error event with custom context fields and Sentry tags. Fields prefixed with 'tags.' become Sentry tags. ```rust 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", ); ``` -------------------------------- ### Create OpenTelemetry Spans and Capture Events Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-opentelemetry/README.md Use the OpenTelemetry API to create spans and capture messages. Span attributes are sent as data attributes to Sentry, and captured messages are associated with the current span. ```rust 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); }); }); ``` -------------------------------- ### Combine Sentry Hub and HTTP layers with ServiceBuilder Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tower/README.md When combining Sentry Hub and Sentry HTTP layers with tower::ServiceBuilder, define the Hub layer before the Http one to ensure correct ordering and prevent memory leaks. ```rust let layer = tower::ServiceBuilder::new() .layer(sentry_tower::NewSentryLayer::::new_from_top()) .layer(sentry_tower::SentryHttpLayer::new().enable_transaction()); ``` -------------------------------- ### Generate Breadcrumbs from Tracing Events Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Tracing events with debug level automatically create breadcrumbs attached to the current Sentry scope. Fields passed to the event macro are tracked as structured data. ```rust for i in 0..10 { tracing::debug!(number = i, "Generates a breadcrumb"); } ``` -------------------------------- ### Capture Message in Actix Handler Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-actix/README.md Shows how to capture a warning message within an actix handler using the current request's Hub. This assumes the Sentry middleware has been applied. ```rust sentry::capture_message("Something is not well", sentry::Level::Warning); ``` -------------------------------- ### Combine Error Messages with Error Structs Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Log an error that includes both a descriptive message and a captured error struct. Sentry groups issues by message and location, adding the error as a nested source. ```rust 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"); ``` -------------------------------- ### Capture anyhow::Error with sentry-anyhow Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-anyhow/README.md Use capture_anyhow to send an anyhow::Error to Sentry. This function is available when the 'anyhow' cargo feature is enabled. ```rust use sentry_anyhow::capture_anyhow; fn function_that_might_fail() -> anyhow::Result<()> { Err(anyhow::anyhow!("some kind of error")) } if let Err(err) = function_that_might_fail() { capture_anyhow(&err); } ``` -------------------------------- ### Customize Span Name and Operation with Special Fields Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Override the default span name and operation sent to Sentry using the `sentry.name` and `sentry.op` fields within the `#[tracing::instrument]` macro. ```rust #[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) { // ... } ``` -------------------------------- ### Custom Event and Span Filtering Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Customize which tracing events and spans are captured by Sentry using explicit filters. The event filter determines if an event becomes a Sentry event or is ignored, while the span filter controls span capture. ```rust use sentry::integrations::tracing::EventFilter; use tracing_subscriber::prelude::*; let sentry_layer = sentry::integrations::tracing::layer() .event_filter(|md| match *md.level() { tracing::Level::ERROR => EventFilter::Event, _ => EventFilter::Ignore, }) .span_filter(|md| matches!(*md.level(), tracing::Level::ERROR | tracing::Level::WARN)); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer()) .with(sentry_layer) .init(); ``` -------------------------------- ### Custom SentryLogger Filter Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-log/README.md Configures the Sentry logger to capture only error-level logs as Sentry events, ignoring all other log levels. ```rust use sentry_log::LogFilter; let logger = sentry_log::SentryLogger::new().filter(|md| match md.level() { log::Level::Error => LogFilter::Event, _ => LogFilter::Ignore, }); ``` -------------------------------- ### Track Rust Error Structs Source: https://github.com/getsentry/sentry-rust/blob/master/sentry-tracing/README.md Capture Rust standard library error structs as Sentry issues. Assign a reference to an error trait object to the 'error' field. ```rust 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); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.