Skip to content

feat(seer): Return custom attribute context from get_attribute_names - #121001

Open
DominikB2014 wants to merge 3 commits into
masterfrom
dominikbuszowiecki/browse-596-update-get_attribute_names-rpc-return-custom-attribute-context
Open

feat(seer): Return custom attribute context from get_attribute_names#121001
DominikB2014 wants to merge 3 commits into
masterfrom
dominikbuszowiecki/browse-596-update-get_attribute_names-rpc-return-custom-attribute-context

Conversation

@DominikB2014

Copy link
Copy Markdown
Contributor

get_attribute_names dropped user-authored attribute context. Anything that
wasn't a sentry convention or a Sentry-defined field was filtered out before
reaching Seer:

# user-authored custom context is intentionally left out.
if not (context.get("isConvention") or source_by_name.get(name) == "sentry"):
    continue

So custom attributes reached the query agent with no descriptions, even once an
organization had described them.

This routes them into a new custom_fields list, matching the shape in
BROWSE-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

  • Why a separate list rather than appending to built_in_fields: that list
    means "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_fields is unchanged — conventions and Sentry-defined attributes
    route exactly as before.
  • Custom attributes without authored context are unchanged too: they appear
    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_fields is 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 empty
until an organization authors context.

Seer reads built_in_fields today; picking up custom_fields is a separate
change in the seer repo.

Tests

New unit tests in tests/sentry/seer/assisted_query/test_traces_tools.py
(mocking ApiClient, following test_metrics_tools.py) cover the routing:
custom context → custom_fields, number-typed custom context, Sentry-source
attributes staying in built_in_fields, and no context requested. Verified they
fail if the custom_fields branch 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 branch
is off master.

Refs BROWSE-596

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>
@linear-code

linear-code Bot commented Jul 31, 2026

Copy link
Copy Markdown

BROWSE-596

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jul 31, 2026
…ttribute_names-rpc-return-custom-attribute-context
@DominikB2014
DominikB2014 marked this pull request as ready for review July 31, 2026 20:29
@DominikB2014
DominikB2014 requested review from a team as code owners July 31, 2026 20:29
@DominikB2014
DominikB2014 marked this pull request as draft July 31, 2026 20:29
@DominikB2014

Copy link
Copy Markdown
Contributor Author

@cursor review

@DominikB2014
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
skaasten self-requested a review July 31, 2026 20:36
# 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:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

~ I'm surprised these tests are in a snuba api package - seems like they belong in a seer/rpc test namespace?

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

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants