From 71e0786fcdf89ea0f2633e4a79b9c0ffbcc5eab4 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Mon, 27 Mar 2023 17:53:01 -0700 Subject: [PATCH 01/19] feat(replays): add replay_id to DSC --- relay-sampling/src/lib.rs | 21 +++++++++++++++++++++ relay-server/src/testutils.rs | 1 + relay-server/src/utils/dynamic_sampling.rs | 1 + 3 files changed, 23 insertions(+) diff --git a/relay-sampling/src/lib.rs b/relay-sampling/src/lib.rs index 510b9f2402b..6c6f9378542 100644 --- a/relay-sampling/src/lib.rs +++ b/relay-sampling/src/lib.rs @@ -1164,6 +1164,8 @@ pub struct DynamicSamplingContext { /// user object). #[serde(flatten, default)] pub user: TraceUserContext, + /// if the event occured during a session replay, the associated replay_id is added to the DSC + pub replay_id: Option, /// Additional arbitrary fields for forwards compatibility. #[serde(flatten, default)] pub other: BTreeMap, @@ -1197,6 +1199,7 @@ impl DynamicSamplingContext { release: event.release.as_str().map(str::to_owned), environment: event.environment.value().cloned(), transaction: event.transaction.value().cloned(), + replay_id: None, sample_rate: None, user: TraceUserContext { user_segment: user @@ -1311,6 +1314,7 @@ mod tests { transaction: None, sample_rate: None, user: TraceUserContext::default(), + replay_id: None, other: BTreeMap::new(), } } @@ -1413,6 +1417,7 @@ mod tests { user_segment: user_segment.to_string(), user_id: user_id.to_string(), }, + replay_id: Default::default(), other: Default::default(), } } @@ -1587,6 +1592,7 @@ mod tests { environment: Some("prod".into()), transaction: Some("transaction1".into()), sample_rate: None, + replay_id: Some(Uuid::new_v4()), other: BTreeMap::new(), }; @@ -1622,6 +1628,7 @@ mod tests { environment: None, transaction: None, sample_rate: None, + replay_id: None, other: BTreeMap::new(), }; assert_eq!(Value::Null, dsc.get_value("trace.release")); @@ -1638,6 +1645,7 @@ mod tests { environment: None, transaction: None, sample_rate: None, + replay_id: None, other: BTreeMap::new(), }; assert_eq!(Value::Null, dsc.get_value("trace.user.id")); @@ -1742,6 +1750,7 @@ mod tests { user_segment: "vip".into(), user_id: "user-id".into(), }, + replay_id: Some(Uuid::new_v4()), environment: Some("debug".into()), transaction: Some("transaction1".into()), sample_rate: None, @@ -1917,6 +1926,7 @@ mod tests { user_segment: "vip".to_owned(), user_id: "user-id".to_owned(), }, + replay_id: Some(Uuid::new_v4()), environment: Some("debug".to_string()), transaction: Some("transaction1".into()), sample_rate: None, @@ -1979,6 +1989,7 @@ mod tests { user_segment: "vip".to_owned(), user_id: "user-id".to_owned(), }, + replay_id: Some(Uuid::new_v4()), environment: Some("debug".to_string()), transaction: Some("transaction1".into()), sample_rate: None, @@ -2018,6 +2029,7 @@ mod tests { user_segment: "vip".to_owned(), user_id: "user-id".to_owned(), }, + replay_id: Some(Uuid::new_v4()), environment: Some("debug".to_string()), transaction: Some("transaction1".into()), sample_rate: None, @@ -2080,6 +2092,7 @@ mod tests { user_segment: "vip".to_owned(), user_id: "user-id".to_owned(), }, + replay_id: Some(Uuid::new_v4()), environment: Some("debug".to_string()), transaction: Some("transaction1".into()), sample_rate: None, @@ -2467,6 +2480,7 @@ mod tests { user_segment: "vip".to_owned(), user_id: "user-id".to_owned(), }, + replay_id: Some(Uuid::new_v4()), environment: Some("debug".to_string()), transaction: Some("transaction1".into()), sample_rate: None, @@ -2487,6 +2501,7 @@ mod tests { public_key: ProjectKey::parse("abd0f232775f45feab79864e580d160b").unwrap(), release: Some("1.1.1".to_string()), user: TraceUserContext::default(), + replay_id: Some(Uuid::new_v4()), environment: Some("debug".to_string()), transaction: Some("transaction1".into()), sample_rate: None, @@ -2510,6 +2525,7 @@ mod tests { user_segment: "vip".to_owned(), user_id: "user-id".to_owned(), }, + replay_id: None, environment: None, transaction: Some("transaction1".into()), sample_rate: None, @@ -2533,6 +2549,7 @@ mod tests { user_segment: "vip".to_owned(), user_id: "user-id".to_owned(), }, + replay_id: None, environment: Some("debug".to_string()), transaction: None, sample_rate: None, @@ -2549,6 +2566,7 @@ mod tests { public_key: ProjectKey::parse("abd0f232775f45feab79864e580d160b").unwrap(), release: None, user: TraceUserContext::default(), + replay_id: None, environment: None, transaction: None, sample_rate: None, @@ -2944,6 +2962,7 @@ mod tests { "environment": None, "transaction": None, "user_id": "hello", + "replay_id": None, } "###); } @@ -2968,6 +2987,7 @@ mod tests { "transaction": None, "sample_rate": "0.5", "user_id": "hello", + "replay_id": None, } "###); } @@ -2992,6 +3012,7 @@ mod tests { "transaction": None, "sample_rate": "0.00001", "user_id": "hello", + "replay_id": None, } "###); } diff --git a/relay-server/src/testutils.rs b/relay-server/src/testutils.rs index a1ae3214cea..f69f248d235 100644 --- a/relay-server/src/testutils.rs +++ b/relay-server/src/testutils.rs @@ -48,6 +48,7 @@ pub fn create_sampling_context(sample_rate: Option) -> DynamicSamplingConte transaction: None, sample_rate, user: Default::default(), + replay_id: None, other: Default::default(), } } diff --git a/relay-server/src/utils/dynamic_sampling.rs b/relay-server/src/utils/dynamic_sampling.rs index 6e79ba7c65d..21e6a13ec3e 100644 --- a/relay-server/src/utils/dynamic_sampling.rs +++ b/relay-server/src/utils/dynamic_sampling.rs @@ -226,6 +226,7 @@ mod tests { transaction: transaction.map(|value| value.to_string()), sample_rate, user: Default::default(), + replay_id: Default::default(), other: Default::default(), } } From c124f9db7b7040e684ce99b7213fe19631050b53 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Tue, 28 Mar 2023 17:12:47 -0700 Subject: [PATCH 02/19] add context, start on test --- relay-general/src/protocol/contexts/mod.rs | 5 ++ relay-general/src/protocol/contexts/replay.rs | 25 +++++++ relay-server/src/actors/processor.rs | 66 ++++++++++++++++++- 3 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 relay-general/src/protocol/contexts/replay.rs diff --git a/relay-general/src/protocol/contexts/mod.rs b/relay-general/src/protocol/contexts/mod.rs index fcae472c2b7..25877db4b83 100644 --- a/relay-general/src/protocol/contexts/mod.rs +++ b/relay-general/src/protocol/contexts/mod.rs @@ -12,6 +12,8 @@ mod os; pub use os::*; mod profile; pub use profile::*; +mod replay; +pub use replay::*; mod reprocessing; pub use reprocessing::*; mod response; @@ -53,6 +55,8 @@ pub enum Context { Trace(Box), /// Information related to Profiling. Profile(Box), + /// Information related to Replay. + Replay(Box), /// Information related to Monitors feature. Monitor(Box), /// Auxilliary information for reprocessing. @@ -85,6 +89,7 @@ impl Context { Context::Trace(_) => Some(TraceContext::default_key()), Context::Profile(_) => Some(ProfileContext::default_key()), Context::Monitor(_) => Some(MonitorContext::default_key()), + Context::Replay(_) => Some(ReplayContext::default_key()), Context::Response(_) => Some(ResponseContext::default_key()), Context::Otel(_) => Some(OtelContext::default_key()), Context::CloudResource(_) => Some(CloudResourceContext::default_key()), diff --git a/relay-general/src/protocol/contexts/replay.rs b/relay-general/src/protocol/contexts/replay.rs new file mode 100644 index 00000000000..0d1ec7c0002 --- /dev/null +++ b/relay-general/src/protocol/contexts/replay.rs @@ -0,0 +1,25 @@ +use crate::protocol::EventId; +use crate::types::Annotated; + +/// Profile context +#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] +#[cfg_attr(feature = "jsonschema", derive(JsonSchema))] +pub struct ReplayContext { + /// The profile ID. + #[metastructure(required = "true")] + pub replay_id: Annotated, +} + +impl ReplayContext { + /// The key under which a profile context is generally stored (in `Contexts`) + pub fn default_key() -> &'static str { + "replay" + } +} + +// #[cfg(test)] +// mod tests { +// use super::*; +// use crate::protocol::Context; + +// } diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 1e9b69fad97..dc6a1db9df7 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -21,8 +21,9 @@ use relay_general::pii::{PiiAttachmentsProcessor, PiiConfigError, PiiProcessor}; use relay_general::processor::{process_value, ProcessingState}; use relay_general::protocol::{ self, Breadcrumb, ClientReport, Csp, Event, EventType, ExpectCt, ExpectStaple, Hpkp, IpAddr, - LenientString, Metrics, RelayInfo, Replay, ReplayError, SecurityReportType, SessionAggregates, - SessionAttributes, SessionStatus, SessionUpdate, Timestamp, UserReport, Values, + LenientString, Metrics, RelayInfo, Replay, ReplayContext, ReplayError, SecurityReportType, + SessionAggregates, SessionAttributes, SessionStatus, SessionUpdate, Timestamp, UserReport, + Values, }; use relay_general::store::{ClockDriftProcessor, LightNormalizationConfig, TransactionNameConfig}; use relay_general::types::{Annotated, Array, FromValue, Object, ProcessingAction, Value}; @@ -1759,6 +1760,15 @@ impl EnvelopeProcessorService { // In processing mode, also write metrics into the event. Most metrics have already been // collected at this state, except for the combined size of all attachments. if self.config.processing_enabled() { + if let Some(dsc) = envelope.dsc() { + if let Some(replay_id) = dsc.replay_id { + let contexts = event.contexts.get_or_insert_with(Contexts::new); + contexts.add(SentryContext::Replay(Box::new(ReplayContext { + replay_id: Annotated::new(relay_general::protocol::EventId(replay_id)), + }))); + } + } + let mut metrics = std::mem::take(&mut state.metrics); let attachment_size = envelope @@ -2580,9 +2590,10 @@ mod tests { use std::str::FromStr; use chrono::{DateTime, TimeZone, Utc}; + use relay_common::{Dsn, Uuid}; use relay_general::pii::{DataScrubbingConfig, PiiConfig}; use relay_general::protocol::EventId; - use relay_sampling::{RuleCondition, RuleId, RuleType, SamplingMode}; + use relay_sampling::{RuleCondition, RuleId, RuleType, SamplingMode, TraceUserContext}; use relay_test::mock_service; use similar_asserts::assert_eq; @@ -2969,6 +2980,55 @@ mod tests { assert_eq!(new_envelope.items().next().unwrap().ty(), &ItemType::Event); } + #[tokio::test] + async fn test_replay_id_added_from_dsc() { + let processor = create_test_processor(Default::default()); + let event_id = protocol::EventId::new(); + + let dsn: Dsn = "https://e12d836b15bb49d7bbf99e64295d995b:@sentry.io/42" + .parse() + .unwrap(); + + let request_meta = RequestMeta::new(dsn); + let mut envelope = Envelope::from_request(Some(event_id), request_meta); + + let test_dsc = DynamicSamplingContext { + trace_id: Uuid::new_v4(), + release: None, + environment: None, + user: TraceUserContext { + user_segment: "vip".to_string(), + user_id: "me".to_string(), + }, + public_key: ProjectKey::parse("a94ae32be2584e0bbd7a4cbb95971fee").unwrap(), + transaction: None, + sample_rate: None, + other: BTreeMap::new(), + replay_id: Some(Uuid::new_v4()), + }; + + envelope.set_dsc(test_dsc); + + envelope.add_item({ + let mut item = Item::new(ItemType::Event); + item.set_payload(ContentType::Json, r###"{"foo": "bar"}"###); + item + }); + + let message = ProcessEnvelope { + envelope: ManagedEnvelope::standalone(envelope), + project_state: Arc::new(ProjectState::allowed()), + sampling_project_state: None, + }; + + let envelope_response = processor.process(message).unwrap(); + let ctx = envelope_response.envelope.unwrap(); + let new_envelope = ctx.envelope(); + + let item = new_envelope.items().next().unwrap(); + println!("{:?}", item); + } + #[tokio::test] async fn test_browser_version_extraction_with_pii_like_data() { let processor = create_test_processor(Default::default()); From 810784f634fabf1f1d6c0694e12edb2b3c2db03e Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Wed, 29 Mar 2023 17:37:37 -0700 Subject: [PATCH 03/19] add test case --- relay-general/src/protocol/contexts/replay.rs | 42 +++++++++++++++---- .../test_fixtures__event_schema.snap | 28 +++++++++++++ relay-server/src/actors/processor.rs | 27 ++++++++++-- 3 files changed, 86 insertions(+), 11 deletions(-) diff --git a/relay-general/src/protocol/contexts/replay.rs b/relay-general/src/protocol/contexts/replay.rs index 0d1ec7c0002..41c9026540b 100644 --- a/relay-general/src/protocol/contexts/replay.rs +++ b/relay-general/src/protocol/contexts/replay.rs @@ -1,25 +1,51 @@ use crate::protocol::EventId; use crate::types::Annotated; -/// Profile context +/// Replay context #[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] #[cfg_attr(feature = "jsonschema", derive(JsonSchema))] pub struct ReplayContext { - /// The profile ID. + /// The replay ID. #[metastructure(required = "true")] pub replay_id: Annotated, } impl ReplayContext { - /// The key under which a profile context is generally stored (in `Contexts`) + /// The key under which a replay context is generally stored (in `Contexts`) pub fn default_key() -> &'static str { "replay" } } -// #[cfg(test)] -// mod tests { -// use super::*; -// use crate::protocol::Context; +#[cfg(test)] +mod tests { + use super::*; + use crate::protocol::Context; -// } + #[test] + pub(crate) fn test_trace_context_roundtrip() { + let json = r#"{ + "replay_id": "4c79f60c11214eb38604f4ae0781bfb2", + "type": "replay" +}"#; + let context = Annotated::new(Context::Replay(Box::new(ReplayContext { + replay_id: Annotated::new(EventId("4c79f60c11214eb38604f4ae0781bfb2".parse().unwrap())), + }))); + + assert_eq!(context, Annotated::from_json(json).unwrap()); + assert_eq!(json, context.to_json_pretty().unwrap()); + } + + #[test] + pub(crate) fn test_replay_context_normalization() { + let json = r#"{ + "replay_id": "4C79F60C11214EB38604F4AE0781BFB2", + "type": "replay" +}"#; + let context = Annotated::new(Context::Replay(Box::new(ReplayContext { + replay_id: Annotated::new(EventId("4c79f60c11214eb38604f4ae0781bfb2".parse().unwrap())), + }))); + + assert_eq!(context, Annotated::from_json(json).unwrap()); + } +} diff --git a/relay-general/tests/snapshots/test_fixtures__event_schema.snap b/relay-general/tests/snapshots/test_fixtures__event_schema.snap index 1c0d909c16c..7d5e0c7dbbd 100644 --- a/relay-general/tests/snapshots/test_fixtures__event_schema.snap +++ b/relay-general/tests/snapshots/test_fixtures__event_schema.snap @@ -896,6 +896,9 @@ expression: "relay_general::protocol::event_json_schema()" { "$ref": "#/definitions/ProfileContext" }, + { + "$ref": "#/definitions/ReplayContext" + }, { "$ref": "#/definitions/MonitorContext" }, @@ -2665,6 +2668,31 @@ expression: "relay_general::protocol::event_json_schema()" "RegVal": { "type": "string" }, + "ReplayContext": { + "description": " Replay context", + "anyOf": [ + { + "type": "object", + "required": [ + "replay_id" + ], + "properties": { + "replay_id": { + "description": " The replay ID.", + "anyOf": [ + { + "$ref": "#/definitions/EventId" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + ] + }, "Request": { "description": " Http request information.\n\n The Request interface contains information on a HTTP request related to the event. In client\n SDKs, this can be an outgoing request, or the request that rendered the current web page. On\n server SDKs, this could be the incoming web request that is being handled.\n\n The data variable should only contain the request body (not the query string). It can either be\n a dictionary (for standard HTTP requests) or a raw request body.\n\n ### Ordered Maps\n\n In the Request interface, several attributes can either be declared as string, object, or list\n of tuples. Sentry attempts to parse structured information from the string representation in\n such cases.\n\n Sometimes, keys can be declared multiple times, or the order of elements matters. In such\n cases, use the tuple representation over a plain object.\n\n Example of request headers as object:\n\n ```json\n {\n \"content-type\": \"application/json\",\n \"accept\": \"application/json, application/xml\"\n }\n ```\n\n Example of the same headers as list of tuples:\n\n ```json\n [\n [\"content-type\", \"application/json\"],\n [\"accept\", \"application/json\"],\n [\"accept\", \"application/xml\"]\n ]\n ```\n\n Example of a fully populated request object:\n\n ```json\n {\n \"request\": {\n \"method\": \"POST\",\n \"url\": \"http://absolute.uri/foo\",\n \"query_string\": \"query=foobar&page=2\",\n \"data\": {\n \"foo\": \"bar\"\n },\n \"cookies\": \"PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;\",\n \"headers\": {\n \"content-type\": \"text/html\"\n },\n \"env\": {\n \"REMOTE_ADDR\": \"192.168.0.1\"\n }\n }\n }\n ```", "anyOf": [ diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index dc6a1db9df7..4f360cbc935 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -2982,7 +2982,18 @@ mod tests { #[tokio::test] async fn test_replay_id_added_from_dsc() { - let processor = create_test_processor(Default::default()); + let config = Config::from_json_value(serde_json::json!({ + "outcomes": { + "emit_outcomes": true, + "emit_client_outcomes": false, + }, + "processing": { + "enabled": true, + "kafka_config": [], + } + })) + .unwrap(); + let processor = create_test_processor(config); let event_id = protocol::EventId::new(); let dsn: Dsn = "https://e12d836b15bb49d7bbf99e64295d995b:@sentry.io/42" @@ -2992,6 +3003,7 @@ mod tests { let request_meta = RequestMeta::new(dsn); let mut envelope = Envelope::from_request(Some(event_id), request_meta); + let replay_id = Uuid::new_v4(); let test_dsc = DynamicSamplingContext { trace_id: Uuid::new_v4(), release: None, @@ -3004,7 +3016,7 @@ mod tests { transaction: None, sample_rate: None, other: BTreeMap::new(), - replay_id: Some(Uuid::new_v4()), + replay_id: Some(replay_id), }; envelope.set_dsc(test_dsc); @@ -3026,7 +3038,16 @@ mod tests { let new_envelope = ctx.envelope(); let item = new_envelope.items().next().unwrap(); - println!("{:?}", item); + + let annotated_event: Annotated = + Annotated::from_json_bytes(&item.payload()).unwrap(); + let event = annotated_event.into_value().unwrap(); + + let contexts = event.contexts.into_value().unwrap(); + let replay_context = contexts.get("replay").unwrap(); + let replay_str = replay_id.to_string().replace("-", ""); + let output = format!(r#"{{"replay_id":"{replay_str}","type":"replay"}}"#); + assert_eq!(output, replay_context.to_json().unwrap()); } #[tokio::test] From 5ac497825bfb791cb8f5e794c0cbac25fbca6a82 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Wed, 29 Mar 2023 17:55:52 -0700 Subject: [PATCH 04/19] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6344d78e012..724123b3ae7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ **Features** - Allow monitor checkins to paass `monitor_config` for monitor upserts. ([#1962](https://github.com/getsentry/relay/pull/1962)) +- Add replay_id onto event from dynamic sampling context. ([#1983](https://github.com/getsentry/relay/pull/1983)) ## 23.3.1 From 5df6a0ff5616fc35fc9274f882fa45ab803c80ef Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Wed, 29 Mar 2023 17:58:13 -0700 Subject: [PATCH 05/19] move comments --- relay-server/src/actors/processor.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 4f360cbc935..58855921945 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -1757,9 +1757,8 @@ impl EnvelopeProcessorService { // event id. To be defensive, we always overwrite to ensure consistency. event.id = Annotated::new(event_id); - // In processing mode, also write metrics into the event. Most metrics have already been - // collected at this state, except for the combined size of all attachments. if self.config.processing_enabled() { + // add the replay_id to the event's context if it exists on the DSC if let Some(dsc) = envelope.dsc() { if let Some(replay_id) = dsc.replay_id { let contexts = event.contexts.get_or_insert_with(Contexts::new); @@ -1769,6 +1768,8 @@ impl EnvelopeProcessorService { } } + // In processing mode, also write metrics into the event. Most metrics have already been + // collected at this state, except for the combined size of all attachments. let mut metrics = std::mem::take(&mut state.metrics); let attachment_size = envelope From 1ad3c4b4fdd06215694bf3c5dd2dc8670395e61b Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Wed, 29 Mar 2023 18:14:40 -0700 Subject: [PATCH 06/19] move logic into own function which is only used in processing --- relay-server/src/actors/processor.rs | 33 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 58855921945..9abe4ff1fb7 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -1757,19 +1757,9 @@ impl EnvelopeProcessorService { // event id. To be defensive, we always overwrite to ensure consistency. event.id = Annotated::new(event_id); + // In processing mode, also write metrics into the event. Most metrics have already been + // collected at this state, except for the combined size of all attachments. if self.config.processing_enabled() { - // add the replay_id to the event's context if it exists on the DSC - if let Some(dsc) = envelope.dsc() { - if let Some(replay_id) = dsc.replay_id { - let contexts = event.contexts.get_or_insert_with(Contexts::new); - contexts.add(SentryContext::Replay(Box::new(ReplayContext { - replay_id: Annotated::new(relay_general::protocol::EventId(replay_id)), - }))); - } - } - - // In processing mode, also write metrics into the event. Most metrics have already been - // collected at this state, except for the combined size of all attachments. let mut metrics = std::mem::take(&mut state.metrics); let attachment_size = envelope @@ -2178,6 +2168,22 @@ impl EnvelopeProcessorService { Ok(()) } + #[cfg(feature = "processing")] + /// Adds data from the DSC onto the event, only replay_id for now. + fn enrich_event_with_dsc(&self, state: &mut ProcessEnvelopeState) { + let envelope = state.managed_envelope.envelope_mut(); + + if let Some(event) = state.event.value_mut() { + if let Some(dsc) = envelope.dsc() { + if let Some(replay_id) = dsc.replay_id { + let contexts = event.contexts.get_or_insert_with(Contexts::new); + contexts.add(SentryContext::Replay(Box::new(ReplayContext { + replay_id: Annotated::new(relay_general::protocol::EventId(replay_id)), + }))); + } + } + } + } /// Run dynamic sampling rules to see if we keep the envelope or remove it. fn compute_sampling_decision(&self, state: &mut ProcessEnvelopeState) { state.sampling_result = utils::should_keep_event( @@ -2273,6 +2279,7 @@ impl EnvelopeProcessorService { if_processing!({ self.process_unreal(state)?; self.create_placeholders(state); + self.enrich_event_with_dsc(state); }); self.finalize_event(state)?; @@ -3046,7 +3053,7 @@ mod tests { let contexts = event.contexts.into_value().unwrap(); let replay_context = contexts.get("replay").unwrap(); - let replay_str = replay_id.to_string().replace("-", ""); + let replay_str = replay_id.to_string().replace('-', ""); let output = format!(r#"{{"replay_id":"{replay_str}","type":"replay"}}"#); assert_eq!(output, replay_context.to_json().unwrap()); } From b62b0f2947afaccbfb79fb70015fe2ab634bbc22 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Wed, 29 Mar 2023 18:18:46 -0700 Subject: [PATCH 07/19] fix import --- relay-server/src/actors/processor.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 9abe4ff1fb7..c39694a5986 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -21,9 +21,8 @@ use relay_general::pii::{PiiAttachmentsProcessor, PiiConfigError, PiiProcessor}; use relay_general::processor::{process_value, ProcessingState}; use relay_general::protocol::{ self, Breadcrumb, ClientReport, Csp, Event, EventType, ExpectCt, ExpectStaple, Hpkp, IpAddr, - LenientString, Metrics, RelayInfo, Replay, ReplayContext, ReplayError, SecurityReportType, - SessionAggregates, SessionAttributes, SessionStatus, SessionUpdate, Timestamp, UserReport, - Values, + LenientString, Metrics, RelayInfo, Replay, ReplayError, SecurityReportType, SessionAggregates, + SessionAttributes, SessionStatus, SessionUpdate, Timestamp, UserReport, Values, }; use relay_general::store::{ClockDriftProcessor, LightNormalizationConfig, TransactionNameConfig}; use relay_general::types::{Annotated, Array, FromValue, Object, ProcessingAction, Value}; @@ -45,7 +44,7 @@ use { crate::service::ServiceError, crate::utils::{EnvelopeLimiter, MetricsLimiter}, anyhow::Context, - relay_general::protocol::{Context as SentryContext, Contexts, ProfileContext}, + relay_general::protocol::{Context as SentryContext, Contexts, ProfileContext, ReplayContext}, relay_general::store::{GeoIpLookup, StoreConfig, StoreProcessor}, relay_quotas::{RateLimitingError, RedisRateLimiter}, symbolic_unreal::{Unreal4Error, Unreal4ErrorKind}, From 11180e9d58d078c428aa886288502929dad81e50 Mon Sep 17 00:00:00 2001 From: Josh Ferge Date: Thu, 30 Mar 2023 12:25:06 -0700 Subject: [PATCH 08/19] Update relay-sampling/src/lib.rs Co-authored-by: Oleksandr <1931331+olksdr@users.noreply.github.com> --- relay-sampling/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay-sampling/src/lib.rs b/relay-sampling/src/lib.rs index 6c6f9378542..36a8d5a7db3 100644 --- a/relay-sampling/src/lib.rs +++ b/relay-sampling/src/lib.rs @@ -1164,7 +1164,7 @@ pub struct DynamicSamplingContext { /// user object). #[serde(flatten, default)] pub user: TraceUserContext, - /// if the event occured during a session replay, the associated replay_id is added to the DSC + /// If the event occurred during a session replay, the associated replay_id is added to the DSC. pub replay_id: Option, /// Additional arbitrary fields for forwards compatibility. #[serde(flatten, default)] From 84e3b177c5a54e96c93894a20388710a01bd71a5 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Thu, 30 Mar 2023 12:36:04 -0700 Subject: [PATCH 09/19] add 'other' to replay context --- relay-general/src/protocol/contexts/replay.rs | 8 ++++++-- relay-server/src/actors/processor.rs | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/relay-general/src/protocol/contexts/replay.rs b/relay-general/src/protocol/contexts/replay.rs index 41c9026540b..a81a9948be2 100644 --- a/relay-general/src/protocol/contexts/replay.rs +++ b/relay-general/src/protocol/contexts/replay.rs @@ -1,13 +1,15 @@ use crate::protocol::EventId; -use crate::types::Annotated; +use crate::types::{Annotated, Object, Value}; /// Replay context #[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] #[cfg_attr(feature = "jsonschema", derive(JsonSchema))] pub struct ReplayContext { /// The replay ID. - #[metastructure(required = "true")] pub replay_id: Annotated, + /// Additional arbitrary fields for forwards compatibility. + #[metastructure(additional_properties, retain = "true")] + pub other: Object, } impl ReplayContext { @@ -30,6 +32,7 @@ mod tests { }"#; let context = Annotated::new(Context::Replay(Box::new(ReplayContext { replay_id: Annotated::new(EventId("4c79f60c11214eb38604f4ae0781bfb2".parse().unwrap())), + other: Object::default(), }))); assert_eq!(context, Annotated::from_json(json).unwrap()); @@ -44,6 +47,7 @@ mod tests { }"#; let context = Annotated::new(Context::Replay(Box::new(ReplayContext { replay_id: Annotated::new(EventId("4c79f60c11214eb38604f4ae0781bfb2".parse().unwrap())), + other: Object::default(), }))); assert_eq!(context, Annotated::from_json(json).unwrap()); diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 352f49070c1..cc4e8a4d63e 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -2178,6 +2178,7 @@ impl EnvelopeProcessorService { let contexts = event.contexts.get_or_insert_with(Contexts::new); contexts.add(SentryContext::Replay(Box::new(ReplayContext { replay_id: Annotated::new(relay_general::protocol::EventId(replay_id)), + other: Object::default(), }))); } } From 8037323dd575d75cea5269a1cf5250f264cdd3d9 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Thu, 30 Mar 2023 12:45:23 -0700 Subject: [PATCH 10/19] update snapshot --- .../tests/snapshots/test_fixtures__event_schema.snap | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/relay-general/tests/snapshots/test_fixtures__event_schema.snap b/relay-general/tests/snapshots/test_fixtures__event_schema.snap index 7d5e0c7dbbd..9852b92454a 100644 --- a/relay-general/tests/snapshots/test_fixtures__event_schema.snap +++ b/relay-general/tests/snapshots/test_fixtures__event_schema.snap @@ -2673,12 +2673,10 @@ expression: "relay_general::protocol::event_json_schema()" "anyOf": [ { "type": "object", - "required": [ - "replay_id" - ], "properties": { "replay_id": { "description": " The replay ID.", + "default": null, "anyOf": [ { "$ref": "#/definitions/EventId" From c4410e8135c4015b2629c86a7028035b517024f5 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Thu, 30 Mar 2023 12:55:49 -0700 Subject: [PATCH 11/19] only run replay test when processing is enabled --- relay-server/src/actors/processor.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index cc4e8a4d63e..55b358d2d4c 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -2990,6 +2990,7 @@ mod tests { } #[tokio::test] + #[cfg(feature = "processing")] async fn test_replay_id_added_from_dsc() { let config = Config::from_json_value(serde_json::json!({ "outcomes": { From a1ee0276f9a8f4160de8730574e4aac3f685f875 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Thu, 30 Mar 2023 13:02:02 -0700 Subject: [PATCH 12/19] fix import in tests --- relay-server/src/actors/processor.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 55b358d2d4c..14bc9376caf 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -2602,7 +2602,7 @@ mod tests { use relay_common::{Dsn, Uuid}; use relay_general::pii::{DataScrubbingConfig, PiiConfig}; use relay_general::protocol::EventId; - use relay_sampling::{RuleCondition, RuleId, RuleType, SamplingMode, TraceUserContext}; + use relay_sampling::{RuleCondition, RuleId, RuleType, SamplingMode}; use relay_test::mock_service; use similar_asserts::assert_eq; @@ -2612,6 +2612,9 @@ mod tests { use crate::testutils::{new_envelope, state_with_rule_and_condition}; use crate::utils::Semaphore as TestSemaphore; + #[cfg(feature = "processing")] + use relay_sampling::TraceUserContext; + struct TestProcessSessionArguments<'a> { item: Item, received: DateTime, From ac82f65bd1889ab9da563d79022e80c0f787b303 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Thu, 30 Mar 2023 13:08:20 -0700 Subject: [PATCH 13/19] fix more imports --- relay-server/src/actors/processor.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 14bc9376caf..13edc144db6 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -2599,7 +2599,7 @@ mod tests { use std::str::FromStr; use chrono::{DateTime, TimeZone, Utc}; - use relay_common::{Dsn, Uuid}; + use relay_general::pii::{DataScrubbingConfig, PiiConfig}; use relay_general::protocol::EventId; use relay_sampling::{RuleCondition, RuleId, RuleType, SamplingMode}; @@ -2613,7 +2613,10 @@ mod tests { use crate::utils::Semaphore as TestSemaphore; #[cfg(feature = "processing")] - use relay_sampling::TraceUserContext; + use { + relay_common::{Dsn, Uuid}, + relay_sampling::TraceUserContext, + }; struct TestProcessSessionArguments<'a> { item: Item, From 6cc8a20387b257e423baae400e9ab7c874554fd6 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Tue, 4 Apr 2023 12:37:30 -0700 Subject: [PATCH 14/19] move replay dsc logic to store normalization --- relay-general/benches/benchmarks.rs | 1 + relay-general/src/protocol/contexts/replay.rs | 2 +- .../src/store/.normalize.rs.pending-snap | 16 ++++ relay-general/src/store/mod.rs | 3 + relay-general/src/store/normalize.rs | 48 +++++++++++- relay-server/src/actors/processor.rs | 78 +------------------ 6 files changed, 69 insertions(+), 79 deletions(-) create mode 100644 relay-general/src/store/.normalize.rs.pending-snap diff --git a/relay-general/benches/benchmarks.rs b/relay-general/benches/benchmarks.rs index 092a9436632..34d59708d44 100644 --- a/relay-general/benches/benchmarks.rs +++ b/relay-general/benches/benchmarks.rs @@ -92,6 +92,7 @@ fn bench_store_processor(c: &mut Criterion) { breakdowns: None, span_attributes: Default::default(), client_sample_rate: None, + replay_id: None, client_hints: ClientHints::default(), }; diff --git a/relay-general/src/protocol/contexts/replay.rs b/relay-general/src/protocol/contexts/replay.rs index a81a9948be2..463bc1e3f8a 100644 --- a/relay-general/src/protocol/contexts/replay.rs +++ b/relay-general/src/protocol/contexts/replay.rs @@ -13,7 +13,7 @@ pub struct ReplayContext { } impl ReplayContext { - /// The key under which a replay context is generally stored (in `Contexts`) + /// The key under which a replay context is generally stored (in `Contexts`). pub fn default_key() -> &'static str { "replay" } diff --git a/relay-general/src/store/.normalize.rs.pending-snap b/relay-general/src/store/.normalize.rs.pending-snap new file mode 100644 index 00000000000..1689aecc9a4 --- /dev/null +++ b/relay-general/src/store/.normalize.rs.pending-snap @@ -0,0 +1,16 @@ +{"run_id":"1680635793-395237000","line":1501,"new":{"module_name":"relay_general__store__normalize__tests","snapshot_name":"replay_id_added_from_dsc","metadata":{"source":"relay-general/src/store/normalize.rs","assertion_line":1501,"expression":"event.contexts"},"snapshot":"~"},"old":{"module_name":"relay_general__store__normalize__tests","metadata":{},"snapshot":"Tags(\n PairList(\n [\n TagEntry(\n \"device.class\",\n \"2\",\n ),\n ],\n ),\n)"}} +{"run_id":"1680636747-15499000","line":2996,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2928,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2962,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2894,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2830,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2862,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2415,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2485,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2148,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2038,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2734,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2085,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2611,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2630,"new":null,"old":null} +{"run_id":"1680636747-15499000","line":2207,"new":null,"old":null} diff --git a/relay-general/src/store/mod.rs b/relay-general/src/store/mod.rs index be9ddd4a087..7182827e8a7 100644 --- a/relay-general/src/store/mod.rs +++ b/relay-general/src/store/mod.rs @@ -3,6 +3,7 @@ use std::collections::BTreeSet; use std::sync::Arc; use chrono::{DateTime, Utc}; +use relay_common::Uuid; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -66,6 +67,8 @@ pub struct StoreConfig { /// The SDK's sample rate as communicated via envelope headers. pub client_sample_rate: Option, + /// The replay_id associated with the current event communicated via envelope headers. + pub replay_id: Option, } /// The processor that normalizes events for store. diff --git a/relay-general/src/store/normalize.rs b/relay-general/src/store/normalize.rs index 5326be21aba..baba2911b6f 100644 --- a/relay-general/src/store/normalize.rs +++ b/relay-general/src/store/normalize.rs @@ -16,7 +16,8 @@ use crate::processor::{MaxChars, ProcessValue, ProcessingState, Processor}; use crate::protocol::{ self, AsPair, Breadcrumb, ClientSdkInfo, Context, Contexts, DebugImage, DeviceClass, Event, EventId, EventType, Exception, Frame, Headers, IpAddr, Level, LogEntry, Measurement, - Measurements, Request, SpanStatus, Stacktrace, Tags, TraceContext, User, VALID_PLATFORMS, + Measurements, ReplayContext, Request, SpanStatus, Stacktrace, Tags, TraceContext, User, + VALID_PLATFORMS, }; use crate::store::{ClockDriftProcessor, GeoIpLookup, StoreConfig, TransactionNameConfig}; use crate::types::{ @@ -199,6 +200,16 @@ impl<'a> NormalizeProcessor<'a> { } } } + fn normalize_replay_context(&self, event: &mut Event) { + if let Some(ref mut contexts) = event.contexts.value_mut() { + if let Some(replay_id) = self.config.replay_id { + contexts.add(Context::Replay(Box::new(ReplayContext { + replay_id: Annotated::new(EventId(replay_id)), + other: Object::default(), + }))); + } + } + } /// Infers the `EventType` from the event's interfaces. fn infer_event_type(&self, event: &Event) -> EventType { @@ -821,6 +832,7 @@ impl<'a> Processor for NormalizeProcessor<'a> { // Normalize connected attributes and interfaces self.normalize_spans(event); self.normalize_trace_context(event); + self.normalize_replay_context(event); Ok(()) } @@ -1123,6 +1135,7 @@ fn remove_logger_word(tokens: &mut Vec<&str>) { mod tests { use chrono::TimeZone; use insta::assert_debug_snapshot; + use relay_common::Uuid; use serde_json::json; use similar_asserts::assert_eq; @@ -1471,6 +1484,39 @@ mod tests { process_value(&mut event, &mut processor, ProcessingState::root()).unwrap(); assert_eq!(get_value!(event.environment), None); } + #[test] + fn test_replay_id_added_from_dsc() { + let replay_id = Uuid::new_v4(); + let mut event = Annotated::new(Event { + contexts: Annotated::new(Contexts(Object::new())), + ..Event::default() + }); + let config = StoreConfig { + replay_id: Some(replay_id), + ..StoreConfig::default() + }; + let mut processor = NormalizeProcessor::new(Arc::new(config), None); + let config = LightNormalizationConfig::default(); + light_normalize_event(&mut event, config).unwrap(); + process_value(&mut event, &mut processor, ProcessingState::root()).unwrap(); + + let event = event.value().unwrap(); + + assert_eq!( + event.contexts, + Annotated::new(Contexts({ + let mut contexts = Object::new(); + contexts.insert( + "replay".to_owned(), + Annotated::new(ContextInner(Context::Replay(Box::new(ReplayContext { + replay_id: Annotated::new(EventId(replay_id)), + other: Object::default(), + })))), + ); + contexts + })) + ) + } #[test] fn test_none_environment_errors() { diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 9b8dac08333..fcb3e5eb928 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -1890,6 +1890,7 @@ impl EnvelopeProcessorService { breakdowns: project_state.config.breakdowns_v2.clone(), span_attributes: project_state.config.span_attributes.clone(), client_sample_rate: envelope.dsc().and_then(|ctx| ctx.sample_rate), + replay_id: envelope.dsc().and_then(|ctx| ctx.replay_id), client_hints: envelope.meta().client_hints().to_owned(), }; @@ -2617,12 +2618,6 @@ mod tests { use crate::testutils::{new_envelope, state_with_rule_and_condition}; use crate::utils::Semaphore as TestSemaphore; - #[cfg(feature = "processing")] - use { - relay_common::{Dsn, Uuid}, - relay_sampling::TraceUserContext, - }; - struct TestProcessSessionArguments<'a> { item: Item, received: DateTime, @@ -3000,77 +2995,6 @@ mod tests { assert_eq!(new_envelope.items().next().unwrap().ty(), &ItemType::Event); } - #[tokio::test] - #[cfg(feature = "processing")] - async fn test_replay_id_added_from_dsc() { - let config = Config::from_json_value(serde_json::json!({ - "outcomes": { - "emit_outcomes": true, - "emit_client_outcomes": false, - }, - "processing": { - "enabled": true, - "kafka_config": [], - } - })) - .unwrap(); - let processor = create_test_processor(config); - let event_id = protocol::EventId::new(); - - let dsn: Dsn = "https://e12d836b15bb49d7bbf99e64295d995b:@sentry.io/42" - .parse() - .unwrap(); - - let request_meta = RequestMeta::new(dsn); - let mut envelope = Envelope::from_request(Some(event_id), request_meta); - - let replay_id = Uuid::new_v4(); - let test_dsc = DynamicSamplingContext { - trace_id: Uuid::new_v4(), - release: None, - environment: None, - user: TraceUserContext { - user_segment: "vip".to_string(), - user_id: "me".to_string(), - }, - public_key: ProjectKey::parse("a94ae32be2584e0bbd7a4cbb95971fee").unwrap(), - transaction: None, - sample_rate: None, - other: BTreeMap::new(), - replay_id: Some(replay_id), - }; - - envelope.set_dsc(test_dsc); - - envelope.add_item({ - let mut item = Item::new(ItemType::Event); - item.set_payload(ContentType::Json, r###"{"foo": "bar"}"###); - item - }); - - let message = ProcessEnvelope { - envelope: ManagedEnvelope::standalone(envelope), - project_state: Arc::new(ProjectState::allowed()), - sampling_project_state: None, - }; - - let envelope_response = processor.process(message).unwrap(); - let ctx = envelope_response.envelope.unwrap(); - let new_envelope = ctx.envelope(); - - let item = new_envelope.items().next().unwrap(); - - let annotated_event: Annotated = - Annotated::from_json_bytes(&item.payload()).unwrap(); - let event = annotated_event.into_value().unwrap(); - - let contexts = event.contexts.into_value().unwrap(); - let replay_context = contexts.get("replay").unwrap(); - let replay_str = replay_id.to_string().replace('-', ""); - let output = format!(r#"{{"replay_id":"{replay_str}","type":"replay"}}"#); - assert_eq!(output, replay_context.to_json().unwrap()); - } - #[tokio::test] async fn test_browser_version_extraction_with_pii_like_data() { let processor = create_test_processor(Default::default()); From f8e1fd817a9c702a5bc7f2af1bd9c2cb14b8d64e Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Tue, 4 Apr 2023 14:34:12 -0700 Subject: [PATCH 15/19] add more info for replay context --- relay-general/src/protocol/contexts/replay.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/relay-general/src/protocol/contexts/replay.rs b/relay-general/src/protocol/contexts/replay.rs index 463bc1e3f8a..4e57542a8c9 100644 --- a/relay-general/src/protocol/contexts/replay.rs +++ b/relay-general/src/protocol/contexts/replay.rs @@ -2,6 +2,12 @@ use crate::protocol::EventId; use crate::types::{Annotated, Object, Value}; /// Replay context +/// +/// The replay context contains the replay_id of the session replay if the event +/// occurred during a replay. The replay_id is added onto the dynamic sampling context +/// on the javascript SDK which propagates it through the trace. In relay, we take +/// this value from the DSC and create a context which contains only the replay_id +/// This context is never set on the client for events, only on relay. #[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] #[cfg_attr(feature = "jsonschema", derive(JsonSchema))] pub struct ReplayContext { From 2b15c273741a40b42527922c7911829f29d241ec Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Wed, 5 Apr 2023 12:18:54 -0700 Subject: [PATCH 16/19] delete unused function, fix snapshots --- .../src/store/.normalize.rs.pending-snap | 16 ---------------- .../snapshots/test_fixtures__event_schema.snap | 2 +- relay-server/src/actors/processor.rs | 18 ------------------ 3 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 relay-general/src/store/.normalize.rs.pending-snap diff --git a/relay-general/src/store/.normalize.rs.pending-snap b/relay-general/src/store/.normalize.rs.pending-snap deleted file mode 100644 index 1689aecc9a4..00000000000 --- a/relay-general/src/store/.normalize.rs.pending-snap +++ /dev/null @@ -1,16 +0,0 @@ -{"run_id":"1680635793-395237000","line":1501,"new":{"module_name":"relay_general__store__normalize__tests","snapshot_name":"replay_id_added_from_dsc","metadata":{"source":"relay-general/src/store/normalize.rs","assertion_line":1501,"expression":"event.contexts"},"snapshot":"~"},"old":{"module_name":"relay_general__store__normalize__tests","metadata":{},"snapshot":"Tags(\n PairList(\n [\n TagEntry(\n \"device.class\",\n \"2\",\n ),\n ],\n ),\n)"}} -{"run_id":"1680636747-15499000","line":2996,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2928,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2962,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2894,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2830,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2862,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2415,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2485,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2148,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2038,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2734,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2085,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2611,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2630,"new":null,"old":null} -{"run_id":"1680636747-15499000","line":2207,"new":null,"old":null} diff --git a/relay-general/tests/snapshots/test_fixtures__event_schema.snap b/relay-general/tests/snapshots/test_fixtures__event_schema.snap index 9852b92454a..ae65ff1296c 100644 --- a/relay-general/tests/snapshots/test_fixtures__event_schema.snap +++ b/relay-general/tests/snapshots/test_fixtures__event_schema.snap @@ -2669,7 +2669,7 @@ expression: "relay_general::protocol::event_json_schema()" "type": "string" }, "ReplayContext": { - "description": " Replay context", + "description": " Replay context\n\n The replay context contains the replay_id of the session replay if the event\n occurred during a replay. The replay_id is added onto the dynamic sampling context\n on the javascript SDK which propagates it through the trace. In relay, we take\n this value from the DSC and create a context which contains only the replay_id\n This context is never set on the client for events, only on relay.", "anyOf": [ { "type": "object", diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index fcb3e5eb928..72dd39a0d90 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -2168,23 +2168,6 @@ impl EnvelopeProcessorService { Ok(()) } - #[cfg(feature = "processing")] - /// Adds data from the DSC onto the event, only replay_id for now. - fn enrich_event_with_dsc(&self, state: &mut ProcessEnvelopeState) { - let envelope = state.managed_envelope.envelope_mut(); - - if let Some(event) = state.event.value_mut() { - if let Some(dsc) = envelope.dsc() { - if let Some(replay_id) = dsc.replay_id { - let contexts = event.contexts.get_or_insert_with(Contexts::new); - contexts.add(SentryContext::Replay(Box::new(ReplayContext { - replay_id: Annotated::new(relay_general::protocol::EventId(replay_id)), - other: Object::default(), - }))); - } - } - } - } /// Run dynamic sampling rules to see if we keep the envelope or remove it. fn compute_sampling_decision(&self, state: &mut ProcessEnvelopeState) { state.sampling_result = utils::should_keep_event( @@ -2284,7 +2267,6 @@ impl EnvelopeProcessorService { if_processing!({ self.process_unreal(state)?; self.create_placeholders(state); - self.enrich_event_with_dsc(state); }); self.finalize_event(state)?; From 18a26445c56524dc285bf6fbbd837695bd5c52b1 Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Wed, 5 Apr 2023 12:25:19 -0700 Subject: [PATCH 17/19] fix lint --- relay-server/src/actors/processor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay-server/src/actors/processor.rs b/relay-server/src/actors/processor.rs index 72dd39a0d90..0e7ec246603 100644 --- a/relay-server/src/actors/processor.rs +++ b/relay-server/src/actors/processor.rs @@ -44,7 +44,7 @@ use { crate::service::ServiceError, crate::utils::{EnvelopeLimiter, MetricsLimiter}, anyhow::Context, - relay_general::protocol::{Context as SentryContext, Contexts, ProfileContext, ReplayContext}, + relay_general::protocol::{Context as SentryContext, Contexts, ProfileContext}, relay_general::store::{GeoIpLookup, StoreConfig, StoreProcessor}, relay_quotas::{RateLimitingError, RedisRateLimiter}, symbolic_unreal::{Unreal4Error, Unreal4ErrorKind}, From 9b441fc46e31acacae145276ef9ab469ed07b259 Mon Sep 17 00:00:00 2001 From: Josh Ferge Date: Thu, 6 Apr 2023 13:59:15 -0700 Subject: [PATCH 18/19] Update relay-general/src/protocol/contexts/replay.rs Co-authored-by: Oleksandr <1931331+olksdr@users.noreply.github.com> --- relay-general/src/protocol/contexts/replay.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay-general/src/protocol/contexts/replay.rs b/relay-general/src/protocol/contexts/replay.rs index 4e57542a8c9..bfe92036c60 100644 --- a/relay-general/src/protocol/contexts/replay.rs +++ b/relay-general/src/protocol/contexts/replay.rs @@ -1,7 +1,7 @@ use crate::protocol::EventId; use crate::types::{Annotated, Object, Value}; -/// Replay context +/// Replay context. /// /// The replay context contains the replay_id of the session replay if the event /// occurred during a replay. The replay_id is added onto the dynamic sampling context From a81fb6d0bd2dbb20b138f181031a84ab09e4d85e Mon Sep 17 00:00:00 2001 From: Joshua Ferge Date: Thu, 6 Apr 2023 14:19:03 -0700 Subject: [PATCH 19/19] accept snapshots w/ period added --- relay-general/tests/snapshots/test_fixtures__event_schema.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay-general/tests/snapshots/test_fixtures__event_schema.snap b/relay-general/tests/snapshots/test_fixtures__event_schema.snap index ae65ff1296c..d17950e4c52 100644 --- a/relay-general/tests/snapshots/test_fixtures__event_schema.snap +++ b/relay-general/tests/snapshots/test_fixtures__event_schema.snap @@ -2669,7 +2669,7 @@ expression: "relay_general::protocol::event_json_schema()" "type": "string" }, "ReplayContext": { - "description": " Replay context\n\n The replay context contains the replay_id of the session replay if the event\n occurred during a replay. The replay_id is added onto the dynamic sampling context\n on the javascript SDK which propagates it through the trace. In relay, we take\n this value from the DSC and create a context which contains only the replay_id\n This context is never set on the client for events, only on relay.", + "description": " Replay context.\n\n The replay context contains the replay_id of the session replay if the event\n occurred during a replay. The replay_id is added onto the dynamic sampling context\n on the javascript SDK which propagates it through the trace. In relay, we take\n this value from the DSC and create a context which contains only the replay_id\n This context is never set on the client for events, only on relay.", "anyOf": [ { "type": "object",