-
Notifications
You must be signed in to change notification settings - Fork 103
feat(spans): Correctly emit negative outcomes for rate limited transactions that have nested spans #3749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(spans): Correctly emit negative outcomes for rate limited transactions that have nested spans #3749
Conversation
…ctions that have nested spans
profile_chunks, | ||
} = self; | ||
|
||
let nested_spans = event.clone_for(DataCategory::Span, spans_length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case spans_length
is 0
, we will have both categories filtered out downstream since they won't be active
.
relay-server/src/services/project.rs
Outdated
.and_then(|i| serde_json::from_slice::<PartialEvent>(&i.payload()).ok()) | ||
.map_or(0, |p| p.spans.0) | ||
} else { | ||
0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not very nice, but I wanted to avoid unnecessary work in case the flag is not set.
tests/integration/test_spans.py
Outdated
|
||
@pytest.mark.parametrize( | ||
"category,raises_rate_limited", | ||
"category,hits_fast_path", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer the raises_rate_limit
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, will change it back. I have changed it because of a test refactor but I rolled it back.
relay-server/src/services/project.rs
Outdated
envelope_limiter.enforce(envelope.envelope_mut(), &scoping)?; | ||
|
||
if check_nested_spans { | ||
track_nested_spans_outcomes(&envelope, &enforcement, spans); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should integrate the new logic a little bit more with the Enforcement
, to prevent having multiple code paths that do similar things. It's a good call to not inject the span count into the envelope summary, but it could still be part of the Enforcement
. That is:
- Pass a flag into
enforce
to conditionally check for spans in the transaction item and setEnforcement::spans
. Enforcement::track_outcomes
automatically does the right thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could possibly pass the managed envelope and some options to the track_outcomes
and do it there, I preferred this at the moment, because track_outcomes
already does work correctly for rate limits with the envelope. Modifying it will affect both cached/non-cached rate limits.
Having track_outcomes
inspect the (managed) envelope seems like a footgun to me, since it is potentially built from completely different values than what the envelope contains (assume_event
).
Co-authored-by: Joris Bayer <[email protected]>
…getsentry/relay into riccardo/feat/rate-limiting-improvement
enforcement.track_outcomes( | ||
state.envelope(), | ||
&state.managed_envelope.scoping(), | ||
self.inner.addrs.outcome_aggregator.clone(), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's now done inside apply_with_outcomes
if enforcement.event_active() { | ||
state.remove_event(); | ||
debug_assert!(state.envelope().is_empty()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved up, since it requires enforcement which is consumed by the apply_with_outcomes
. I verified that the ordering doesn't seem to impact the end result.
/// Rate limiting information for a data category. | ||
#[derive(Debug)] | ||
struct CategoryLimit { | ||
#[cfg_attr(test, derive(Clone))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to have the clone()
in tests. Either we implement manually the Clone
in the tests or we go this route. Idk which would be preferred. The manual definition might be more verbose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine with me!
} | ||
} | ||
|
||
fn enforce_and_apply( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generalized all the code into this function, since I wanted tests to be leaner since a lot of repetition was there previously and some tests were also passing without calling the apply_with_outcomes
so to avoid that risk in the future, I decided to have everything into one.
let timestamp = relay_common::time::instant_to_date_time(envelope.meta().start_time()); | ||
let scoping = *scoping; | ||
let event_id = envelope.event_id(); | ||
let remote_addr = envelope.meta().remote_addr(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made sure the fields were all the same as the ones set by the track_outcome
of the ManagedEnvelope
.
( | ||
Outcome::RateLimited(limit.reason_code), | ||
limit.category, | ||
limit.quantity, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Felt like there was no need for a struct
assert_eq!(outcome.category, expected_category); | ||
assert_eq!(outcome.quantity, expected_quantity); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No python, nice!
/// Rate limiting information for a data category. | ||
#[derive(Debug)] | ||
struct CategoryLimit { | ||
#[cfg_attr(test, derive(Clone))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine with me!
Co-authored-by: Joris Bayer <[email protected]>
Co-authored-by: Joris Bayer <[email protected]>
/// to items in the envelope. This excludes rate limits applied to required attachments, since | ||
/// clients are allowed to continue sending them. | ||
/// | ||
/// # Example |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we keep these docs, they seem to be still relevant? We just don't drop the items anymore directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to rewrite them in the new function. Will do in a follow up.
* master: chore(dynamic-sampling): Remove metrics for dsc tracking (#3766) feat(web-vitals): add support for mobile browsers (#3762) feat(profiles): Support profiler_id in context (#3714) ref(normalization): Add origin and event_type tags to normalization decision (#3764) feat(rate-limiting): Add back docs with examples on rate limiting (#3761) feat(spans): Correctly emit negative outcomes for rate limited transactions that have nested spans (#3749) ref(metrics): Remove unused sentry extra data (#3758) feat(statsd): Emit tokio runtime metrics via statsd (#3755) ref(metrics): Aggregate metrics before rate limiting (#3746) ref(cogs): Remove unused metric, revert to released usage accountant (#3756) build(cargo): Update curve25519-dalek from 4.0.0 to 4.1.3 (#3745) test(deps): Bump requests from 2.31.0 to 2.32.2 (#3752)
This PR correctly emits negative outcomes for rate-limited transactions with nested spans by also emitting negative outcomes for the nested spans themselves.
Closes: #3705