Skip to content

feat: add outcomes to TraceItem#174

Merged
MeredithAnya merged 5 commits intomainfrom
meredith/EAP-384
Feb 12, 2026
Merged

feat: add outcomes to TraceItem#174
MeredithAnya merged 5 commits intomainfrom
meredith/EAP-384

Conversation

@MeredithAnya
Copy link
Member

@MeredithAnya MeredithAnya commented Feb 6, 2026

Adds Outcomes to the TraceItem which will have metadata like key_id and then a CategoryCount with the following fields:

  • data_category (uint32)
  • quantity (uint64)

A TraceItem can have multiple outcomes because there can be different quantity types. For example, Log items have outcomes in both the log_item and log_byte category, hence the need for multiple CategoryCounts.

🤖 Generated with Claude Code

Adds outcome tracking to trace items with data category, quantity, and key_id fields.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@MeredithAnya MeredithAnya requested a review from a team as a code owner February 6, 2026 20:50
@linear
Copy link

linear bot commented Feb 6, 2026

@github-actions
Copy link

github-actions bot commented Feb 6, 2026

The latest Buf updates on your PR. Results from workflow ci / buf-checks (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed⏩ skipped✅ passed✅ passedFeb 11, 2026, 6:45 PM

Changes message name from plural to singular since it represents a single outcome.
The field name item_outcomes remains plural as it's a repeated list.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@MeredithAnya MeredithAnya changed the title feat: add ItemOutcomes message to TraceItem feat: add item_outcomes to TraceItem Feb 6, 2026
Copy link
Member

@Dav1dde Dav1dde left a comment

Choose a reason for hiding this comment

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

Some context:

  • As a timestamp outcomes can use the received timestamp of the TraceItem.
  • The key id is needed for outcomes, we already do a decently good job to preserve the key id (e.g. for spans), so we want to keep this going.

Outcomes allow for more metadata to be attached, like event_id, remote_addr. These are currently not as important, but we should already decide what we want to do if we need to add more metadata to outcomes:

  1. We cannot add any more metadata
  2. We add more top-level fields to the trace item
  3. We change the schema and introduce a new version which introduces some name-spacing
  4. We change the schema now.

Since we do already have quite a few top level attributes, which are quite similar metadata to e.g. a remote_addr (the received timestamp), I think option 2) is an okay solution.


message ItemOutcome {
// DataCategory that defined in Relay
uint32 data_category = 1;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be an enum taken from the list of categories in the Relay package.

@Dav1dde should we extract this from Relay?

Copy link
Member Author

Choose a reason for hiding this comment

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

@phacops I was making the assumption we would validate the data category in the consumer itself

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's fine. I guess we also don't have a list of DataCategory in protobuf so what I'd want to do is not really possible yet. We'd have to make the list in protobuf first then replace it everywhere it's used instead of using the Python class to generate it or something.

Copy link
Member Author

Choose a reason for hiding this comment

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

@Dav1dde can we get a rust crate for the relay consts? so we can import the consts like we do in other places in snuba

Copy link
Member

Choose a reason for hiding this comment

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

In Relay, for outcomes, the data category is actually typed as u8 which leaves us with about 220 more data categories we can invent.

Currently the source of truth for data categories lives in Sentry, but also all of Sentry (and Relay for that matter) is built in a way that it needs to be able to deal with unknown datacategories (arbitrary numbers), so we could follow this approach also here and just use a number.

I think setting up code generation in Relay, to import into sentry-protos creates a weird dependency graph where sentry-protos depends on some Relay artifcat but Relay also depends on sentry-protos to produce data.

Is changing from u8/uint32 to an enum in protobuf a breaking change? If not we can start out as a number, then think about moving the source of truth for a data category into sentry-protos or some other schema repo.

Copy link
Member

@Dav1dde Dav1dde Feb 11, 2026

Choose a reason for hiding this comment

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

Maybe I misunderstood the question, @MeredithAnya would you like to use the rust artifact/list of datacateories just in the consumer to have some typing or also here in the protos?

If it's just about the consumer, the consumer needs to be able to deal with unknown data categories, as we don't want to have to update the consumer before introducing a new data category.

Copy link
Member Author

@MeredithAnya MeredithAnya Feb 11, 2026

Choose a reason for hiding this comment

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

Maybe I misunderstood the question, @MeredithAnya would you like to use the rust artifact/list of datacateories just in the consumer to have some typing or also here in the protos?

@Dav1dde I was talking about the consumers. Right now I want to enforce that the data categories we are creating accepted outcomes for are in the right subset, in getsentry outcomes consumer they are using it like

from sentry.constants import DataCategory

MIN_CATEGORY = min(DataCategory).value
MAX_CATEGORY = max(DataCategory).value
IGNORED_CATEGORIES = {DataCategory.SESSION}

where in sentry's constants.py the DataCategory is

DataCategory = sentry_relay.consts.DataCategory

Obviously I'd be doing this differently but right now snuba only has the ability to do this in the python consumers/ api logic with https://pypi.org/project/sentry-relay/

@phacops
Copy link
Collaborator

phacops commented Feb 11, 2026

Since we do already have quite a few top level attributes, which are quite similar metadata to e.g. a remote_addr (the received timestamp), I think option 2) is an okay solution.

I could see us add remote_addr but not yet another event_id (we have item_id for this).

@phacops
Copy link
Collaborator

phacops commented Feb 11, 2026

  • The key id is needed for outcomes

What's the use of the key_id? Does it change by DataCategory?

@MeredithAnya
Copy link
Member Author

Some context:

  • As a timestamp outcomes can use the received timestamp of the TraceItem.
  • The key id is needed for outcomes, we already do a decently good job to preserve the key id (e.g. for spans), so we want to keep this going.

Outcomes allow for more metadata to be attached, like event_id, remote_addr. These are currently not as important, but we should already decide what we want to do if we need to add more metadata to outcomes:

  1. We cannot add any more metadata
  2. We add more top-level fields to the trace item
  3. We change the schema and introduce a new version which introduces some name-spacing
  4. We change the schema now.

Since we do already have quite a few top level attributes, which are quite similar metadata to e.g. a remote_addr (the received timestamp), I think option 2) is an okay solution.

@Dav1dde @phacops decided to change the schema now to make Outcomes its own thing on the TraceItem so we can add other attributes later

@Dav1dde
Copy link
Member

Dav1dde commented Feb 11, 2026

What's the use of the key_id? Does it change by DataCategory?

key_id is the primary key of the DSN in the database table (yeah it is really not great), but it allows us to tie outcomes back to a DSN. It does not change by datacategory, it's more or less on the same level as project_id.

@Dav1dde @phacops decided to change the schema now to make Outcomes its own thing on the TraceItem so we can add other attributes later

This looks good, especially with the required on the category list, nice!

@MeredithAnya MeredithAnya changed the title feat: add item_outcomes to TraceItem feat: add outcomes to TraceItem Feb 12, 2026
@MeredithAnya MeredithAnya merged commit 87854f3 into main Feb 12, 2026
9 checks passed
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

Comments