diff --git a/conduwuit-example.toml b/conduwuit-example.toml index cb6dc8e6bbfef8f011eaa86d026c42136a948ff3..ea095bfa11451c0b5457cb336a86e2488fb13915 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 8b864c846b277a9e4af41675427b2e0368083c06..1997a39ee09b0a8ccbd44da7c85dfc23e70d1a48 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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[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 59f88a0ce351a2c4b70869f980995b2e08de2af6..04ad8654f982da1e564292421420d8327221d35f 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 std::{ + str::FromStr, + sync::{Arc, OnceLock}, +}; -use conduit::{config::Config, trace}; +use conduit::{config::Config, debug, trace}; use sentry::{ - types::{protocol::v7::Event, Dsn}, - Breadcrumb, ClientOptions, + types::{ + protocol::v7::{Context, Event}, + Dsn, + }, + Breadcrumb, ClientOptions, Level, }; +static SEND_PANIC: OnceLock<bool> = OnceLock::new(); +static SEND_ERROR: OnceLock<bool> = OnceLock::new(); + pub(crate) fn init(config: &Config) -> Option<sentry::ClientInitGuard> { 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<Event<'static>> { - 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<Breadcrumb> { - trace!("Adding sentry breadcrumb: {crumb:?}"); + if crumb.ty == "log" && crumb.level == Level::Debug { + return None; + } + + trace!("Sentry breadcrumb: {crumb:?}"); Some(crumb) }