You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(profiles): Emit "accepted" outcomes for profiles filtered by sampling (#2054)
To facilitate a billing model that is consistent between transactions
and profiles, #2051 introduced a new data category for profiles, such
that
```
processed profiles = indexed profiles + sampled profiles # "sampled" as in dropped by dynamic sampling
```
just like it is already the case for transactions:
```
processed transactions = indexed transactions + sampled transactions
```
In other words, "processed profiles" should count _all_ valid, non rate
limited profiles seen by Relays, even if they were dropped by dynamic
sampling.
## Difference between transactions and profiles
For transactions, we extract _metrics_ before dynamic sampling, and
those metrics are what we rate limit and eventually log as "accepted"
for the "processed" transaction data category
(`DataCategory.Transaction`).
For profiles, we do not extract metrics (yet), so the outcomes for the
"processed" profile data category have to be calculated in a different
way.
## How this PR achieves this goal
1. In processing Relays, if an envelope still contains profiles _after_
dynamic sampling, log an `Accepted` outcome for the "processed"
category. By restricting this to processing Relays, we can be sure that
every profile is only counted once.
2. Also in processing Relays, shortly before reporting outcomes to
kafka,
2.1. translate `Filtered` outcomes with reason `Sampled:` to an
`Accepted` outcome. This counts all profiles dropped by dynamic
sampling, regardless of where the dynamic sampling took place (external
relay, pop relay, processing relay).
2.2. Also send the original `Filtered` outcome, but with data category
`DataCategory.TransactionIndexed`.
By adding up the counts of these two disjoint sets, we should correctly
count all profiles regardless of whether they were sampled or not.
## Alternative proposal (rejected for now)
In order to _actually_ line up behavior of transactions and profiles, we
could start extracting a simple counter metric for profiles before
dynamic sampling, and let that metric represent `DataCategory.Profile`
-- this would mean that rate limits are applied to the metric, and the
accepted outcome would be emitted from the `billing_metrics_consumer`,
just like we do for the `DataCategory.Transactions`. See [this internal
doc](https://www.notion.so/sentry/Implementation-Concerns-412caf18c2f04f579bb551b98c9dad8c)
for more.
## Why the currrent approach was chosen
I personally believe that the alternative proposal described above would
be more correct and easier to maintain, but:
1. By containing all new logic to processing relays, we will correctly
count "processed" profiles even if they were dropped by dynamic sampling
outdated external relays.
3. In a wider sense, by containing all new logic to processing relays,
we can iterate faster (deploy hotfixes, etc.) without having to worry
about the behavior of external relays (which we cannot update).
4. This change is easy to revert if needed. The alternative solution
would be distributed across nodes, from external relays to sentry.
0 commit comments