Skip to content

Commit

Permalink
feat(server): Serialize the DSC into event payloads (#3811)
Browse files Browse the repository at this point in the history
Serializes the full contents of the dynamic sampling context (DSC) into
the event payload as a hidden `_dsc` field. This allows for debugging of
dynamic sampling rules, sample rates, and all information passed along
by SDKs.

This runs exclusively in processing Relays at the very end of the
processing stage. Note that this may include _inferred_ DSCs from the
event payload under any of the following conditions:

- The client did not send a DSC
- The DSC originates from a different Sentry organization
  • Loading branch information
jan-auer committed Jul 11, 2024
1 parent 1ad9f6d commit bae3dc0
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- Copy root span data from `contexts.trace.data` when converting transaction events into raw spans. ([#3790](https://github.com/getsentry/relay/pull/3790))
- Remove experimental double-write from spans to transactions. ([#3801](https://github.com/getsentry/relay/pull/3801))
- Add feature flag to disable replay-video events. ([#3803](https://github.com/getsentry/relay/pull/3803))
- Write the envelope's Dynamic Sampling Context (DSC) into event payloads for debugging. ([#3811](https://github.com/getsentry/relay/pull/3811))

## 24.6.0

Expand Down
4 changes: 4 additions & 0 deletions relay-event-schema/src/protocol/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,10 @@ pub struct Event {
#[metastructure(omit_from_schema)]
pub _metrics_summary: Annotated<MetricsSummary>,

/// Value of the `DynamicSamplingContext` for this event.
#[metastructure(omit_from_schema)]
pub _dsc: Annotated<Value>,

/// Additional arbitrary fields for forwards compatibility.
#[metastructure(additional_properties, pii = "true")]
pub other: Object<Value>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,6 @@ Event {
scraping_attempts: ~,
_metrics: ~,
_metrics_summary: ~,
_dsc: ~,
other: {},
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,6 @@ Event {
scraping_attempts: ~,
_metrics: ~,
_metrics_summary: ~,
_dsc: ~,
other: {},
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,6 @@ Event {
scraping_attempts: ~,
_metrics: ~,
_metrics_summary: ~,
_dsc: ~,
other: {},
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,6 @@ Event {
scraping_attempts: ~,
_metrics: ~,
_metrics_summary: ~,
_dsc: ~,
other: {},
}
80 changes: 76 additions & 4 deletions relay-server/src/services/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3432,6 +3432,78 @@ mod tests {
);
}

#[tokio::test]
#[cfg(feature = "processing")]
async fn test_materialize_dsc() {
let dsn = "https://e12d836b15bb49d7bbf99e64295d995b:@sentry.io/42"
.parse()
.unwrap();
let request_meta = RequestMeta::new(dsn);
let mut envelope = Envelope::from_request(None, request_meta);

let dsc = r#"{
"trace_id": "00000000-0000-0000-0000-000000000000",
"public_key": "e12d836b15bb49d7bbf99e64295d995b",
"sample_rate": "0.2"
}"#;
envelope.set_dsc(serde_json::from_str(dsc).unwrap());

let mut item = Item::new(ItemType::Event);
item.set_payload(ContentType::Json, r#"{}"#);
envelope.add_item(item);

let (outcome_aggregator, test_store) = testutils::processor_services();
let managed_envelope = ManagedEnvelope::standalone(
envelope,
outcome_aggregator,
test_store,
ProcessingGroup::Error,
);

let process_message = ProcessEnvelope {
envelope: managed_envelope,
project_state: Arc::new(ProjectState::allowed()),
sampling_project_state: None,
reservoir_counters: ReservoirCounters::default(),
};

let config = Config::from_json_value(serde_json::json!({
"processing": {
"enabled": true,
"kafka_config": [],
}
}))
.unwrap();

let processor = create_test_processor(config);
let response = processor.process(process_message).unwrap();
let envelope = response.envelope.as_ref().unwrap().envelope();
let event = envelope
.get_item_by(|item| item.ty() == &ItemType::Event)
.unwrap();

let event = Annotated::<Event>::from_json_bytes(&event.payload()).unwrap();
insta::assert_debug_snapshot!(event.value().unwrap()._dsc, @r###"
Object(
{
"environment": ~,
"public_key": String(
"e12d836b15bb49d7bbf99e64295d995b",
),
"release": ~,
"replay_id": ~,
"sample_rate": String(
"0.2",
),
"trace_id": String(
"00000000-0000-0000-0000-000000000000",
),
"transaction": ~,
},
)
"###);
}

fn capture_test_event(transaction_name: &str, source: TransactionSource) -> Vec<String> {
let mut event = Annotated::<Event>::from_json(
r#"
Expand All @@ -3442,10 +3514,10 @@ mod tests {
"start_timestamp": 946684800.0,
"contexts": {
"trace": {
"trace_id": "4c79f60c11214eb38604f4ae0781bfb2",
"span_id": "fa90fdead5f74053",
"op": "http.server",
"type": "trace"
"trace_id": "4c79f60c11214eb38604f4ae0781bfb2",
"span_id": "fa90fdead5f74053",
"op": "http.server",
"type": "trace"
}
},
"transaction_info": {
Expand Down
6 changes: 6 additions & 0 deletions relay-server/src/services/processor/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ pub fn finalize<G: EventProcessing>(
);
}
}

if let Some(dsc) = envelope.dsc() {
if let Ok(Some(value)) = relay_protocol::to_value(dsc) {
event._dsc = Annotated::new(value);
}
}
}

let mut processor =
Expand Down

0 comments on commit bae3dc0

Please sign in to comment.