diff --git a/.github/workflows/desktop_cd.yaml b/.github/workflows/desktop_cd.yaml index 31053490bfe..0a1acc03bf5 100644 --- a/.github/workflows/desktop_cd.yaml +++ b/.github/workflows/desktop_cd.yaml @@ -212,6 +212,7 @@ jobs: env: APP_VERSION: ${{ needs.compute-version.outputs.version }} ANARLOG_GPUI_SIDECAR: optional + SENTRY_DSN: ${{ secrets.SENTRY_DSN_HYPRNOTE_2 }} - uses: ./.github/actions/apple_cert id: apple-cert with: @@ -451,6 +452,7 @@ jobs: env: APP_VERSION: ${{ needs.compute-version.outputs.version }} ANARLOG_GPUI_SIDECAR: "1" + SENTRY_DSN: ${{ secrets.SENTRY_DSN_HYPRNOTE_2 }} TAURI_ENV_TARGET_TRIPLE: ${{ matrix.target }} - run: | BUILD_ARGS=( diff --git a/Cargo.lock b/Cargo.lock index c021cbd3fc5..2cab96ecf0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4499,6 +4499,19 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "crash-reporting" +version = "0.1.0" +dependencies = [ + "dirs 6.0.0", + "regex", + "sentry", + "serde_json", + "tracing", + "tracing-subscriber", + "user-error", +] + [[package]] name = "crc" version = "3.4.0" @@ -5380,6 +5393,7 @@ dependencies = [ "audio-actual", "audio-mock", "chrono", + "crash-reporting", "db-app", "db-core", "db-sync", @@ -5389,7 +5403,6 @@ dependencies = [ "pico-args", "ractor", "search-index", - "sentry", "serde", "serde_json", "specta", @@ -5485,6 +5498,7 @@ dependencies = [ "base64 0.22.1", "chrono", "chrono-tz 0.10.4", + "crash-reporting", "db-app", "db-core", "deeplink-core", @@ -19932,8 +19946,8 @@ dependencies = [ name = "tauri-plugin-tracing" version = "0.1.0" dependencies = [ + "crash-reporting", "dirs 6.0.0", - "regex", "rquickjs 0.10.0", "sentry", "serde", @@ -19942,14 +19956,12 @@ dependencies = [ "specta-typescript", "tauri", "tauri-plugin", - "tauri-plugin-sentry", "tauri-specta", "tempfile", "thiserror 2.0.18", "tracing", "tracing-appender", "tracing-subscriber", - "user-error", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4c0c4fc4d15..45819397781 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,6 +66,7 @@ anlg-claude = { path = "crates/claude", package = "claude" } anlg-cli-process = { path = "crates/cli-process", package = "cli-process" } anlg-cloudsync = { path = "crates/cloudsync", package = "cloudsync" } anlg-codex = { path = "crates/codex", package = "codex" } +anlg-crash-reporting = { path = "crates/crash-reporting", package = "crash-reporting" } anlg-data = { path = "crates/data", package = "data" } anlg-db-app = { path = "crates/db-app", package = "db-app" } anlg-db-change = { path = "crates/db-change", package = "db-change" } diff --git a/apps/desktop-gpui/Cargo.toml b/apps/desktop-gpui/Cargo.toml index 0560dea4879..a572da5a06c 100644 --- a/apps/desktop-gpui/Cargo.toml +++ b/apps/desktop-gpui/Cargo.toml @@ -14,6 +14,7 @@ anlg-agent-access = { workspace = true } anlg-audio = { workspace = true } anlg-audio-actual = { workspace = true } anlg-audio-mock = { workspace = true } +anlg-crash-reporting = { workspace = true } anlg-db-app = { workspace = true } anlg-db-core = { workspace = true } anlg-deeplink-core = { workspace = true } diff --git a/apps/desktop-gpui/src/main.rs b/apps/desktop-gpui/src/main.rs index dfc724d6c26..9a388b08715 100644 --- a/apps/desktop-gpui/src/main.rs +++ b/apps/desktop-gpui/src/main.rs @@ -86,6 +86,7 @@ pub const APP_VERSION: &str = match option_env!("APP_VERSION") { use std::path::PathBuf; use std::sync::Arc; +use anlg_crash_reporting::{Options as CrashReportingOptions, consent::CONSENT_QUERY}; use anyhow::Context as _; use gpui::{ App, AppContext as _, Application, Bounds, TitlebarOptions, WindowBounds, WindowDecorations, @@ -94,6 +95,7 @@ use gpui::{ use crate::db::Store; use crate::workspace::Workspace; +use tracing_subscriber::prelude::*; /// The main window the tray menu acts on. struct MainWindow { @@ -367,13 +369,16 @@ fn parse_args() -> anyhow::Result { } fn main() -> anyhow::Result<()> { - tracing_subscriber::fmt() - .with_env_filter( + tracing_subscriber::registry() + .with( tracing_subscriber::EnvFilter::try_from_default_env() .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")), ) + .with(anlg_crash_reporting::tracing_layer()) + .with(tracing_subscriber::fmt::layer().with_writer(|| { + anlg_crash_reporting::redaction::RedactingWriter::new(std::io::stderr()) + })) .init(); - let args = parse_args()?; let db_path = match args.db_path { Some(path) => path, @@ -415,6 +420,22 @@ fn main() -> anyhow::Result<()> { db_path, args.identifier.clone(), ))?; + let crash_reporting_enabled = runtime.block_on(async { + let rows = sqlx::query_as::<_, (String, String)>(CONSENT_QUERY) + .fetch_all(store.pool()) + .await + .unwrap_or_default(); + anlg_crash_reporting::consent::from_rows(&rows) + }); + let _sentry = anlg_crash_reporting::init( + CrashReportingOptions { + dsn: option_env!("SENTRY_DSN"), + release: Some(format!("anarlog-desktop-gpui@{APP_VERSION}")), + release_channel: option_env!("RELEASE_CHANNEL").unwrap_or("dev"), + service_name: "desktop-gpui", + }, + crash_reporting_enabled, + ); let audio = audio::provider(&args.identifier); let store = Arc::new(store); let search = search::SearchIndex::start(&store); diff --git a/apps/desktop-gpui/src/workspace/settings.rs b/apps/desktop-gpui/src/workspace/settings.rs index e4162296bca..9fd9e1f4dd1 100644 --- a/apps/desktop-gpui/src/workspace/settings.rs +++ b/apps/desktop-gpui/src/workspace/settings.rs @@ -724,6 +724,9 @@ impl Workspace { value: bool, cx: &mut Context, ) { + if key == "crash_reporting_consent" { + anlg_crash_reporting::set_enabled(value); + } self.set_setting(key, serde_json::Value::Bool(value), cx); } diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index 5e8b41ca693..65f18790108 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -20,6 +20,7 @@ crate-type = ["staticlib", "rlib"] tauri-build = { workspace = true, features = [] } [dependencies] +anlg-crash-reporting = { workspace = true } tauri = { workspace = true, features = ["specta", "protocol-asset"] } tauri-plugin-agent = { workspace = true } @@ -101,7 +102,6 @@ chrono = { workspace = true } dirs = { workspace = true } pico-args = { workspace = true } ractor = { workspace = true } -sentry = { workspace = true, features = ["tracing"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } specta = { workspace = true } diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs index 6e6f72f9e9b..1f5ed137465 100644 --- a/apps/desktop/src-tauri/src/lib.rs +++ b/apps/desktop/src-tauri/src/lib.rs @@ -15,6 +15,7 @@ use db::{cloudsync_runtime_config_from_env, open_desktop_db}; use ext::*; use store::*; +use anlg_crash_reporting::{Options as CrashReportingOptions, consent::CONSENT_QUERY}; use std::sync::{ Arc, atomic::{AtomicBool, Ordering}, @@ -30,7 +31,6 @@ const STAGING_BUNDLE_ID: &str = "com.hyprnote.staging"; const APP_EXIT_REQUESTED_EVENT: &str = "app-exit-requested"; static EXIT_FLUSH_COMPLETE: AtomicBool = AtomicBool::new(false); static EXIT_FLUSH_REQUESTED: AtomicBool = AtomicBool::new(false); -static CRASH_REPORTING_ENABLED: AtomicBool = AtomicBool::new(false); const EXIT_FLUSH_FALLBACK_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10); const EXIT_HARD_FALLBACK_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(12); @@ -38,12 +38,12 @@ pub(crate) struct CrashReportingState; impl CrashReportingState { fn new(enabled: bool) -> Self { - CRASH_REPORTING_ENABLED.store(enabled, Ordering::SeqCst); + anlg_crash_reporting::set_enabled(enabled); Self } fn set_enabled(&self, enabled: bool) { - CRASH_REPORTING_ENABLED.store(enabled, Ordering::SeqCst); + anlg_crash_reporting::set_enabled(enabled); } } @@ -52,27 +52,12 @@ fn run_crash_reporter_process() -> ! { } async fn load_crash_reporting_consent(db: &anlg_db_core::Db) -> bool { - let rows = sqlx::query_as::<_, (String, String)>( - "SELECT id, value_json FROM app_settings \ - WHERE id IN ('crash_reporting_consent', 'telemetry_consent')", - ) - .fetch_all(db.pool()) - .await - .unwrap_or_default(); - - crash_reporting_consent_from_rows(&rows) -} - -fn crash_reporting_consent_from_rows(rows: &[(String, String)]) -> bool { - let read = |id: &str| { - rows.iter() - .find(|(key, _)| key == id) - .and_then(|(_, value)| serde_json::from_str::(value).ok()) - }; + let rows = sqlx::query_as::<_, (String, String)>(CONSENT_QUERY) + .fetch_all(db.pool()) + .await + .unwrap_or_default(); - read("crash_reporting_consent") - .or_else(|| read("telemetry_consent")) - .unwrap_or(false) + anlg_crash_reporting::consent::from_rows(&rows) } fn mark_exit_flush_complete() { @@ -184,52 +169,15 @@ pub fn main() { ) }); - let sentry_client = { - let dsn = if std::env::var_os("ANARLOG_DISABLE_SENTRY").is_some() { - None - } else { - option_env!("SENTRY_DSN") - }; - - if let Some(dsn) = dsn { - let release = - option_env!("APP_VERSION").map(|v| format!("anarlog-desktop@{}", v).into()); - - let client = sentry::init(( - dsn, - sentry::ClientOptions { - release, - traces_sample_rate: 1.0, - auto_session_tracking: false, - before_send: Some(Arc::new(|event| { - CRASH_REPORTING_ENABLED - .load(Ordering::SeqCst) - .then(|| tauri_plugin_tracing::redaction::sanitize_sentry_event(event)) - .flatten() - })), - before_breadcrumb: Some(Arc::new(|breadcrumb| { - CRASH_REPORTING_ENABLED - .load(Ordering::SeqCst) - .then_some(breadcrumb) - })), - ..Default::default() - }, - )); - - sentry::configure_scope(|scope| { - scope.set_tag("service.namespace", "anarlog"); - scope.set_tag("service.name", "desktop"); - scope.set_tag( - "release_channel", - option_env!("RELEASE_CHANNEL").unwrap_or("dev"), - ); - }); - - Some(client) - } else { - None - } - }; + let sentry_client = anlg_crash_reporting::init( + CrashReportingOptions { + dsn: option_env!("SENTRY_DSN"), + release: option_env!("APP_VERSION").map(|v| format!("anarlog-desktop@{v}")), + release_channel: option_env!("RELEASE_CHANNEL").unwrap_or("dev"), + service_name: "desktop", + }, + crash_reporting_enabled, + ); let crash_reporting_state = CrashReportingState::new(crash_reporting_enabled); let audio: std::sync::Arc = @@ -750,9 +698,9 @@ mod test { ("crash_reporting_consent".to_string(), "true".to_string()), ]; - assert!(crash_reporting_consent_from_rows(&rows)); - assert!(!crash_reporting_consent_from_rows(&rows[..1])); - assert!(!crash_reporting_consent_from_rows(&[])); + assert!(anlg_crash_reporting::consent::from_rows(&rows)); + assert!(!anlg_crash_reporting::consent::from_rows(&rows[..1])); + assert!(!anlg_crash_reporting::consent::from_rows(&[])); } #[test] diff --git a/crates/crash-reporting/Cargo.toml b/crates/crash-reporting/Cargo.toml new file mode 100644 index 00000000000..8fbec55998f --- /dev/null +++ b/crates/crash-reporting/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "crash-reporting" +version = "0.1.0" +edition = "2024" +publish = false + +[dependencies] +anlg-user-error = { workspace = true } +dirs = { workspace = true } +regex = { workspace = true } +sentry = { workspace = true, features = ["tracing"] } +serde_json = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } diff --git a/crates/crash-reporting/src/consent.rs b/crates/crash-reporting/src/consent.rs new file mode 100644 index 00000000000..d72fb85c87e --- /dev/null +++ b/crates/crash-reporting/src/consent.rs @@ -0,0 +1,33 @@ +use serde_json::from_str; + +pub const CONSENT_QUERY: &str = "SELECT id, value_json FROM app_settings \ + WHERE id IN ('crash_reporting_consent', 'telemetry_consent')"; + +pub fn from_rows(rows: &[(String, String)]) -> bool { + let read = |id: &str| { + rows.iter() + .find(|(key, _)| key == id) + .and_then(|(_, value)| from_str::(value).ok()) + }; + + read("crash_reporting_consent") + .or_else(|| read("telemetry_consent")) + .unwrap_or(false) +} + +#[cfg(test)] +mod tests { + use super::from_rows; + + #[test] + fn prefers_crash_reporting_consent_over_legacy_telemetry() { + let rows = vec![ + ("telemetry_consent".to_string(), "false".to_string()), + ("crash_reporting_consent".to_string(), "true".to_string()), + ]; + + assert!(from_rows(&rows)); + assert!(!from_rows(&rows[..1])); + assert!(!from_rows(&[])); + } +} diff --git a/crates/crash-reporting/src/filter.rs b/crates/crash-reporting/src/filter.rs new file mode 100644 index 00000000000..7c518951352 --- /dev/null +++ b/crates/crash-reporting/src/filter.rs @@ -0,0 +1,50 @@ +use sentry::integrations::tracing::EventFilter; + +pub const WEBVIEW_CONSOLE_TARGET: &str = "anarlog.webview.console"; + +pub fn is_webview_console_target(target: &str) -> bool { + target == WEBVIEW_CONSOLE_TARGET + || target == "hyprnote.webview.console" + || target.starts_with("tauri_plugin_tracing") +} + +pub fn sentry_event_filter_for(level: &tracing::Level, target: &str) -> EventFilter { + if is_webview_console_target(target) { + return EventFilter::Ignore; + } + + match *level { + tracing::Level::ERROR => EventFilter::Event, + tracing::Level::WARN | tracing::Level::INFO => EventFilter::Breadcrumb, + tracing::Level::DEBUG | tracing::Level::TRACE => EventFilter::Ignore, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sentry_filter_keeps_only_native_errors_as_events() { + assert_eq!( + sentry_event_filter_for(&tracing::Level::ERROR, "native").bits(), + EventFilter::Event.bits() + ); + assert_eq!( + sentry_event_filter_for(&tracing::Level::WARN, "native").bits(), + EventFilter::Breadcrumb.bits() + ); + assert_eq!( + sentry_event_filter_for(&tracing::Level::ERROR, WEBVIEW_CONSOLE_TARGET).bits(), + EventFilter::Ignore.bits() + ); + assert_eq!( + sentry_event_filter_for(&tracing::Level::ERROR, "tauri_plugin_tracing::ext").bits(), + EventFilter::Ignore.bits() + ); + assert_eq!( + sentry_event_filter_for(&tracing::Level::ERROR, "hyprnote.webview.console").bits(), + EventFilter::Ignore.bits() + ); + } +} diff --git a/crates/crash-reporting/src/lib.rs b/crates/crash-reporting/src/lib.rs new file mode 100644 index 00000000000..4b2738fb419 --- /dev/null +++ b/crates/crash-reporting/src/lib.rs @@ -0,0 +1,123 @@ +pub mod consent; +pub mod filter; +pub mod redaction; + +use std::sync::atomic::{AtomicBool, Ordering}; + +use sentry::integrations::tracing::SentryLayer; +use tracing::Subscriber; +use tracing_subscriber::registry::LookupSpan; + +static ENABLED: AtomicBool = AtomicBool::new(false); + +pub struct Options<'a> { + pub dsn: Option<&'a str>, + pub release: Option, + pub release_channel: &'a str, + pub service_name: &'a str, +} + +pub fn enabled() -> bool { + ENABLED.load(Ordering::SeqCst) +} + +pub fn set_enabled(value: bool) { + ENABLED.store(value, Ordering::SeqCst); +} + +pub fn init(options: Options<'_>, initially_enabled: bool) -> Option { + set_enabled(initially_enabled); + let dsn = options + .dsn + .filter(|_| std::env::var_os("ANARLOG_DISABLE_SENTRY").is_none())?; + let service_name = options.service_name; + let release_channel = options.release_channel; + let client = sentry::init(( + dsn, + sentry::ClientOptions { + release: options.release.map(Into::into), + traces_sample_rate: 1.0, + auto_session_tracking: false, + before_send: Some(std::sync::Arc::new(|event| { + enabled() + .then(|| redaction::sanitize_sentry_event(event)) + .flatten() + })), + before_breadcrumb: Some(std::sync::Arc::new(|breadcrumb| { + enabled().then_some(breadcrumb) + })), + ..Default::default() + }, + )); + + sentry::configure_scope(|scope| { + scope.set_tag("service.namespace", "anarlog"); + scope.set_tag("service.name", service_name); + scope.set_tag("release_channel", release_channel); + }); + + Some(client) +} + +pub fn tracing_layer() -> SentryLayer +where + S: Subscriber + for<'a> LookupSpan<'a>, +{ + sentry::integrations::tracing::layer().event_filter(|metadata| { + filter::sentry_event_filter_for(metadata.level(), metadata.target()) + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::{Mutex, OnceLock}; + + static STATE_LOCK: OnceLock> = OnceLock::new(); + + #[test] + fn init_without_dsn_returns_none() { + let _lock = STATE_LOCK.get_or_init(|| Mutex::new(())).lock().unwrap(); + assert!( + init( + Options { + dsn: None, + release: None, + release_channel: "dev", + service_name: "test", + }, + true, + ) + .is_none() + ); + } + + #[test] + fn init_disabled_by_environment_returns_none() { + let _lock = STATE_LOCK.get_or_init(|| Mutex::new(())).lock().unwrap(); + if std::env::var_os("ANARLOG_DISABLE_SENTRY").is_none() { + unsafe { std::env::set_var("ANARLOG_DISABLE_SENTRY", "1") }; + let result = init( + Options { + dsn: Some("https://public@example.com/1"), + release: None, + release_channel: "dev", + service_name: "test", + }, + true, + ); + unsafe { std::env::remove_var("ANARLOG_DISABLE_SENTRY") }; + assert!(result.is_none()); + } + } + + #[test] + fn enabled_round_trip() { + let _lock = STATE_LOCK.get_or_init(|| Mutex::new(())).lock().unwrap(); + set_enabled(false); + assert!(!enabled()); + set_enabled(true); + assert!(enabled()); + set_enabled(false); + } +} diff --git a/plugins/tracing/src/redaction.rs b/crates/crash-reporting/src/redaction.rs similarity index 100% rename from plugins/tracing/src/redaction.rs rename to crates/crash-reporting/src/redaction.rs diff --git a/plugins/tracing/Cargo.toml b/plugins/tracing/Cargo.toml index 0a7abe5533c..d6c8d2a0867 100644 --- a/plugins/tracing/Cargo.toml +++ b/plugins/tracing/Cargo.toml @@ -13,6 +13,7 @@ tauri-plugin = { workspace = true, features = ["build"] } [dev-dependencies] dirs = { workspace = true } rquickjs = "0.10" +sentry = { workspace = true, features = ["tracing"] } specta-typescript = { workspace = true } tauri = { workspace = true, features = ["test"] } tempfile = { workspace = true } @@ -20,20 +21,15 @@ tracing-appender = { version = "0.2" } tracing-subscriber = { workspace = true, features = ["env-filter"] } [dependencies] -anlg-user-error = { workspace = true } +anlg-crash-reporting = { workspace = true } tauri = { workspace = true } tauri-specta = { workspace = true, features = ["derive", "typescript"] } -sentry = { workspace = true, features = ["tracing"] } -tauri-plugin-sentry = { workspace = true } - -dirs = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } specta = { workspace = true, features = ["derive", "serde_json"] } -thiserror = { workspace = true } -regex = "1" +thiserror = { workspace = true } tracing = { workspace = true } tracing-appender = { version = "0.2" } tracing-subscriber = { workspace = true, features = ["env-filter", "chrono"] } diff --git a/plugins/tracing/src/lib.rs b/plugins/tracing/src/lib.rs index 692e5073f90..8375ce32c32 100644 --- a/plugins/tracing/src/lib.rs +++ b/plugins/tracing/src/lib.rs @@ -1,14 +1,15 @@ mod commands; mod errors; mod ext; -pub mod redaction; mod utils; +pub use anlg_crash_reporting::{filter, redaction}; +pub use filter::WEBVIEW_CONSOLE_TARGET; + pub use errors::*; pub use ext::*; pub use utils::{cleanup_old_daily_logs, make_file_writer}; -use sentry::integrations::tracing::EventFilter; use tauri::Manager; use tracing_subscriber::{ EnvFilter, fmt, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, @@ -17,30 +18,6 @@ use tracing_subscriber::{ use utils::cleanup_legacy_logs; const PLUGIN_NAME: &str = "tracing"; -const WEBVIEW_CONSOLE_TARGET: &str = "anarlog.webview.console"; - -fn sentry_event_filter(metadata: &tracing::Metadata<'_>) -> EventFilter { - sentry_event_filter_for(metadata.level(), metadata.target()) -} - -fn is_webview_console_target(target: &str) -> bool { - target == WEBVIEW_CONSOLE_TARGET - || target == "hyprnote.webview.console" - || target.starts_with("tauri_plugin_tracing") -} - -fn sentry_event_filter_for(level: &tracing::Level, target: &str) -> EventFilter { - if is_webview_console_target(target) { - return EventFilter::Ignore; - } - - match *level { - tracing::Level::ERROR => EventFilter::Event, - tracing::Level::WARN | tracing::Level::INFO => EventFilter::Breadcrumb, - tracing::Level::DEBUG | tracing::Level::TRACE => EventFilter::Ignore, - } -} - fn make_specta_builder() -> tauri_specta::Builder { tauri_specta::Builder::::new() .plugin_name(PLUGIN_NAME) @@ -89,8 +66,7 @@ impl Builder { .add_directive("ort=warn".parse().unwrap()) .add_directive("tantivy=error".parse().unwrap()); - let sentry_layer = - sentry::integrations::tracing::layer().event_filter(sentry_event_filter); + let sentry_layer = anlg_crash_reporting::tracing_layer(); let logs_dir = match app.tracing().logs_dir() { Ok(dir) => dir, @@ -176,24 +152,41 @@ mod test { #[test] fn sentry_filter_keeps_only_native_errors_as_events() { assert_eq!( - sentry_event_filter_for(&tracing::Level::ERROR, "native").bits(), - EventFilter::Event.bits() + anlg_crash_reporting::filter::sentry_event_filter_for( + &tracing::Level::ERROR, + "native", + ) + .bits(), + sentry::integrations::tracing::EventFilter::Event.bits() ); assert_eq!( - sentry_event_filter_for(&tracing::Level::WARN, "native").bits(), - EventFilter::Breadcrumb.bits() + anlg_crash_reporting::filter::sentry_event_filter_for(&tracing::Level::WARN, "native",) + .bits(), + sentry::integrations::tracing::EventFilter::Breadcrumb.bits() ); assert_eq!( - sentry_event_filter_for(&tracing::Level::ERROR, WEBVIEW_CONSOLE_TARGET).bits(), - EventFilter::Ignore.bits() + anlg_crash_reporting::filter::sentry_event_filter_for( + &tracing::Level::ERROR, + WEBVIEW_CONSOLE_TARGET, + ) + .bits(), + sentry::integrations::tracing::EventFilter::Ignore.bits() ); assert_eq!( - sentry_event_filter_for(&tracing::Level::ERROR, "tauri_plugin_tracing::ext").bits(), - EventFilter::Ignore.bits() + anlg_crash_reporting::filter::sentry_event_filter_for( + &tracing::Level::ERROR, + "tauri_plugin_tracing::ext", + ) + .bits(), + sentry::integrations::tracing::EventFilter::Ignore.bits() ); assert_eq!( - sentry_event_filter_for(&tracing::Level::ERROR, "hyprnote.webview.console").bits(), - EventFilter::Ignore.bits() + anlg_crash_reporting::filter::sentry_event_filter_for( + &tracing::Level::ERROR, + "hyprnote.webview.console", + ) + .bits(), + sentry::integrations::tracing::EventFilter::Ignore.bits() ); } }