Rate limiting observability (metrics and tracing) PR B - #5800
Conversation
There was a problem hiding this comment.
Large PR Detected
This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.
How to unblock this PR:
Add a section to your PR description with the following format:
## Large PR Justification
[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformationAlternative:
Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.
See our Contributing Guidelines for more details.
This review will be automatically dismissed once you add the justification section.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5800 +/- ##
==========================================
- Coverage 71.32% 71.29% -0.04%
==========================================
Files 693 693
Lines 70587 70598 +11
==========================================
- Hits 50347 50332 -15
- Misses 16605 16631 +26
Partials 3635 3635 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Most of this diff is generated swagger docs, not your rate-limiting code. Likely cause: Can you rerun |
103b54a to
6d5de2e
Compare
6d5de2e to
9ff840f
Compare
Signed-off-by: Sanskarzz <sanskar.gur@gmail.com>
9ff840f to
e618f4b
Compare
Thanks, Jeremy. I reran task docs and reproduced the large Swagger-only diff locally. I also tested the pinned swag version from #5802, but my local run still rewrote generated schema names without any API change. |
aponcedeleonch
left a comment
There was a problem hiding this comment.
the change looks good but it needs a rebase 😄
|
Heads-up on an interaction with #6136 (fixes #6133), since we'd otherwise discover it after one of us merges. The overlap. #6136 makes the mutating webhook republish the parsed MCP request, because This PR moves telemetry to immediately after the parser. That puts telemetry outside the mutation, and republishing can't reach it there: a derived context only flows downstream, and Net effect once both land in this order: span names, No textual conflict. #6136 doesn't touch One option you may not have considered. The requirement here is a live span before the limiter runs, which you can get by moving the limiter later instead of telemetry earlier: The limiter's only stated constraint is the one in its own comment at But I'm not recommending it outright, because it has a real cost: rate-limited requests would then pay the webhook round-trips before being rejected. For a quota control that's backwards — outbound HTTP per rejected request is amplification on exactly the traffic you're shedding. If webhooks aren't configured it's free, but that's not something to rely on. So the alternative worth weighing is splitting span creation (early, so the limiter has something to annotate) from MCP attribute population (late, post-mutation) — If this merges first, #6136 will reconcile — I'd update the ordering list and the limitations bullet in If #6136 merges first (it's small, green, and fixes a live mis-authorization, whereas this one has changes requested), this PR would need those same four spots updated, plus a decision on the telemetry-accuracy question above. No action needed from you on #6136 itself — flagging so the second one through isn't a surprise. |
Summary
the existing request span with the normal allowed or rejected outcome.
values from its existing scope and operation dimensions.
active span, while preserving the existing vMCP core decorator composition.
document the span attribute contract.
Part of issue #4553
Type of change
Test plan
task test)task test-e2e)task lint-fix)Changes
pkg/ratelimit/limiter.gopkg/ratelimit/observability.gopkg/ratelimit/observability_test.gopkg/ratelimit/middleware_test.gopkg/runner/middleware.gopkg/runner/middleware_test.gopkg/vmcp/ratelimit/decorator_test.gopkg/vmcp/server/server.godocs/observability.mdDoes this introduce a user-facing change?
Yes. Traces for Redis-backed rate-limited tool calls now expose whether the
request was allowed or rejected and which bounded bucket type rejected it.
Rate-limit enforcement, responses, Redis keys, retry timing, and fail-open
behavior are unchanged.
Implementation plan
Approved implementation plan
decision branches; do not create a dedicated rate-limit span.
rate_limit.rejected_byfrom private scope and operation dimensionswithout expanding
Limiter,Decision, orRateLimitedError.request span is active at the limiter.
reference.
Special notes for reviewers
Redis failures intentionally receive no normal-outcome attributes in this PR:
the limiter cannot know whether its caller applies fail-open behavior. A
follow-up PR will add the fail-open counter and set
rate_limit.fail_open=trueat the shared enforcement adapter.