Skip to content

feat(attributes): Ensure replacements aren't deprecated#391

Merged
mjq merged 1 commit into
mainfrom
mjq/replacements-not-deprecated
May 20, 2026
Merged

feat(attributes): Ensure replacements aren't deprecated#391
mjq merged 1 commit into
mainfrom
mjq/replacements-not-deprecated

Conversation

@mjq
Copy link
Copy Markdown
Member

@mjq mjq commented May 19, 2026

When an attribute is deprecated, it should point to a non-deprecated replacement.

This should obviously be true for newly introduced deprecations, but is a tradeoff for the case where:

  • attribute A is deprecated and replaced by B
  • later, attribute B is deprecated and replaced by C

This would now cause a test failure, and A would need to also be updated to point to C instead of B.

However, on the plus side:

  • much easier to programatically translate or replace attribute with their latest replacement, since you don't have to follow a chain of attribute definitions
  • avoids the trap where a human sees a deprecated attribute and replaces it with the advertised replacement, not realizing that it's also deprecated

I think on the whole this is worth it.


🤖: Claude (Opus 4.6) used to write the test; validated by hand. All words my own.

When a field is deprecated, it should point to a non-deprecated replacement.

This should obviously be true for newly introduced deprecations, but is a tradeoff for the case where:
- field A is deprecated and replaced by B
- later, field B is deprecated and replaced by C

This would now cause a test failure, and A would need to be updated to point to C instead of B.

However, on the plus side:
- much easier to programatically translate or replace fields with their latest
  replacement, since you don't have to follow a chain of attribute definitions
- avoids the trap where a human sees a deprecated field and replaces it with
  the advertised replacement, not realizing that it's _also_ deprecated

I think on the whole this is worth it.

---

🤖: Claude (Opus 4.6) used to write the test; validated by hand. All words my
own.
@mjq mjq requested review from a team, Lms24, cleptric and nsdeschenes as code owners May 19, 2026 19:39
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Attributes

  • Ensure replacements aren't deprecated by mjq in #391
  • Add several measurement attributes by loewenheim in #362
  • Add gcp.function.context.* span attributes by chargome in #371
  • Add sentry.dsc.project_id as an attribute by constantinius in #358
  • Add trpc.* attributes by chargome in #370
  • Add angular.version attribute by chargome in #367
  • Add aws.lambda.* and aws.cloudwatch.logs.* attributes by chargome in #369
  • Add react.version attribute by chargome in #368
  • Add state.type attribute by chargome in #365
  • Add cloud.* span attributes by chargome in #364
  • Add calculated performance scores by loewenheim in #355
  • Add rpc.response.status_code attribute by alexander-alderman-webb in #352
  • Add rpc.method attribute by alexander-alderman-webb in #351
  • Add app vitals start attributes by buenaflor in #353
  • Add process.runtime.engine.* attributes by chargome in #347

Other

  • (docs) Add measurements page by Lms24 in #389
  • (measurements) Add attribute field by loewenheim in #388

Bug Fixes 🐛

Attributes

  • Correct PR references in attribute changelogs by chargome in #384
  • Increase some PII values by loewenheim in #373
  • Change several deprecation statuses to normalize to align with ingestion paths by constantinius in #350

Other

  • (create) Replace angle brackets in file names by loewenheim in #356

Internal Changes 🔧

Deps

  • Bump astro from 6.1.6 to 6.1.10 by dependabot in #374
  • Bump svelte from 5.53.5 to 5.55.7 by dependabot in #381

Other

  • (gh) Remove myself from CODEOWNERS by lcian in #354
  • Bump vulnerable pytest by alexander-alderman-webb in #360
  • Bump vulnerable js packages by chargome in #359

🤖 This preview updates automatically when you update the PR.

@mjq mjq changed the title feat: Ensure field replacements aren't deprecated feat(attributes): Ensure field replacements aren't deprecated May 19, 2026
@mjq mjq changed the title feat(attributes): Ensure field replacements aren't deprecated feat(attributes): Ensure replacements aren't deprecated May 19, 2026
Copy link
Copy Markdown
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

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

good new test, thanks! FYI @alexander-alderman-webb for gen_ai attributes

@mjq mjq merged commit eaf3721 into main May 20, 2026
19 checks passed
@mjq mjq deleted the mjq/replacements-not-deprecated branch May 20, 2026 15:53
mjq added a commit to getsentry/snuba that referenced this pull request May 21, 2026
Currently when EAP is queried via RPC for a particular attribute name,
the underlying query will coalesce that attribute name with any of its
deprecated aliases.

For example, given an attribute `A` that was deprecated in favour of
`B`, that was then deprecated in favour of `C`, querying for `C` will in
fact resolve to `coalesce(C, B, A)`. This helps keeps queries working
despite attribute deprecations.

_(Actually, the ordering of `B, A` is currently non-deterministic, but
this PR addresses that.)_

**However**, this requires that the caller always use the latest name
for an attribute - for example, a query for `A` would only search `A`,
and a query for `B` would only search `B`. Only `C` triggers the
coalescing. Our desired behaviour is that a search for any of `A`, `B`,
or `C` triggers a coalesced query on all aliases.

There are two possible approaches to take:

1. All RPC callers must use the `sentry-conventions` library to replace
attribute names with their latest non-deprecated alias before calling
EAP, or get inconsistent results.
2. Snuba always performs coalescing, for deprecated as well as
non-deprecated attributes.

Option 1 is challenging because of how Sentry's Alerts work, which store
RPC calls. Even if these calls use the latest attribute at creation
time, a later deprecation coming in would cause incorrect result until
they were recreated, and we would need to create a mechanism to do so
whenever Snuba's `sentry-conventions` library was updated. To avoid
duplicating the deprecated attribute logic in every caller and dealing
with this conventions/alerts coupling, I'm suggesting option 2, which
this PR implements.

Note the subtleties around **coalesce ordering**:
- The requested attribute is always first. This is the most consistent
option for end users and gives callers a bit of control over behaviour
for edge cases.
- If the requested attribute is deprecated, then its non-deprecated
alias is always second. We wouldn't want a deprecated alias taking
precedence over the current, non-deprecated one.
- Finally, all remaining deprecated aliases are listed in alphabetically
sorted order. This ordering is arbitrary because we don't store metadata
around the order in which fields are deprecated, but enforcing an
ordering is nonetheless important so that we don't get non-deterministic
results.

This PR also updates `sentry-conventions` to the latest version in order
to get getsentry/sentry-conventions#391 (ensures
that all deprecated attributes point to a non-deprecated replacement;
ensures that `_resolve_canonical` only ever has to make 1 hop).

---

🤖: Claude Code (Opus 4.6) used to generate the code, with human editing
+ review. All words my own.
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.

3 participants