Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
4 changes: 0 additions & 4 deletions relay-dynamic-config/src/feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ pub enum Feature {
/// See <https://getsentry.github.io/objectstore/rust/objectstore_service/multipart/>.
#[serde(rename = "projects:relay-upload-multipart")]
UploadMultipart,
/// Enable relay billing outcome generation.
#[serde(rename = "organizations:relay-generate-billing-outcome")]
GenerateBillingOutcome,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Graduated billing flag not preserved

Medium Severity

Removing GenerateBillingOutcome without a deprecated serde variant or GRADUATED_FEATURE_FLAGS entry means organizations:relay-generate-billing-outcome deserializes as Unknown and is dropped from FeatureSet. Upstream Relays no longer retain or inject that flag in forwarded project configs, so older processing Relays that still gate track_accepted_outcome on it can stop emitting metric billing outcomes.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 69b1fb4. Configure here.

/// Enables OTLP spans to use the Span V2 processing pipeline in Relay.
///
/// This is now the default behaviour of Relay.
Expand Down
15 changes: 4 additions & 11 deletions relay-server/src/services/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,6 @@ impl EnvelopeProcessorService {
) {
use crate::constants::DEFAULT_EVENT_RETENTION;
use crate::services::store::StoreMetrics;
use relay_dynamic_config::Feature;

for ProjectBuckets {
buckets,
Expand All @@ -1213,16 +1212,10 @@ impl EnvelopeProcessorService {
continue;
}

if project_info
.config
.features
.has(Feature::GenerateBillingOutcome)
{
// Emit metric billing outcomes.
self.inner
.metric_outcomes
.track_accepted_outcome(scoping, &mut buckets);
}
// Emit metric billing outcomes.
self.inner
.metric_outcomes
.track_accepted_outcome(scoping, &mut buckets);

let retention = project_info
.config
Expand Down
12 changes: 10 additions & 2 deletions tests/integration/test_spans.py
Original file line number Diff line number Diff line change
Expand Up @@ -1100,8 +1100,16 @@ def test_discard_transaction(
spans = spans_consumer.get_spans(n=2)
assert len(spans) == 2

outcomes = outcomes_consumer.get_outcomes()
assert [(o["category"], o["outcome"], o["reason"]) for o in outcomes] == [
outcomes = outcomes_consumer.get_outcomes(n=3)

outcomes.sort(key=lambda o: o["outcome"])

# skip billing outcomes
assert outcomes[0]["outcome"] == 0
assert outcomes[1]["outcome"] == 0

o = outcomes[2]
assert [(o["category"], o["outcome"], o["reason"])] == [
(9, 1, "discarded"), # TransactionIndexed, Filtered
]
Comment on lines +1104 to 1114

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The test test_discard_transaction hardcodes an expectation of 3 outcomes, but 4 are now generated, causing an assertion failure in poll_many.
Severity: LOW

Suggested Fix

The test should be made more robust. Instead of fetching a hardcoded number of outcomes with get_outcomes(n=3), it should fetch all available outcomes without specifying n. Then, it should filter the results to find the specific outcome being tested or dynamically verify the total count. Sorting should also use a more stable key, like the outcome category, to avoid flakiness.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: tests/integration/test_spans.py#L1103-L1114

Potential issue: The test `test_discard_transaction` hardcodes an expectation for
exactly 3 outcomes by calling `outcomes_consumer.get_outcomes(n=3)`. However, due to the
removal of the `GenerateBillingOutcome` feature flag, `track_accepted_outcome` is now
always called. For the `envelope_with_transaction_and_spans` fixture, this change causes
4 outcomes to be generated: one for a non-segment child span, two for the segment span
(one `Span` and one `Transaction`), and one `TransactionIndexed` filtered outcome. The
`poll_many` method asserts that the number of received messages matches the requested
number `n`, which will fail with an error like "Expected 3 messages, only got 4".

Did we get this right? 👍 / 👎 to inform future reviews.


Expand Down
Loading