Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Correctly handle minidump objecstore upload failures. ([#6033](https://github.com/getsentry/relay/pull/6033))
- Add `client.address` attribute to known IP fields. ([#6058](https://github.com/getsentry/relay/pull/6058))
- Fix a bug in mobile attribute normalization. ([#6065](https://github.com/getsentry/relay/pull/6065))
- Stop using cross-org DSC data in v2 span normalization. ([#6073](https://github.com/getsentry/relay/pull/6073))

**Internal**:

Expand Down
54 changes: 17 additions & 37 deletions relay-event-normalization/src/eap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use relay_conventions::attributes::*;
use relay_conventions::{AttributeInfo, ReplacementName, WriteBehavior};
use relay_event_schema::protocol::{Attribute, AttributeType, Attributes, BrowserContext, Geo};
use relay_protocol::{Annotated, Error, ErrorKind, Meta, Remark, RemarkType, Value};
use relay_sampling::DynamicSamplingContext;
use relay_spans::derive_op_for_v2_span;

use crate::span::TABLE_NAME_REGEX;
Expand All @@ -19,7 +20,7 @@ use crate::span::tag_extraction::{
domain_from_scrubbed_http, domain_from_server_address, span_op_to_category,
sql_action_from_query, sql_tables_from_query,
};
use crate::{ClientHints, EnrichedDsc, FromUserAgentInfo as _, RawUserAgentInfo};
use crate::{ClientHints, FromUserAgentInfo as _, RawUserAgentInfo};

mod ai;
mod mobile;
Expand Down Expand Up @@ -356,7 +357,7 @@ pub fn normalize_user_geo(
pub fn normalize_dsc(
attributes: &mut Annotated<Attributes>,
is_segment: &Annotated<bool>,
dsc: Option<EnrichedDsc>,
dsc: Option<&DynamicSamplingContext>,
) {
let Some(dsc) = dsc else {
return;
Expand All @@ -368,26 +369,28 @@ pub fn normalize_dsc(
if attributes.contains_key(SENTRY__DSC__TRACE_ID) {
return;
}
attributes.insert(SENTRY__DSC__TRACE_ID, dsc.dsc.trace_id.to_string());
attributes.insert(SENTRY__DSC__TRACE_ID, dsc.trace_id.to_string());

if let Some(transaction) = &dsc.dsc.transaction {
if let Some(transaction) = &dsc.transaction {
attributes.insert(SENTRY__DSC__TRANSACTION, transaction.clone());
}

attributes.insert(SENTRY__DSC__PROJECT_ID, dsc.sampling_project_id.to_string());
if let Some(project_id) = &dsc.project_id {
attributes.insert(SENTRY__DSC__PROJECT_ID, project_id.to_string());
}

if is_segment.value().is_some_and(|is_segment| *is_segment) {
attributes.insert(SENTRY__DSC__PUBLIC_KEY, dsc.dsc.public_key.to_string());
if let Some(release) = &dsc.dsc.release {
attributes.insert(SENTRY__DSC__PUBLIC_KEY, dsc.public_key.to_string());
if let Some(release) = &dsc.release {
attributes.insert(SENTRY__DSC__RELEASE, release.clone());
}
if let Some(environment) = &dsc.dsc.environment {
if let Some(environment) = &dsc.environment {
attributes.insert(SENTRY__DSC__ENVIRONMENT, environment.clone());
}
if let Some(sample_rate) = dsc.dsc.sample_rate {
if let Some(sample_rate) = dsc.sample_rate {
attributes.insert(SENTRY__DSC__SAMPLE_RATE, sample_rate);
}
if let Some(sampled) = dsc.dsc.sampled {
if let Some(sampled) = dsc.sampled {
attributes.insert(SENTRY__DSC__SAMPLED, sampled);
}
}
Expand Down Expand Up @@ -825,6 +828,7 @@ mod tests {
DynamicSamplingContext {
trace_id: "67e5504410b1426f9247bb680e5fe0c8".parse().unwrap(),
public_key: "12345678901234567890123456789012".parse().unwrap(),
project_id: Some(ProjectId::new(42)),
release: None,
environment: None,
transaction: transaction.map(str::to_owned),
Expand All @@ -847,15 +851,7 @@ mod tests {
fn test_normalize_dsc_child_span_no_transaction() {
let mut attributes = Annotated::empty();
let dsc = &mock_dsc(None);
let sampling_project_id = ProjectId::new(42);
normalize_dsc(
&mut attributes,
&Annotated::new(false),
Some(EnrichedDsc {
dsc,
sampling_project_id,
}),
);
normalize_dsc(&mut attributes, &Annotated::new(false), Some(dsc));
assert_annotated_snapshot!(attributes, @r#"
{
"sentry.dsc.project_id": {
Expand All @@ -874,15 +870,7 @@ mod tests {
fn test_normalize_dsc_child_span() {
let mut attributes = Annotated::empty();
let dsc = &mock_dsc(Some("/some/endpoint"));
let sampling_project_id = ProjectId::new(42);
normalize_dsc(
&mut attributes,
&Annotated::new(false),
Some(EnrichedDsc {
dsc,
sampling_project_id,
}),
);
normalize_dsc(&mut attributes, &Annotated::new(false), Some(dsc));
assert_annotated_snapshot!(attributes, @r#"
{
"sentry.dsc.project_id": {
Expand All @@ -905,15 +893,7 @@ mod tests {
fn test_normalize_dsc_segment() {
let mut attributes = Annotated::empty();
let dsc = &mock_dsc(Some("/some/endpoint"));
let sampling_project_id = ProjectId::new(42);
normalize_dsc(
&mut attributes,
&Annotated::new(true),
Some(EnrichedDsc {
dsc,
sampling_project_id,
}),
);
normalize_dsc(&mut attributes, &Annotated::new(true), Some(dsc));
assert_annotated_snapshot!(attributes, @r#"
{
"sentry.dsc.project_id": {
Expand Down
9 changes: 5 additions & 4 deletions relay-event-normalization/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use relay_protocol::{
Annotated, Empty, Error, ErrorKind, FiniteF64, FromValue, Getter, Meta, Object, Remark,
RemarkType, TryFromFloatError, Value,
};
use relay_sampling::DynamicSamplingContext;
use smallvec::SmallVec;
use uuid::Uuid;

Expand All @@ -41,8 +42,8 @@ use crate::span::ai::enrich_ai_event_data;
use crate::span::tag_extraction::{extract_segment_name_from_event, extract_span_tags_from_event};
use crate::utils::{self, MAX_DURATION_MOBILE_MS, get_event_user_tag};
use crate::{
BorrowedSpanOpDefaults, BreakdownsConfig, CombinedMeasurementsConfig, EnrichedDsc, GeoIpLookup,
MaxChars, ModelMetadata, PerformanceScoreConfig, RawUserAgentInfo, SpanDescriptionRule,
BorrowedSpanOpDefaults, BreakdownsConfig, CombinedMeasurementsConfig, GeoIpLookup, MaxChars,
ModelMetadata, PerformanceScoreConfig, RawUserAgentInfo, SpanDescriptionRule,
TransactionNameConfig, breakdowns, event_error, legacy, mechanism, remove_other, schema, span,
stacktrace, transactions, trimming, user_agent,
};
Expand Down Expand Up @@ -182,8 +183,8 @@ pub struct NormalizationConfig<'a> {
/// the SDK.
pub force_trace_context: bool,

/// Dynamic sampling context and additional attributes used for dsc span normalization.
pub dsc: Option<EnrichedDsc<'a>>,
/// Dynamic sampling context used for dsc span normalization.
pub dsc: Option<&'a DynamicSamplingContext>,
}

impl Default for NormalizationConfig<'_> {
Expand Down
11 changes: 0 additions & 11 deletions relay-event-normalization/src/normalize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ use std::{collections::HashMap, sync::LazyLock};

use regex::Regex;
use relay_base_schema::metrics::MetricUnit;
use relay_base_schema::project::ProjectId;
use relay_event_schema::protocol::VALID_PLATFORMS;
use relay_pattern::Pattern;
use relay_protocol::{FiniteF64, RuleCondition};
use relay_sampling::DynamicSamplingContext;
use serde::{Deserialize, Serialize};

pub mod breakdowns;
Expand Down Expand Up @@ -366,15 +364,6 @@ pub struct ModelMetadataEntry {
pub context_size: Option<u64>,
}

/// [`DynamicSamplingContext`] plus additional attributes used for dsc span normalization.
#[derive(Debug, Clone, Copy)]
pub struct EnrichedDsc<'a> {
/// Dynamic sampling context containing the trace id and root transaction that started the trace.
pub dsc: &'a DynamicSamplingContext,
/// ID of the project where the trace originated.
pub sampling_project_id: ProjectId,
}

#[cfg(test)]
mod tests {
use chrono::{TimeZone, Utc};
Expand Down
18 changes: 11 additions & 7 deletions relay-event-normalization/src/normalize/span/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
use regex::Regex;
use relay_event_schema::protocol::{Event, SpanData, TraceContext};
use relay_protocol::Annotated;
use relay_sampling::DynamicSamplingContext;
use std::sync::LazyLock;

use crate::EnrichedDsc;

pub mod ai;
pub mod country_subregion;
pub mod description;
Expand Down Expand Up @@ -61,7 +60,7 @@ pub fn normalize_app_start_spans(event: &mut Event) {
///
/// If `sentry.dsc.trace_id` is already present in a span's `data`, the function does nothing for
/// that span.
pub fn normalize_dsc_for_event_spans(event: &mut Event, dsc: Option<EnrichedDsc>) {
pub fn normalize_dsc_for_event_spans(event: &mut Event, dsc: Option<&DynamicSamplingContext>) {
if let Some(ctx) = event.context_mut::<TraceContext>() {
normalize_dsc_for_span_data(&mut ctx.data, dsc);
}
Expand All @@ -77,7 +76,10 @@ pub fn normalize_dsc_for_event_spans(event: &mut Event, dsc: Option<EnrichedDsc>
/// Writes DSC attributes needed for dynamic sampling into `span_data`.
///
/// If `sentry.dsc.trace_id` is already present in `span_data`, the function does nothing.
pub fn normalize_dsc_for_span_data(span_data: &mut Annotated<SpanData>, dsc: Option<EnrichedDsc>) {
pub fn normalize_dsc_for_span_data(
span_data: &mut Annotated<SpanData>,
dsc: Option<&DynamicSamplingContext>,
) {
let Some(dsc) = dsc else {
return;
};
Expand All @@ -86,9 +88,11 @@ pub fn normalize_dsc_for_span_data(span_data: &mut Annotated<SpanData>, dsc: Opt
if data.sentry_dsc_trace_id.value().is_some() {
return;
}
data.sentry_dsc_trace_id = Annotated::new(dsc.dsc.trace_id.to_string());
data.sentry_dsc_project_id = Annotated::new(dsc.sampling_project_id.to_string());
if let Some(transaction) = &dsc.dsc.transaction {
data.sentry_dsc_trace_id = Annotated::new(dsc.trace_id.to_string());
if let Some(project_id) = &dsc.project_id {
data.sentry_dsc_project_id = Annotated::new(project_id.to_string());
}
Comment thread
sentry[bot] marked this conversation as resolved.
if let Some(transaction) = &dsc.transaction {
data.sentry_dsc_transaction = Annotated::new(transaction.to_string());
}
}
12 changes: 11 additions & 1 deletion relay-sampling/src/dsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use std::collections::BTreeMap;
use std::fmt;

use relay_base_schema::project::ProjectKey;
use relay_base_schema::project::{ProjectId, ProjectKey};
use relay_event_schema::protocol::TraceId;
use relay_protocol::{Getter, Val};
use serde::{Deserialize, Serialize};
Expand All @@ -28,6 +28,13 @@ pub struct DynamicSamplingContext {
pub trace_id: TraceId,
/// The project key.
pub public_key: ProjectKey,
/// The sampling project id.
///
/// Not part of the DSC protocol, but accessed and used together with the rest of the DSC.
/// Placed here for ergonomy and to avoid having to mutate the request context when the sampling
/// org is different from the sending org.
#[serde(skip)]
pub project_id: Option<ProjectId>,
/// The release.
#[serde(default)]
pub release: Option<String>,
Expand Down Expand Up @@ -562,6 +569,7 @@ mod tests {
let dsc = DynamicSamplingContext {
trace_id: "67e5504410b1426f9247bb680e5fe0c8".parse().unwrap(),
public_key: ProjectKey::parse("abd0f232775f45feab79864e580d160b").unwrap(),
project_id: Some(ProjectId::new(42)),
release: Some("1.1.1".into()),
user: TraceUserContext {
user_segment: "user-seg".into(),
Expand Down Expand Up @@ -600,6 +608,7 @@ mod tests {
let dsc = DynamicSamplingContext {
trace_id: "67e5504410b1426f9247bb680e5fe0c8".parse().unwrap(),
public_key: ProjectKey::parse("abd0f232775f45feab79864e580d160b").unwrap(),
project_id: Some(ProjectId::new(42)),
release: None,
user: TraceUserContext::default(),
environment: None,
Expand All @@ -619,6 +628,7 @@ mod tests {
let dsc = DynamicSamplingContext {
trace_id: "67e5504410b1426f9247bb680e5fe0c8".parse().unwrap(),
public_key: ProjectKey::parse("abd0f232775f45feab79864e580d160b").unwrap(),
project_id: Some(ProjectId::new(42)),
release: None,
user: TraceUserContext::default(),
environment: None,
Expand Down
2 changes: 2 additions & 0 deletions relay-sampling/src/evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ impl fmt::Display for MatchedRuleIds {
#[cfg(test)]
mod tests {
use chrono::TimeZone;
use relay_base_schema::project::ProjectId;
use relay_protocol::RuleCondition;
use similar_asserts::assert_eq;
use std::str::FromStr;
Expand Down Expand Up @@ -299,6 +300,7 @@ mod tests {
let mut dsc = DynamicSamplingContext {
trace_id: "67e5504410b1426f9247bb680e5fe0c8".parse().unwrap(),
public_key: "12345678123456781234567812345678".parse().unwrap(),
project_id: Some(ProjectId::new(42)),
release: None,
environment: None,
transaction: None,
Expand Down
13 changes: 13 additions & 0 deletions relay-server/src/envelope/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,18 @@ impl<M> EnvelopeHeaders<M> {
}
}

/// Returns a mutable reference to the dynamic sampling context from the headers, if present.
pub fn dsc_mut(&mut self) -> Option<&mut DynamicSamplingContext> {
match &mut self.trace {
None => None,
Some(ErrorBoundary::Err(e)) => {
relay_log::debug!(error = e.as_ref(), "failed to parse sampling context");
None
}
Some(ErrorBoundary::Ok(t)) => Some(t),
}
}

/// Overrides the dynamic sampling context in envelope headers.
pub fn set_dsc(&mut self, dsc: DynamicSamplingContext) {
self.trace = Some(ErrorBoundary::Ok(dsc));
Expand Down Expand Up @@ -1243,6 +1255,7 @@ mod tests {
let dsc = DynamicSamplingContext {
trace_id: "67e5504410b1426f9247bb680e5fe0c8".parse().unwrap(),
public_key: ProjectKey::parse("abd0f232775f45feab79864e580d160b").unwrap(),
project_id: None,
release: Some("1.1.1".to_owned()),
user: Default::default(),
replay_id: None,
Expand Down
4 changes: 2 additions & 2 deletions relay-server/src/processing/legacy_spans/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use crate::services::processor::ProcessingError;
use chrono::{DateTime, Utc};
use relay_event_normalization::EnrichedDsc;
use relay_event_normalization::span::{self, ai};
use relay_event_normalization::{
BorrowedSpanOpDefaults, ClientHints, CombinedMeasurementsConfig, FromUserAgentInfo,
Expand All @@ -15,6 +14,7 @@ use relay_event_schema::processor::{ProcessingState, process_value};
use relay_event_schema::protocol::{BrowserContext, EventId, IpAddr, Span, SpanData};
use relay_metrics::UnixTimestamp;
use relay_protocol::{Annotated, Empty, Value};
use relay_sampling::DynamicSamplingContext;

/// Config needed to normalize a standalone span.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -57,7 +57,7 @@ pub struct NormalizeSpanConfig<'a> {
pub geo_lookup: &'a GeoIpLookup,
pub span_op_defaults: BorrowedSpanOpDefaults<'a>,
/// Dynamic sampling context plus additional attributes used for dsc span normalization.
pub dsc: Option<EnrichedDsc<'a>>,
pub dsc: Option<&'a DynamicSamplingContext>,
}

fn set_segment_attributes(span: &mut Annotated<Span>) {
Expand Down
24 changes: 9 additions & 15 deletions relay-server/src/processing/legacy_spans/process.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use relay_event_normalization::{
CombinedMeasurementsConfig, EnrichedDsc, GeoIpLookup, MeasurementsConfig,
};
use relay_event_normalization::{CombinedMeasurementsConfig, GeoIpLookup, MeasurementsConfig};
use relay_event_schema::processor::{ProcessingAction, ProcessingState, process_value};
use relay_event_schema::protocol::Span;
use relay_metrics::MetricNamespace;
Expand Down Expand Up @@ -46,18 +44,14 @@ pub fn normalize(
) {
let aggregator_config = ctx.config.aggregator_config_for(MetricNamespace::Spans);
let model_data = ctx.global_config.ai_model_metadata();
let sampling_project_id = ctx
let mut dsc = spans.headers.dsc().cloned();
let project_id = ctx
.sampling_project_info
.and_then(|p| p.project_id)
.or(ctx.project_info.project_id);
let dsc = spans.headers.dsc().cloned();
let dsc = dsc
.as_ref()
.zip(sampling_project_id)
.map(|(dsc, sampling_project_id)| EnrichedDsc {
dsc,
sampling_project_id,
});
.unwrap_or(ctx.project_info)
.project_id;
if let Some(dsc) = &mut dsc {
dsc.project_id = project_id;
}
Comment thread
elramen marked this conversation as resolved.
let norm = normalize::NormalizeSpanConfig {
received_at: spans.received_at(),
timestamp_range: aggregator_config.timestamp_range(),
Expand All @@ -79,7 +73,7 @@ pub fn normalize(
client_ip: spans.headers.meta().client_addr().map(Into::into),
geo_lookup,
span_op_defaults: ctx.global_config.span_op_defaults.borrow(),
dsc,
dsc: dsc.as_ref(),
};

spans.retain(
Expand Down
Loading
Loading