Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

- Apply timestamp validations to transaction spans. ([#6005](https://github.com/getsentry/relay/pull/6005))
- Obtain PII values for `SpanData` fields from `sentry-conventions`. ([#5997](https://github.com/getsentry/relay/pull/5997))
- Add `sentry.dsc.transaction` and `sentry.dsc.trace_id` to all spans. ([#6001](https://github.com/getsentry/relay/pull/6001), [#6004](https://github.com/getsentry/relay/pull/6004), [#6008](https://github.com/getsentry/relay/pull/6008))
- Add `sentry.dsc.transaction`, `sentry.dsc.trace_id`, and `sentry.dsc.project_id` to all spans. ([#6001](https://github.com/getsentry/relay/pull/6001), [#6004](https://github.com/getsentry/relay/pull/6004), [#6008](https://github.com/getsentry/relay/pull/6008), [#6011](https://github.com/getsentry/relay/pull/6011))

## 26.5.0

Expand Down
1 change: 1 addition & 0 deletions relay-cabi/src/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ pub unsafe extern "C" fn relay_store_normalizer_normalize_event(
performance_issues_spans: Default::default(),
derive_trace_id: Default::default(),
dsc: None,
sampling_project_id: None,
};
normalize_event(&mut event, &normalization_config);

Expand Down
40 changes: 36 additions & 4 deletions relay-event-normalization/src/eap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::borrow::Cow;
use std::net::IpAddr;

use chrono::{DateTime, Utc};
use relay_base_schema::project::ProjectId;
use relay_common::time::UnixTimestamp;
use relay_conventions::attributes::*;
use relay_conventions::{AttributeInfo, WriteBehavior};
Expand Down Expand Up @@ -355,6 +356,7 @@ pub fn normalize_dsc(
attributes: &mut Annotated<Attributes>,
is_segment: &Annotated<bool>,
dsc: Option<&DynamicSamplingContext>,
project_id: Option<&ProjectId>,
Comment thread
elramen marked this conversation as resolved.
Outdated
) {
let Some(dsc) = dsc else { return };

Expand All @@ -369,6 +371,9 @@ pub fn normalize_dsc(
if let Some(transaction) = &dsc.transaction {
attributes.insert(SENTRY__DSC__TRANSACTION, transaction.clone());
}
if let Some(project_id) = project_id {
attributes.insert(SENTRY__DSC__PROJECT_ID, project_id.value() as i64);
Comment thread
elramen marked this conversation as resolved.
Outdated
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
}

if is_segment.value().is_some_and(|is_segment| *is_segment) {
attributes.insert(SENTRY__DSC__PUBLIC_KEY, dsc.public_key.to_string());
Expand Down Expand Up @@ -752,17 +757,26 @@ mod tests {
#[test]
fn test_normalize_dsc_child_span_no_dsc() {
let mut attributes = Annotated::empty();
normalize_dsc(&mut attributes, &Annotated::new(false), None);
normalize_dsc(&mut attributes, &Annotated::new(false), None, None);
assert!(attributes.value().is_none());
}

#[test]
fn test_normalize_dsc_child_span_no_transaction() {
let mut attributes = Annotated::empty();
let dsc = mock_dsc(None);
normalize_dsc(&mut attributes, &Annotated::new(false), Some(&dsc));
normalize_dsc(
&mut attributes,
&Annotated::new(false),
Some(&dsc),
Some(&ProjectId::new(42)),
);
assert_annotated_snapshot!(attributes, @r#"
{
"sentry.dsc.project_id": {
"type": "integer",
"value": 42
},
"sentry.dsc.trace_id": {
"type": "string",
"value": "67e5504410b1426f9247bb680e5fe0c8"
Expand All @@ -775,9 +789,18 @@ mod tests {
fn test_normalize_dsc_child_span() {
let mut attributes = Annotated::empty();
let dsc = mock_dsc(Some("/some/endpoint"));
normalize_dsc(&mut attributes, &Annotated::new(false), Some(&dsc));
normalize_dsc(
&mut attributes,
&Annotated::new(false),
Some(&dsc),
Some(&ProjectId::new(42)),
);
assert_annotated_snapshot!(attributes, @r#"
{
"sentry.dsc.project_id": {
"type": "integer",
"value": 42
},
"sentry.dsc.trace_id": {
"type": "string",
"value": "67e5504410b1426f9247bb680e5fe0c8"
Expand All @@ -794,9 +817,18 @@ mod tests {
fn test_normalize_dsc_segment() {
let mut attributes = Annotated::empty();
let dsc = mock_dsc(Some("/some/endpoint"));
normalize_dsc(&mut attributes, &Annotated::new(true), Some(&dsc));
normalize_dsc(
&mut attributes,
&Annotated::new(true),
Some(&dsc),
Some(&ProjectId::new(42)),
);
assert_annotated_snapshot!(attributes, @r#"
{
"sentry.dsc.project_id": {
"type": "integer",
"value": 42
},
"sentry.dsc.public_key": {
"type": "string",
"value": "12345678901234567890123456789012"
Expand Down
13 changes: 9 additions & 4 deletions relay-event-normalization/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use regex::Regex;
use relay_base_schema::metrics::{
DurationUnit, FractionUnit, MetricUnit, can_be_valid_metric_name,
};
use relay_base_schema::project::ProjectId;
use relay_conventions::attributes::{
APP__VITALS__START__COLD__VALUE, APP__VITALS__START__SCREEN, APP__VITALS__START__TYPE,
APP__VITALS__START__VALUE, APP__VITALS__START__WARM__VALUE, SCORE__TOTAL,
Expand Down Expand Up @@ -141,7 +142,7 @@ pub struct NormalizationConfig<'a> {
/// This is similar to `transaction_name_config`, but applies to span descriptions.
pub span_description_rules: Option<&'a Vec<SpanDescriptionRule>>,

/// Configuration for generating performance score measurements for web vitals
/// Configuration for generating performance score measurements for web vitals.
pub performance_score: Option<&'a PerformanceScoreConfig>,

/// Metadata for AI models including costs and context size.
Expand All @@ -165,7 +166,7 @@ pub struct NormalizationConfig<'a> {
/// It is persisted into the event payload for correlation.
pub replay_id: Option<Uuid>,

/// Controls list of hosts to be excluded from scrubbing
/// Controls list of hosts to be excluded from scrubbing.
pub span_allowed_hosts: &'a [String],

/// Rules to infer `span.op` from other span fields.
Expand All @@ -177,8 +178,11 @@ pub struct NormalizationConfig<'a> {
/// Should add a random trace ID to events that lack one.
pub derive_trace_id: bool,

/// Dynamic sampling context
/// Dynamic sampling context.
pub dsc: Option<&'a DynamicSamplingContext>,

/// The identifier of the project where the trace originated.
pub sampling_project_id: Option<&'a ProjectId>,
Comment thread
elramen marked this conversation as resolved.
Outdated
}

impl Default for NormalizationConfig<'_> {
Expand Down Expand Up @@ -215,6 +219,7 @@ impl Default for NormalizationConfig<'_> {
performance_issues_spans: Default::default(),
derive_trace_id: Default::default(),
dsc: None,
sampling_project_id: None,
}
}
}
Expand Down Expand Up @@ -347,7 +352,7 @@ fn normalize(event: &mut Event, meta: &mut Meta, config: &NormalizationConfig) {

if config.normalize_spans && event.ty.value() == Some(&EventType::Transaction) {
span::normalize_app_start_spans(event);
span::normalize_dsc_for_event_spans(event, config.dsc);
span::normalize_dsc_for_event_spans(event, config.dsc, config.sampling_project_id);
Comment thread
elramen marked this conversation as resolved.
Outdated
span::exclusive_time::compute_span_exclusive_time(event);
}

Expand Down
20 changes: 16 additions & 4 deletions relay-event-normalization/src/normalize/span/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Span normalization logic.

use regex::Regex;
use relay_conventions::attributes::{SENTRY__DSC__TRACE_ID, SENTRY__DSC__TRANSACTION};
use relay_base_schema::project::ProjectId;
use relay_conventions::attributes::*;
use relay_event_schema::protocol::{Event, SpanData, TraceContext};
use relay_protocol::{Annotated, Value};
use relay_sampling::DynamicSamplingContext;
Expand Down Expand Up @@ -61,14 +62,18 @@ 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<&DynamicSamplingContext>) {
pub fn normalize_dsc_for_event_spans(
event: &mut Event,
dsc: Option<&DynamicSamplingContext>,
project_id: Option<&ProjectId>,
Comment thread
elramen marked this conversation as resolved.
Outdated
) {
if let Some(ctx) = event.context_mut::<TraceContext>() {
normalize_dsc_for_span_data(&mut ctx.data, dsc);
normalize_dsc_for_span_data(&mut ctx.data, dsc, project_id);
}
if let Some(spans) = event.spans.value_mut() {
for span in spans {
if let Some(span) = span.value_mut() {
normalize_dsc_for_span_data(&mut span.data, dsc);
normalize_dsc_for_span_data(&mut span.data, dsc, project_id);
}
}
}
Expand All @@ -80,6 +85,7 @@ pub fn normalize_dsc_for_event_spans(event: &mut Event, dsc: Option<&DynamicSamp
pub fn normalize_dsc_for_span_data(
span_data: &mut Annotated<SpanData>,
dsc: Option<&DynamicSamplingContext>,
project_id: Option<&ProjectId>,
) {
Comment thread
elramen marked this conversation as resolved.
Outdated
let Some(dsc) = dsc else { return };

Expand All @@ -98,4 +104,10 @@ pub fn normalize_dsc_for_span_data(
Annotated::new(Value::String(transaction.clone())),
);
}
if let Some(project_id) = project_id {
data.other.insert(
SENTRY__DSC__PROJECT_ID.to_owned(),
Annotated::new(Value::U64(project_id.value())),
);
}
Comment thread
elramen marked this conversation as resolved.
Outdated
}
7 changes: 6 additions & 1 deletion relay-server/src/processing/legacy_spans/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::services::processor::ProcessingError;
use chrono::{DateTime, Utc};
use relay_base_schema::project::ProjectId;
use relay_event_normalization::span::{self, ai};
use relay_event_normalization::{
BorrowedSpanOpDefaults, ClientHints, CombinedMeasurementsConfig, FromUserAgentInfo,
Expand Down Expand Up @@ -58,6 +59,8 @@ pub struct NormalizeSpanConfig<'a> {
pub span_op_defaults: BorrowedSpanOpDefaults<'a>,
/// Dynamic sampling context from the envelope headers.
pub dsc: Option<&'a DynamicSamplingContext>,
/// Project ID of the project that started the trace.
pub sampling_project_id: Option<&'a ProjectId>,
}

fn set_segment_attributes(span: &mut Annotated<Span>) {
Expand Down Expand Up @@ -112,6 +115,7 @@ pub fn normalize(
geo_lookup,
span_op_defaults,
dsc,
sampling_project_id,
} = config;

set_segment_attributes(annotated_span);
Expand Down Expand Up @@ -211,7 +215,7 @@ pub fn normalize(

normalize_performance_score(span, *performance_score);

span::normalize_dsc_for_span_data(&mut span.data, *dsc);
span::normalize_dsc_for_span_data(&mut span.data, *dsc, *sampling_project_id);

ai::enrich_ai_span(span, *ai_model_metadata);

Expand Down Expand Up @@ -555,6 +559,7 @@ mod tests {
geo_lookup: &GEO_LOOKUP,
span_op_defaults: Default::default(),
dsc: None,
sampling_project_id: None,
}
}

Expand Down
3 changes: 3 additions & 0 deletions relay-server/src/processing/legacy_spans/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ pub fn normalize(
geo_lookup,
span_op_defaults: ctx.global_config.span_op_defaults.borrow(),
dsc: dsc.as_ref(),
sampling_project_id: ctx
.sampling_project_info
.and_then(|p| p.project_id.as_ref()),
};

spans.retain(
Expand Down
8 changes: 7 additions & 1 deletion relay-server/src/processing/spans/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,13 @@ fn normalize_span(
}
eap::normalize_user_agent(&mut span.attributes, client_ua_info);
eap::normalize_user_geo(&mut span.attributes, |ip| geo_lookup.lookup(ip));
eap::normalize_dsc(&mut span.attributes, &span.is_segment, dsc);
eap::normalize_dsc(
&mut span.attributes,
&span.is_segment,
dsc,
ctx.sampling_project_info
.and_then(|p| p.project_id.as_ref()),
);
if ctx.is_processing() {
eap::normalize_ai(&mut span.attributes, duration, model_metdata);
}
Expand Down
3 changes: 3 additions & 0 deletions relay-server/src/processing/utils/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ pub fn normalize(
.has_feature(Feature::PerformanceIssuesSpans),
derive_trace_id: project_info.has_feature(Feature::AddDefaultTraceID),
dsc: headers.dsc(),
sampling_project_id: ctx
.sampling_project_info
.and_then(|p| p.project_id.as_ref()),
};

metric!(timer(RelayTimers::EventProcessingNormalization), {
Expand Down
10 changes: 10 additions & 0 deletions tests/integration/test_ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ def test_ai_spans_example_transaction(
"type": "string",
"value": "generateText weather-chat",
},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -539,6 +540,7 @@ def test_ai_spans_example_transaction(
"type": "string",
"value": "generate_text gpt-4o",
},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -639,6 +641,7 @@ def test_ai_spans_example_transaction(
"value": "POST " "https://api.openai.com/v1/responses",
},
"sentry.domain": {"type": "string", "value": "*.openai.com"},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -735,6 +738,7 @@ def test_ai_spans_example_transaction(
"type": "string",
"value": "execute_tool getWeather",
},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -798,6 +802,7 @@ def test_ai_spans_example_transaction(
"value": "GET " "https://wttr.in/San%20Francisco",
},
"sentry.domain": {"type": "string", "value": "wttr.in"},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -887,6 +892,7 @@ def test_ai_spans_example_transaction(
"type": "string",
"value": "execute_tool getWeather",
},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -950,6 +956,7 @@ def test_ai_spans_example_transaction(
"value": "GET https://wttr.in/London",
},
"sentry.domain": {"type": "string", "value": "wttr.in"},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -1069,6 +1076,7 @@ def test_ai_spans_example_transaction(
"type": "string",
"value": "generate_text gpt-4o",
},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -1166,6 +1174,7 @@ def test_ai_spans_example_transaction(
"value": "POST " "https://api.openai.com/v1/responses",
},
"sentry.domain": {"type": "string", "value": "*.openai.com"},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down Expand Up @@ -1244,6 +1253,7 @@ def test_ai_spans_example_transaction(
"gen_ai.usage.output_tokens": {"type": "integer", "value": 65},
"gen_ai.usage.total_tokens": {"type": "double", "value": 310.0},
"sentry.description": {"type": "string", "value": "main"},
"sentry.dsc.project_id": {"type": "integer", "value": 42},
"sentry.dsc.trace_id": {
"type": "string",
"value": "a9351cd574f092f6acad48e250981f11",
Expand Down
Loading
Loading