Skip to content

fix(eap): Normalize segment names for standalone spans#6163

Open
loewenheim wants to merge 3 commits into
masterfrom
sebastian/normalize-segment-name
Open

fix(eap): Normalize segment names for standalone spans#6163
loewenheim wants to merge 3 commits into
masterfrom
sebastian/normalize-segment-name

Conversation

@loewenheim

Copy link
Copy Markdown
Contributor

In the legacy standalone span pipeline we run a normalization that scrubs unique identifiers out of transaction names and also applies rules from the project config to them. This PR enables the same normalization for the experimental V2 pipeline (but not for V2 spans in general).

ref: INGEST-943

@loewenheim loewenheim requested a review from a team as a code owner July 1, 2026 15:32
@linear-code

linear-code Bot commented Jul 1, 2026

Copy link
Copy Markdown

INGEST-943

@loewenheim loewenheim self-assigned this Jul 1, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2efc5b5. Configure here.

attributes
.0
.insert(SENTRY__SEGMENT__NAME.to_owned(), attribute);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate transaction left unnormalized

Medium Severity

normalize_segment_name only rewrites sentry.segment.name, while write_legacy_attributes skips copying into sentry.transaction when that key already exists. Legacy V1→V2 conversion can populate both from data and sentry_tags, so one attribute can stay high-cardinality while the other is scrubbed.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2efc5b5. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ughhh.

/// by running [`normalize_transaction_name`] on it.
///
/// This exists for parity with the legacy standalone span pipeline.
pub fn normalize_segment_name(

Copy link
Copy Markdown
Contributor Author

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> for normalize_transaction_name. Suggestions for improvements are very welcome.

// V2 span without a name it's just invalid.
infer_name: false,
clear_web_vital_segment_info: false,
..Default::default()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Default here instead of adding yet another false. I'm wondering if this normalization maybe should run for V2 spans though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.

}

assert spans_consumer.get_span() == {
"_meta": mock.ANY,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mocking the _meta here because it differs slightly between the legacy and V2 pipelines, in an uninteresting way (attributes in V2 have an extra level of nesting for the value).


// SENTRY__SEGMENT__NAME must exist and be a string.

let Some(annotated_attr) = attributes.remove(SENTRY__SEGMENT__NAME) else {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems easier if you just create a new temporary Annotated<String> and then later replace the value.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does. I think I was having tunnel vision about not cloning the existing value.

// V2 span without a name it's just invalid.
infer_name: false,
clear_web_vital_segment_info: false,
..Default::default()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.

@Dav1dde

Dav1dde commented Jul 2, 2026

Copy link
Copy Markdown
Member

I am also not sure if this is something we should port at all, this is likely just been put in place for the future but not relevant for web vitals (actual usage).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants