diff --git a/rust/cymbal/src/frames/records.rs b/rust/cymbal/src/frames/records.rs index 157fd9d85ce03..8b969f060f7b9 100644 --- a/rust/cymbal/src/frames/records.rs +++ b/rust/cymbal/src/frames/records.rs @@ -43,6 +43,11 @@ impl ErrorTrackingStackFrame { where E: Executor<'c, Database = sqlx::Postgres>, { + let context = if let Some(context) = &self.context { + Some(serde_json::to_string(context)?) + } else { + None + }; sqlx::query!( r#" INSERT INTO posthog_errortrackingstackframe (raw_id, team_id, created_at, symbol_set_id, contents, resolved, id, context) @@ -61,7 +66,7 @@ impl ErrorTrackingStackFrame { serde_json::to_value(&self.contents)?, self.resolved, Uuid::now_v7(), - serde_json::to_string(&self.context)? + context ).execute(e).await?; Ok(()) } diff --git a/rust/cymbal/src/symbol_store/concurrency.rs b/rust/cymbal/src/symbol_store/concurrency.rs index 466bfa8fce2f5..58094e6b61d24 100644 --- a/rust/cymbal/src/symbol_store/concurrency.rs +++ b/rust/cymbal/src/symbol_store/concurrency.rs @@ -71,7 +71,7 @@ where type Set = P::Set; async fn lookup(&self, team_id: i32, r: Self::Ref) -> Result, Error> { - let lock = self.acquire(r.to_string()).await; + let lock = self.acquire(format!("{}:{}", team_id, r.to_string())).await; let result = self.inner.lookup(team_id, r).await; drop(lock); result diff --git a/rust/cymbal/src/symbol_store/saving.rs b/rust/cymbal/src/symbol_store/saving.rs index a9b3f0ed19bf8..5a668ea58e47b 100644 --- a/rust/cymbal/src/symbol_store/saving.rs +++ b/rust/cymbal/src/symbol_store/saving.rs @@ -2,7 +2,7 @@ use axum::async_trait; use chrono::{DateTime, Utc}; use sqlx::PgPool; -use tracing::error; +use tracing::{error, info}; use uuid::Uuid; use crate::{ @@ -71,6 +71,7 @@ impl Saving { set_ref: String, data: Vec, ) -> Result { + info!("Saving symbol set data for {}", set_ref); let start = common_metrics::timing_guard(SAVE_SYMBOL_SET, &[]).label("data", "true"); // Generate a new opaque key, appending our prefix. let key = self.add_prefix(Uuid::now_v7().to_string()); @@ -96,6 +97,7 @@ impl Saving { set_ref: String, reason: &FrameError, ) -> Result<(), UnhandledError> { + info!("Saving symbol set error for {}", set_ref); let start = common_metrics::timing_guard(SAVE_SYMBOL_SET, &[]).label("data", "false"); SymbolSetRecord { id: Uuid::now_v7(), @@ -127,8 +129,10 @@ where async fn fetch(&self, team_id: i32, r: Self::Ref) -> Result { let set_ref = r.to_string(); + info!("Fetching symbol set data for {}", set_ref); if let Some(record) = SymbolSetRecord::load(&self.pool, team_id, &set_ref).await? { if let Some(storage_ptr) = record.storage_ptr { + info!("Found symbol set data for {}", set_ref); let data = self.s3_client.get(&self.bucket, &storage_ptr).await?; metrics::counter!(SAVED_SYMBOL_SET_LOADED).increment(1); return Ok(Saveable { @@ -138,6 +142,7 @@ where set_ref, }); } else if Utc::now() - record.created_at < chrono::Duration::days(1) { + info!("Found recent symbol set error for {}", set_ref); // We tried less than a day ago to get the set data, and failed, so bail out // with the stored error. We unwrap here because we should never store a "no set" // row without also storing the error, and if we do, we want to panic, but we @@ -155,18 +160,22 @@ where .map_err(UnhandledError::from)?; return Err(Error::ResolutionError(error)); } + info!("Found stale symbol set error for {}", set_ref); // We last tried to get the symbol set more than a day ago, so we should try again metrics::counter!(SYMBOL_SET_FETCH_RETRY).increment(1); } match self.inner.fetch(team_id, r).await { // NOTE: We don't save the data here, because we want to save it only after parsing - Ok(data) => Ok(Saveable { - data, - storage_ptr: None, - team_id, - set_ref, - }), + Ok(data) => { + info!("Inner fetched symbol set data for {}", set_ref); + Ok(Saveable { + data, + storage_ptr: None, + team_id, + set_ref, + }) + } Err(Error::ResolutionError(e)) => { // But if we failed to get any data, we save that fact self.save_no_data(team_id, set_ref, &e).await?; @@ -188,6 +197,7 @@ where async fn parse(&self, data: Saveable) -> Result { match self.inner.parse(data.data.clone()).await { Ok(s) => { + info!("Parsed symbol set data for {}", data.set_ref); if data.storage_ptr.is_none() { // We only save the data if we fetched it from the underlying fetcher self.save_data(data.team_id, data.set_ref, data.data) @@ -196,6 +206,7 @@ where return Ok(s); } Err(Error::ResolutionError(e)) => { + info!("Failed to parse symbol set data for {}", data.set_ref); // We save the no-data case here, to prevent us from fetching again for day self.save_no_data(data.team_id, data.set_ref, &e).await?; return Err(Error::ResolutionError(e));