diff --git a/conduwuit-example.toml b/conduwuit-example.toml index cb6dc8e6..ea095bfa 100644 --- a/conduwuit-example.toml +++ b/conduwuit-example.toml @@ -60,6 +60,13 @@ # Whether to attach a stacktrace to Sentry reports. #sentry_attach_stacktrace = false +# Send panics to sentry. This is true by default, but sentry has to be enabled. +#sentry_send_panic = true + +# Send errors to sentry. This is true by default, but sentry has to be enabled. This option is +# only effective in release-mode; forced to false in debug-mode. +#sentry_send_error = true + ### Database configuration diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 8b864c84..1997a39e 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -358,6 +358,10 @@ pub struct Config { pub sentry_traces_sample_rate: f32, #[serde(default)] pub sentry_attach_stacktrace: bool, + #[serde(default = "true_fn")] + pub sentry_send_panic: bool, + #[serde(default = "true_fn")] + pub sentry_send_error: bool, #[serde(default)] pub tokio_console: bool, @@ -822,6 +826,8 @@ impl fmt::Display for Config { #[cfg(feature = "sentry_telemetry")] ("Sentry.io tracing sample rate", &self.sentry_traces_sample_rate.to_string()), ("Sentry.io attach stacktrace", &self.sentry_attach_stacktrace.to_string()), + ("Sentry.io send panics", &self.sentry_send_panic.to_string()), + ("Sentry.io send errors", &self.sentry_send_error.to_string()), ( "Well-known server name", self.well_known diff --git a/src/main/sentry.rs b/src/main/sentry.rs index 59f88a0c..04ad8654 100644 --- a/src/main/sentry.rs +++ b/src/main/sentry.rs @@ -1,18 +1,34 @@ #![cfg(feature = "sentry_telemetry")] -use std::{str::FromStr, sync::Arc}; - -use conduit::{config::Config, trace}; -use sentry::{ - types::{protocol::v7::Event, Dsn}, - Breadcrumb, ClientOptions, +use std::{ + str::FromStr, + sync::{Arc, OnceLock}, }; +use conduit::{config::Config, debug, trace}; +use sentry::{ + types::{ + protocol::v7::{Context, Event}, + Dsn, + }, + Breadcrumb, ClientOptions, Level, +}; + +static SEND_PANIC: OnceLock = OnceLock::new(); +static SEND_ERROR: OnceLock = OnceLock::new(); + pub(crate) fn init(config: &Config) -> Option { config.sentry.then(|| sentry::init(options(config))) } fn options(config: &Config) -> ClientOptions { + SEND_PANIC + .set(config.sentry_send_panic) + .expect("SEND_PANIC was not previously set"); + SEND_ERROR + .set(config.sentry_send_error) + .expect("SEND_ERROR was not previously set"); + let dsn = config .sentry_endpoint .as_ref() @@ -36,11 +52,40 @@ fn options(config: &Config) -> ClientOptions { } fn before_send(event: Event<'static>) -> Option> { - trace!("Sending sentry event: {event:?}"); + if event.exception.iter().any(|e| e.ty == "panic") && !SEND_PANIC.get().unwrap_or(&true) { + return None; + } + + if event.level == Level::Error { + if !SEND_ERROR.get().unwrap_or(&true) { + return None; + } + + if cfg!(debug_assertions) { + return None; + } + + //NOTE: we can enable this to specify error!(sentry = true, ...) + if let Some(Context::Other(context)) = event.contexts.get("Rust Tracing Fields") { + if !context.contains_key("sentry") { + //return None; + } + } + } + + if event.level == Level::Fatal { + trace!("{event:#?}"); + } + + debug!("Sending sentry event: {event:?}"); Some(event) } fn before_breadcrumb(crumb: Breadcrumb) -> Option { - trace!("Adding sentry breadcrumb: {crumb:?}"); + if crumb.ty == "log" && crumb.level == Level::Debug { + return None; + } + + trace!("Sentry breadcrumb: {crumb:?}"); Some(crumb) }