use crate::SentryConfig;
use sentry::ClientInitGuard as SentryGuard;
use strut_core::{AppContext, AppProfile, AppReplica, AppSpindown, AppSpindownToken};
use tokio::runtime::Runtime;
pub struct SentryIntegration;
impl SentryIntegration {
pub fn init(config: impl AsRef<SentryConfig>) -> SentryGuard {
let config = config.as_ref();
let guard = sentry::init((
config.dsn().unsecure(),
sentry::ClientOptions {
debug: config.debug(),
release: sentry::release_name!(),
environment: Some(AppProfile::active().as_str().into()),
sample_rate: config.sample_rate(),
traces_sample_rate: config.traces_sample_rate(),
max_breadcrumbs: config.max_breadcrumbs(),
attach_stacktrace: config.attach_stacktrace(),
shutdown_timeout: config.shutdown_timeout(),
..Default::default()
},
));
sentry::configure_scope(|scope| {
scope.set_tag(
"replica_index",
AppReplica::index()
.map(|index| index.to_string())
.unwrap_or_else(|| "unset".into()),
);
scope.set_tag("replica_lifetime_id", AppReplica::lifetime_id());
});
guard
}
pub fn schedule_flushing(runtime: &Runtime, sentry_guard: SentryGuard) {
let spindown_token = AppSpindown::register("sentry-integration");
runtime.spawn(Self::await_shutdown(sentry_guard, spindown_token));
}
async fn await_shutdown(sentry_guard: SentryGuard, spindown_token: AppSpindownToken) {
AppContext::terminated().await;
tokio::task::spawn_blocking(move || Self::drop_guard(sentry_guard, spindown_token));
}
fn drop_guard(guard: SentryGuard, _spindown_token: AppSpindownToken) {
drop(guard);
}
}