Merge pull request #1600 from gitbutlerapp/add-sentry-integration

Add sentry integration
This commit is contained in:
Nikita Galaiko 2023-11-14 15:12:53 +01:00 committed by GitHub
commit 5e2aa2f592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 62 additions and 32 deletions

View File

@ -5,24 +5,13 @@ use tauri::{generate_context, Manager};
use gblib::{
analytics, app, assets, bookmarks, commands, database, deltas, github, keys, logs, projects,
sessions, storage, users, virtual_branches, watcher, zip,
sentry, sessions, storage, users, virtual_branches, watcher, zip,
};
fn main() {
let tauri_context = generate_context!();
let _guard = sentry::init(("https://9d407634d26b4d30b6a42d57a136d255@o4504644069687296.ingest.sentry.io/4504649768108032", sentry::ClientOptions {
release: Some(tauri_context.package_info().version.to_string().into()),
environment: Some(match tauri_context.package_info().name.as_str() {
"GitButler" => "production",
"GitButler Nightly" => "nightly",
"GitButler Dev" => "development",
_ => "unknown",
}.into()),
attach_stacktrace: true,
default_integrations: true,
..Default::default()
}));
let _guard = sentry::init(tauri_context.package_info());
tokio::runtime::Builder::new_multi_thread()
.enable_all()
@ -141,9 +130,7 @@ fn main() {
app_handle.manage(keys_controller);
let users_controller = users::Controller::from(&app_handle);
if let Some(user) = users_controller.get_user().context("failed to get user")? {
sentry::configure_scope(|scope| scope.set_user(Some(user.clone().into())));
}
sentry::configure_scope(users_controller.get_user().context("failed to get user")?.as_ref());
app_handle.manage(users_controller);
let app: app::App = app::App::try_from(&tauri_app.app_handle())

View File

@ -22,6 +22,7 @@ pub mod paths;
pub mod project_repository;
pub mod projects;
pub mod reader;
pub mod sentry;
pub mod sessions;
pub mod storage;
pub mod users;

View File

@ -4,7 +4,7 @@ use tauri::{AppHandle, Manager};
use tracing::{metadata::LevelFilter, subscriber::set_global_default};
use tracing_subscriber::{fmt::format::FmtSpan, layer::SubscriberExt, Layer};
use crate::paths::LogsDir;
use crate::{paths::LogsDir, sentry};
pub fn init(app_handle: &AppHandle) {
let logs_dir = LogsDir::try_from(app_handle)
@ -45,7 +45,7 @@ pub fn init(app_handle: &AppHandle) {
.with_span_events(FmtSpan::CLOSE)
.with_filter(log_level_filter),
)
.with(sentry_tracing::layer())
.with(sentry::tracing_layer())
.with(
// subscriber that writes spans to a file
tracing_subscriber::fmt::layer()

View File

@ -0,0 +1,53 @@
use std::sync::Arc;
use sentry::ClientInitGuard;
use sentry_tracing::SentryLayer;
use tauri::PackageInfo;
use tracing::Subscriber;
use tracing_subscriber::registry::LookupSpan;
use crate::users;
/// Should be called once on application startup, and the returned guard should be kept alive for
/// the lifetime of the application.
pub fn init(package_info: &PackageInfo) -> ClientInitGuard {
sentry::init(("https://9d407634d26b4d30b6a42d57a136d255@o4504644069687296.ingest.sentry.io/4504649768108032", sentry::ClientOptions {
environment: Some(match package_info.name.as_str() {
"GitButler" => "production",
"GitButler Nightly" => "nightly",
"GitButler Dev" => "development",
_ => "unknown",
}.into()),
release: Some(package_info.version.to_string().into()),
before_send: Some(Arc::new(|event| {
Some(event)
})),
attach_stacktrace: true,
default_integrations: true,
..Default::default()
}))
}
/// Sets the current user in the Sentry scope.
/// There is only one scope in the application, so this will overwrite any previous user.
pub fn configure_scope(user: Option<&users::User>) {
sentry::configure_scope(|scope| {
scope.set_user(user.map(|user| sentry::User {
id: Some(user.id.to_string()),
username: Some(user.name.clone()),
email: Some(user.email.clone()),
..Default::default()
}));
});
}
/// Returns a tracing layer that will send all errors to Sentry.
pub fn tracing_layer<S>() -> SentryLayer<S>
where
S: Subscriber + for<'a> LookupSpan<'a>,
{
sentry_tracing::layer().event_filter(|md| match md.level() {
&tracing::Level::ERROR => sentry_tracing::EventFilter::Event,
_ => sentry_tracing::EventFilter::Ignore,
})
}

View File

@ -1,7 +1,7 @@
use tauri::{AppHandle, Manager};
use tracing::instrument;
use crate::{assets, error::Error};
use crate::{assets, error::Error, sentry};
use super::{
controller::{self, Controller, GetError},
@ -50,7 +50,7 @@ pub async fn set_user(handle: AppHandle, user: User) -> Result<User, Error> {
app.set_user(&user)?;
sentry::configure_scope(|scope| scope.set_user(Some(user.clone().into())));
sentry::configure_scope(Some(&user));
Ok(proxy.proxy_user(user).await)
}
@ -73,7 +73,7 @@ pub async fn delete_user(handle: AppHandle) -> Result<(), Error> {
app.delete_user()?;
sentry::configure_scope(|scope| scope.set_user(None));
sentry::configure_scope(None);
Ok(())
}

View File

@ -19,17 +19,6 @@ pub struct User {
pub github_username: Option<String>,
}
impl From<User> for sentry::User {
fn from(val: User) -> Self {
sentry::User {
id: Some(val.id.to_string()),
username: Some(val.name),
email: Some(val.email),
..Default::default()
}
}
}
impl TryFrom<User> for git::Signature<'_> {
type Error = git::Error;