removed sentry and set it up better

This commit is contained in:
dal 2025-04-04 16:43:58 -06:00
parent 2649fb7656
commit 67932cfe39
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
11 changed files with 45 additions and 53 deletions

View File

@ -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
opt-level = 0 # Ensure this is 0 for faster debug builds
debug = 1 # Reduce debug info slightly while keeping enough for backtraces

View File

@ -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 }

View File

@ -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::<Request>::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()

View File

@ -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"));

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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);

View File

@ -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<String>, email_type: EmailType) ->
Ok(_) => (),
Err(e) => {
tracing::error!("Error sending email: {e}");
send_sentry_error(&format!("Error sending email: {e}"), None)
}
}
});

View File

@ -1,2 +1 @@
pub mod email;
pub mod sentry_utils;

View File

@ -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<User> = 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);
}