From 67932cfe39968f66bbb26e54a083a2237bffdea3 Mon Sep 17 00:00:00 2001 From: dal Date: Fri, 4 Apr 2025 16:43:58 -0600 Subject: [PATCH] removed sentry and set it up better --- api/Cargo.toml | 8 +++-- api/server/Cargo.toml | 2 ++ api/server/src/main.rs | 35 +++++++++++++++---- .../organizations/update_organization.rs | 3 +- .../routes/rest/routes/organizations/users.rs | 3 +- .../src/routes/rest/routes/users/get_user.rs | 2 -- .../rest/routes/users/get_user_by_id.rs | 3 +- .../routes/rest/routes/users/update_user.rs | 14 ++++---- api/server/src/utils/clients/email/resend.rs | 3 -- api/server/src/utils/clients/mod.rs | 1 - api/server/src/utils/clients/sentry_utils.rs | 24 ------------- 11 files changed, 45 insertions(+), 53 deletions(-) delete mode 100644 api/server/src/utils/clients/sentry_utils.rs diff --git a/api/Cargo.toml b/api/Cargo.toml index 0f6cafedd..679a14493 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -74,7 +74,8 @@ redis = { version = "0.27.5", features = [ "tls-rustls-webpki-roots", ] } resend-rs = "0.10.0" -sentry = { version = "0.35.0", features = ["tokio", "sentry-tracing"] } +sentry = { version = "0.37.0", features = ["tokio", "sentry-tracing"] } +sentry-tower = { version = "0.37.0", features = ["axum", "http"] } serde_urlencoded = "0.7.1" snowflake-api = "0.11.0" tempfile = "3.10.1" @@ -89,6 +90,7 @@ tiberius = { version = "0.12.2", default-features = false, features = [ tiktoken-rs = "0.6.0" tokio-stream = "0.1.15" tokio-util = { version = "0.7.11", features = ["compat"] } +tower = { version = "0.5.2" } tower-http = { version = "0.6.2", features = [ "cors", "trace", @@ -106,5 +108,5 @@ incremental = true [profile.dev] incremental = true -opt-level = 0 # Ensure this is 0 for faster debug builds -debug = 1 # Reduce debug info slightly while keeping enough for backtraces \ No newline at end of file +opt-level = 0 # Ensure this is 0 for faster debug builds +debug = 1 # Reduce debug info slightly while keeping enough for backtraces diff --git a/api/server/Cargo.toml b/api/server/Cargo.toml index ee9509fe2..dae42bf1f 100644 --- a/api/server/Cargo.toml +++ b/api/server/Cargo.toml @@ -39,6 +39,7 @@ resend-rs = { workspace = true } rustls = { workspace = true } rustls-native-certs = { workspace = true } sentry = { workspace = true } +sentry-tower = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } serde_urlencoded = { workspace = true } @@ -53,6 +54,7 @@ tokio-postgres = { workspace = true } tokio-postgres-rustls = { workspace = true } tokio-stream = { workspace = true } tokio-util = { workspace = true } +tower = { workspace = true } tower-http = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true } diff --git a/api/server/src/main.rs b/api/server/src/main.rs index 9ff1608e8..10aa697e3 100644 --- a/api/server/src/main.rs +++ b/api/server/src/main.rs @@ -4,7 +4,7 @@ pub mod utils; use std::env; use std::sync::Arc; -use axum::{Extension, Router}; +use axum::{Extension, Router, extract::Request}; use middleware::cors::cors; use database::{self, pool::init_pools}; use diesel::{Connection, PgConnection}; @@ -12,6 +12,7 @@ use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; use dotenv::dotenv; use rustls::crypto::ring; use tokio::sync::broadcast; +use tower::ServiceBuilder; use tower_http::{compression::CompressionLayer, trace::TraceLayer}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; @@ -23,16 +24,26 @@ async fn main() { dotenv().ok(); let environment = env::var("ENVIRONMENT").unwrap_or_else(|_| "development".to_string()); + let is_development = environment == "development"; ring::default_provider() .install_default() .expect("Failed to install default crypto provider"); - let _guard = sentry::init(("https://a417fbed1de30d2714a8afbe38d5bc1b@o4505360096428032.ingest.us.sentry.io/4507360721043456", sentry::ClientOptions { - release: sentry::release_name!(), - environment: Some(environment.into()), - ..Default::default() - })); + // Only initialize Sentry if not in development environment + let _guard = if !is_development { + Some(sentry::init(( + "https://a417fbed1de30d2714a8afbe38d5bc1b@o4505360096428032.ingest.us.sentry.io/4507360721043456", + sentry::ClientOptions { + release: sentry::release_name!(), + environment: Some(environment.clone().into()), + traces_sample_rate: 1.0, + ..Default::default() + } + ))) + } else { + None + }; tracing_subscriber::registry() .with( @@ -67,6 +78,7 @@ async fn main() { let (shutdown_tx, _) = broadcast::channel::<()>(1); let shutdown_tx = Arc::new(shutdown_tx); + // Build the router with or without Sentry layers based on environment let app = Router::new() .merge(protected_router) .merge(public_router) @@ -75,6 +87,17 @@ async fn main() { .layer(CompressionLayer::new()) .layer(Extension(shutdown_tx.clone())); + // Add Sentry layers if not in development + let app = if !is_development { + app.layer( + ServiceBuilder::new() + .layer(sentry_tower::NewSentryLayer::::new_from_top()) + .layer(sentry_tower::SentryHttpLayer::with_transaction()) + ) + } else { + app + }; + let port_number: u16 = env::var("PORT") .unwrap_or_else(|_| "3001".to_string()) .parse() diff --git a/api/server/src/routes/rest/routes/organizations/update_organization.rs b/api/server/src/routes/rest/routes/organizations/update_organization.rs index d95f059d3..b9395fbf1 100644 --- a/api/server/src/routes/rest/routes/organizations/update_organization.rs +++ b/api/server/src/routes/rest/routes/organizations/update_organization.rs @@ -7,7 +7,7 @@ use handlers::organizations::{ update_organization_handler, }; -use crate::{routes::rest::ApiResponse, utils::clients::sentry_utils::send_sentry_error}; +use crate::routes::rest::ApiResponse; use middleware::AuthenticatedUser; pub async fn update_organization( @@ -27,7 +27,6 @@ pub async fn update_organization( Ok(organization) => organization, Err(e) => { tracing::error!("Error updating organization: {:?}", e); - send_sentry_error(&e.to_string(), Some(&user.id)); if e.to_string().contains("not a workspace admin") { return Err((StatusCode::FORBIDDEN, "User is not a workspace admin")); diff --git a/api/server/src/routes/rest/routes/organizations/users.rs b/api/server/src/routes/rest/routes/organizations/users.rs index 435e128df..16dcc299c 100644 --- a/api/server/src/routes/rest/routes/organizations/users.rs +++ b/api/server/src/routes/rest/routes/organizations/users.rs @@ -11,7 +11,7 @@ use database::{ schema::{users, users_to_organizations}, }; -use crate::{routes::rest::ApiResponse, utils::clients::sentry_utils::send_sentry_error}; +use crate::routes::rest::ApiResponse; use middleware::AuthenticatedUser; #[derive(Serialize, Deserialize, Clone)] @@ -31,7 +31,6 @@ pub async fn list_organization_users( Ok(users) => users, Err(e) => { tracing::error!("Error listing organization users: {:?}", e); - send_sentry_error(&e.to_string(), Some(&user.id)); return Err(( StatusCode::INTERNAL_SERVER_ERROR, "Error listing organization users", diff --git a/api/server/src/routes/rest/routes/users/get_user.rs b/api/server/src/routes/rest/routes/users/get_user.rs index ed6ede102..ea64a0a22 100644 --- a/api/server/src/routes/rest/routes/users/get_user.rs +++ b/api/server/src/routes/rest/routes/users/get_user.rs @@ -9,7 +9,6 @@ use database::schema::{ organizations, teams, teams_to_users, users, users_to_organizations, }; use crate::routes::rest::ApiResponse; -use crate::utils::clients::sentry_utils::send_sentry_error; use axum::http::StatusCode; use diesel::{ BoolExpressionMethods, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, QueryDsl, @@ -25,7 +24,6 @@ pub async fn get_user( Ok(user_info_object) => user_info_object, Err(e) => { tracing::error!("Error getting user information: {:?}", e); - send_sentry_error(&e.to_string(), Some(&user.id)); return Err(( StatusCode::INTERNAL_SERVER_ERROR, "Error getting user information", diff --git a/api/server/src/routes/rest/routes/users/get_user_by_id.rs b/api/server/src/routes/rest/routes/users/get_user_by_id.rs index f0d2e64b7..85b54572c 100644 --- a/api/server/src/routes/rest/routes/users/get_user_by_id.rs +++ b/api/server/src/routes/rest/routes/users/get_user_by_id.rs @@ -13,7 +13,7 @@ use database::{ }, }; -use crate::{routes::rest::ApiResponse, utils::clients::sentry_utils::send_sentry_error}; +use crate::routes::rest::ApiResponse; use axum::http::StatusCode; use diesel::{ BoolExpressionMethods, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, QueryDsl, @@ -54,7 +54,6 @@ pub async fn get_user_by_id( Ok(user_info) => user_info, Err(e) => { tracing::error!("Error getting user information: {:?}", e); - send_sentry_error(&e.to_string(), Some(&user.id)); return Err(( StatusCode::INTERNAL_SERVER_ERROR, "Error getting user information", diff --git a/api/server/src/routes/rest/routes/users/update_user.rs b/api/server/src/routes/rest/routes/users/update_user.rs index 48ad8be2a..db9ad5732 100644 --- a/api/server/src/routes/rest/routes/users/update_user.rs +++ b/api/server/src/routes/rest/routes/users/update_user.rs @@ -2,19 +2,18 @@ use anyhow::Result; use axum::extract::Path; use axum::{Extension, Json}; +use crate::routes::rest::ApiResponse; +use crate::utils::security::checks::is_user_workspace_admin_or_data_admin; +use axum::http::StatusCode; use database::enums::UserOrganizationStatus; +use database::organization::get_user_organization_id; use database::schema::{users, users_to_organizations}; use database::{enums::UserOrganizationRole, pool::get_pg_pool}; -use crate::routes::rest::ApiResponse; -use crate::utils::clients::sentry_utils::send_sentry_error; -use crate::utils::security::checks::is_user_workspace_admin_or_data_admin; -use database::organization::get_user_organization_id; -use axum::http::StatusCode; use diesel::{update, ExpressionMethods}; use diesel_async::RunQueryDsl; +use middleware::AuthenticatedUser; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use middleware::AuthenticatedUser; #[derive(Serialize, Deserialize, Clone)] pub struct UserResponse { @@ -40,7 +39,6 @@ pub async fn update_user( Ok(_) => (), Err(e) => { tracing::error!("Error getting user information: {:?}", e); - send_sentry_error(&e.to_string(), Some(&user.id)); return Err(( StatusCode::INTERNAL_SERVER_ERROR, "Error getting user information", @@ -120,7 +118,7 @@ pub async fn update_user_handler( )) } }; - }, + } Ok(false) => return Err(anyhow::anyhow!("Insufficient permissions to update role")), Err(e) => { tracing::error!("Error checking user permissions for role update: {:?}", e); diff --git a/api/server/src/utils/clients/email/resend.rs b/api/server/src/utils/clients/email/resend.rs index a97410b6a..a5903c89e 100644 --- a/api/server/src/utils/clients/email/resend.rs +++ b/api/server/src/utils/clients/email/resend.rs @@ -5,8 +5,6 @@ use html_escape::encode_text as escape_html; use resend_rs::{types::CreateEmailBaseOptions, Resend}; -use crate::utils::clients::sentry_utils::send_sentry_error; - lazy_static::lazy_static! { static ref RESEND_API_KEY: String = env::var("RESEND_API_KEY").expect("RESEND_API_KEY must be set"); static ref RESEND_CLIENT: Resend = Resend::new(&RESEND_API_KEY); @@ -86,7 +84,6 @@ pub async fn send_email(to_addresses: HashSet, email_type: EmailType) -> Ok(_) => (), Err(e) => { tracing::error!("Error sending email: {e}"); - send_sentry_error(&format!("Error sending email: {e}"), None) } } }); diff --git a/api/server/src/utils/clients/mod.rs b/api/server/src/utils/clients/mod.rs index 98dae6a87..aa5f45d47 100644 --- a/api/server/src/utils/clients/mod.rs +++ b/api/server/src/utils/clients/mod.rs @@ -1,2 +1 @@ pub mod email; -pub mod sentry_utils; diff --git a/api/server/src/utils/clients/sentry_utils.rs b/api/server/src/utils/clients/sentry_utils.rs deleted file mode 100644 index c35cb3b84..000000000 --- a/api/server/src/utils/clients/sentry_utils.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::time::SystemTime; - -use sentry::{capture_event, protocol::Event, User}; -use uuid::Uuid; - -pub fn send_sentry_error(message: &String, user_id: Option<&Uuid>) { - let user: Option = match user_id { - Some(id) => Some(User { - id: Some(id.to_string()), - ..Default::default() - }), - None => None, - }; - - let event = Event { - message: Some(message.to_string()), - level: sentry::Level::Error, - event_id: Uuid::new_v4(), - timestamp: SystemTime::now(), - user, - ..Default::default() - }; - capture_event(event); -}