-
Notifications
You must be signed in to change notification settings - Fork 121
fix(eap): Normalize segment names for standalone spans #6163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,10 @@ 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, FromUserAgentInfo as _, RawUserAgentInfo}; | ||
| use crate::{ | ||
| ClientHints, FromUserAgentInfo as _, RawUserAgentInfo, TransactionNameRule, | ||
| normalize_transaction_name, | ||
| }; | ||
|
|
||
| mod ai; | ||
| mod mobile; | ||
|
|
@@ -849,6 +852,32 @@ pub fn normalize_web_vital_span_segment(span: &mut SpanV2) { | |
| } | ||
| } | ||
|
|
||
| /// Normalize the [`SENTRY__SEGMENT__NAME`] attribute (aka the transaction) | ||
| /// by running [`normalize_transaction_name`] on it. | ||
| /// | ||
| /// This exists for parity with the legacy standalone span pipeline. | ||
| pub fn normalize_segment_name( | ||
| attributes: &mut Annotated<Attributes>, | ||
| tx_name_rules: &[TransactionNameRule], | ||
| ) { | ||
| let Some(attributes) = attributes.value_mut() else { | ||
| return; | ||
| }; | ||
|
|
||
| let Some(attr_value) = attributes.get_annotated_value_mut(SENTRY__SEGMENT__NAME) else { | ||
| return; | ||
| }; | ||
|
|
||
| let mut segment_name = match &attr_value.0 { | ||
| Some(Value::String(s)) => Annotated(Some(s.to_owned()), attr_value.1.clone()), | ||
| _ => return, | ||
| }; | ||
|
|
||
| normalize_transaction_name(&mut segment_name, tx_name_rules); | ||
|
|
||
| *attr_value = segment_name.map_value(Value::String); | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate transaction left unnormalizedMedium Severity
Additional Locations (1)Reviewed by Cursor Bugbot for commit 2efc5b5. Configure here.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ughhh. |
||
|
|
||
| /// Double writes sentry conventions attributes into legacy attributes. | ||
| /// | ||
| /// This achieves backwards compatibility as it allows products to continue using legacy attributes | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -113,10 +113,7 @@ fn expand_span_container(item: &Item) -> Result<(Settings, ContainerItems<SpanV2 | |
| infer_user_agent: is | ||
| .and_then(|is| is.infer_user_agent) | ||
| .is_some_and(|infer| infer.is_auto()), | ||
| // We don't want to infer names for V2 spans. If an SDK sent a | ||
| // V2 span without a name it's just invalid. | ||
| infer_name: false, | ||
| clear_web_vital_segment_info: false, | ||
| ..Default::default() | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's only add stuff when we actually need it, basically impossible to remove anything we add later on. |
||
| }, | ||
| // Unsupported, fall back to the safe default. | ||
| Some(_) => Default::default(), | ||
|
|
@@ -155,6 +152,9 @@ fn expand_legacy_spans( | |
| // We want to do this for V1 standalone spans for parity | ||
| // with the legacy pipeline. | ||
| clear_web_vital_segment_info: true, | ||
| // We want to do this for V1 standalone spans for parity | ||
| // with the legacy pipeline. | ||
| normalize_segment_name: true, | ||
| }; | ||
|
|
||
| (settings, spans) | ||
|
|
@@ -229,6 +229,7 @@ fn normalize_span( | |
| hints: meta.client_hints(), | ||
| }); | ||
| let performance_score = ctx.project_info.config().performance_score.as_ref(); | ||
| let tx_name_rules = &ctx.project_info.config.tx_name_rules; | ||
|
|
||
| validate_timestamps(span)?; | ||
|
|
||
|
|
@@ -241,6 +242,9 @@ fn normalize_span( | |
| if settings.clear_web_vital_segment_info { | ||
| eap::normalize_web_vital_span_segment(span); | ||
| } | ||
| if settings.normalize_segment_name { | ||
| eap::normalize_segment_name(&mut span.attributes, tx_name_rules); | ||
| } | ||
| eap::normalize_span_category(&mut span.attributes); | ||
| eap::normalize_received(&mut span.attributes, meta.received_at()); | ||
| eap::normalize_client_address(&mut span.attributes, meta.client_addr()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| from datetime import datetime, timezone | ||
| from unittest import mock | ||
|
|
||
| from sentry_sdk.envelope import Envelope, Item, PayloadRef | ||
|
|
||
|
|
@@ -165,7 +166,7 @@ def test_lcp_span( | |
| "release": "frontend@488531b11e6401fa530ac25554d44426e6ef0f0b", | ||
| "environment": "prod", | ||
| "replay_id": "3d76a6311de149b9b3f560827ea0ecf9", | ||
| "transaction": "/insights/projects/", | ||
| "transaction": "/insights/projects/b8686628-95f0-4be9-af6b-a98164504d8f", | ||
| "user_agent.original": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/42.0", | ||
| "client.address": "{{auto}}", | ||
| "sentry.exclusive_time": 0, | ||
|
|
@@ -212,6 +213,7 @@ def test_lcp_span( | |
| } | ||
|
|
||
| assert spans_consumer.get_span() == { | ||
| "_meta": mock.ANY, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm mocking the |
||
| "attributes": { | ||
| "client.address": {"type": "string", "value": "127.0.0.1"}, | ||
| "browser.web_vital.lcp.value": {"type": "double", "value": 548.0}, | ||
|
|
@@ -247,8 +249,8 @@ def test_lcp_span( | |
| "value": "3d76a6311de149b9b3f560827ea0ecf9", | ||
| }, | ||
| "sentry.report_event": {"type": "string", "value": "navigation"}, | ||
| "sentry.segment.name": {"type": "string", "value": "/insights/projects/"}, | ||
| "sentry.transaction": {"type": "string", "value": "/insights/projects/"}, | ||
| "sentry.segment.name": {"type": "string", "value": "/insights/projects/*"}, | ||
| "sentry.transaction": {"type": "string", "value": "/insights/projects/*"}, | ||
| "user_agent.original": { | ||
| "type": "string", | ||
| "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " | ||
|
|
@@ -375,7 +377,7 @@ def test_cls_span( | |
| "release": "frontend@488531b11e6401fa530ac25554d44426e6ef0f0b", | ||
| "environment": "prod", | ||
| "replay_id": "3d76a6311de149b9b3f560827ea0ecf9", | ||
| "transaction": "/insights/projects/", | ||
| "transaction": "/insights/projects/b8686628-95f0-4be9-af6b-a98164504d8f", | ||
| "user_agent.original": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/42.0", | ||
| "client.address": "{{auto}}", | ||
| "sentry.exclusive_time": 0, | ||
|
|
@@ -423,6 +425,7 @@ def test_cls_span( | |
| } | ||
|
|
||
| assert spans_consumer.get_span() == { | ||
| "_meta": mock.ANY, | ||
| "attributes": { | ||
| "client.address": {"type": "string", "value": "127.0.0.1"}, | ||
| "browser.web_vital.cls.value": {"type": "double", "value": 0.1}, | ||
|
|
@@ -463,8 +466,8 @@ def test_cls_span( | |
| "value": "3d76a6311de149b9b3f560827ea0ecf9", | ||
| }, | ||
| "sentry.report_event": {"type": "string", "value": "navigation"}, | ||
| "sentry.segment.name": {"type": "string", "value": "/insights/projects/"}, | ||
| "sentry.transaction": {"type": "string", "value": "/insights/projects/"}, | ||
| "sentry.segment.name": {"type": "string", "value": "/insights/projects/*"}, | ||
| "sentry.transaction": {"type": "string", "value": "/insights/projects/*"}, | ||
| "user_agent.original": { | ||
| "type": "string", | ||
| "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " | ||
|
|
@@ -590,7 +593,7 @@ def test_inp_span( | |
| "release": "frontend@488531b11e6401fa530ac25554d44426e6ef0f0b", | ||
| "environment": "prod", | ||
| "replay_id": "3d76a6311de149b9b3f560827ea0ecf9", | ||
| "transaction": "/insights/projects/", | ||
| "transaction": "/insights/projects/b8686628-95f0-4be9-af6b-a98164504d8f", | ||
| "user_agent.original": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/42.0", | ||
| "client.address": "{{auto}}", | ||
| "sentry.exclusive_time": 104, | ||
|
|
@@ -624,6 +627,7 @@ def test_inp_span( | |
| } | ||
|
|
||
| assert spans_consumer.get_span() == { | ||
| "_meta": mock.ANY, | ||
| "attributes": { | ||
| "client.address": {"type": "string", "value": "127.0.0.1"}, | ||
| "browser.web_vital.inp.value": {"type": "double", "value": 104.0}, | ||
|
|
@@ -653,8 +657,8 @@ def test_inp_span( | |
| "type": "string", | ||
| "value": "3d76a6311de149b9b3f560827ea0ecf9", | ||
| }, | ||
| "sentry.segment.name": {"type": "string", "value": "/insights/projects/"}, | ||
| "sentry.transaction": {"type": "string", "value": "/insights/projects/"}, | ||
| "sentry.segment.name": {"type": "string", "value": "/insights/projects/*"}, | ||
| "sentry.transaction": {"type": "string", "value": "/insights/projects/*"}, | ||
| "user_agent.original": { | ||
| "type": "string", | ||
| "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code in this function is tortous and ugly because I need to get from an attribute to an
Annotated<String>fornormalize_transaction_name. Suggestions for improvements are very welcome.