feat(seer): Return custom attribute context from get_attribute_names - #121001
Open
DominikB2014 wants to merge 3 commits into
Open
Conversation
The RPC dropped user-authored attribute context: anything that wasn't a sentry convention or a Sentry-defined field was filtered out before reaching Seer, so custom attributes arrived with no descriptions. Route those attributes into a new `custom_fields` list instead. Keeping them out of `built_in_fields` preserves that list's meaning — attributes that are part of Sentry's schema — while custom context, which is specific to an organization, travels alongside it. Custom attributes without authored context are unchanged and appear only in `fields`. Context for these attributes is served by the /trace-items/attributes/ endpoint and gated behind data-browsing-attribute-context, so `custom_fields` is empty until an organization authors some. Refs BROWSE-596 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ttribute_names-rpc-return-custom-attribute-context
DominikB2014
marked this pull request as ready for review
July 31, 2026 20:29
DominikB2014
marked this pull request as draft
July 31, 2026 20:29
Contributor
Author
|
@cursor review |
DominikB2014
marked this pull request as ready for review
July 31, 2026 20:32
`custom_fields: list[BuiltInField]` contradicted itself, and the class name is not internal — the seer-side codegen reads each RPC's return annotation into a JSON-schema manifest, where it surfaces as `#/definitions/BuiltInField`. Rename to `AttributeMeta`, which fits both lists and stays accurate for the hardcoded built-ins that carry no context. The wire format is unchanged, since pydantic serializes field names rather than the class name. Also add the end-to-end coverage that was blocked on the endpoint change, now that #120994 has landed on master. Refs BROWSE-596 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
skaasten
self-requested a review
July 31, 2026 20:36
skaasten
approved these changes
Jul 31, 2026
| # This org has authored no context, so there are no custom fields. | ||
| assert result.custom_fields == [] | ||
|
|
||
| def test_get_attribute_names_with_custom_context(self) -> None: |
Contributor
There was a problem hiding this comment.
~ I'm surprised these tests are in a snuba api package - seems like they belong in a seer/rpc test namespace?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
get_attribute_namesdropped user-authored attribute context. Anything thatwasn't a sentry convention or a Sentry-defined field was filtered out before
reaching Seer:
So custom attributes reached the query agent with no descriptions, even once an
organization had described them.
This routes them into a new
custom_fieldslist, matching the shape inBROWSE-596:
{ "fields": { "string": ["span.op", "span.description", ...], "number": ["span.duration", ...] }, "built_in_fields": [ {"key": "span.op", "type": "string", "context": {...}}, {"key": "span.duration", "type": "number", "context": None}, ... ], "custom_fields": [ {"key": "custom_field_1", "type": "string", "context": {...}}, ... ] }Notes
built_in_fields: that listmeans "attributes that are part of Sentry's schema," and its context comes from
the conventions or a column definition. Custom context is specific to one
organization, so it travels alongside instead of blurring that distinction.
built_in_fieldsis unchanged — conventions and Sentry-defined attributesroute exactly as before.
only in
fields, as they always have.Dependency
Custom context is served by
/trace-items/attributes/via #120994 (BROWSE-595),which marks it
isCustom. Until that lands,custom_fieldsis always empty —this PR is safe to merge in either order but only does something once #120994 is
in. It's also gated behind
data-browsing-attribute-context, so it stays emptyuntil an organization authors context.
Seer reads
built_in_fieldstoday; picking upcustom_fieldsis a separatechange in the
seerrepo.Tests
New unit tests in
tests/sentry/seer/assisted_query/test_traces_tools.py(mocking
ApiClient, followingtest_metrics_tools.py) cover the routing:custom context →
custom_fields, number-typed custom context, Sentry-sourceattributes staying in
built_in_fields, and no context requested. Verified theyfail if the
custom_fieldsbranch is removed.I also merged #120994 locally and ran the two together to confirm authored
context makes it end-to-end from postgres through the endpoint into
custom_fields— 106 tests passed combined. That merge was reverted; this branchis off master.
Refs BROWSE-596