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
This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite. Learn more
This PR adds a /metrics endpoint that serves Prometheus metrics in text format. It's implemented across three files: a new shared metrics_endpoint.rs module, registry/http.rs for the native HTTP path, and serverless.rs for the serverless path. Authentication uses constant-time bearer token comparison gated by two env vars.
Issues
Dead / unreachable code in registry/http.rs
The early return before actor lookup handles all Metrics routes:
This means FrameworkHttpRoute::Metrics => handle_metrics_fetch(&request) in the downstream match arm is unreachable. Calling the real handler there silently hides the invariant. Per the project convention (CLAUDE.md) of avoiding _ => catch-alls, this arm must exist for exhaustiveness — but it should signal the invariant explicitly:
FrameworkHttpRoute::Metrics => unreachable!("metrics handled before actor lookup"),
Missing WWW-Authenticate header on 401
RFC 7235 §3.1 requires a WWW-Authenticate header on 401 responses. Without it, some HTTP clients and scraper agents won't recognize the response as a bearer-auth challenge. Add:
WWW-Authenticate: Bearer realm="rivetkit-metrics"
Env vars read on every request
configured_metrics_token() calls std::env::var on every metrics request. Prometheus scrapers typically hit this every 15 seconds so the overhead is negligible in practice, but reading env vars in a hot path is an avoidable allocation. Consider caching with a OnceLock<Option<String>> at process startup, or at minimum document the behavior so future readers don't wonder.
Two-var opt-in can silently do nothing
If RIVETKIT_METRICS_ENABLED=1 is set but RIVETKIT_METRICS_TOKEN is missing or empty, the endpoint returns 403 "metrics not enabled" with no diagnostic. Operators may believe they configured it correctly but get no metrics. Consider a tracing::warn! at first request (or startup) when enabled but token is absent.
403 for disabled endpoint leaks existence
Returning 403 Forbidden when metrics are not configured tells scrapers the endpoint exists but is locked. 404 Not Found is more conservative if the intent is to hide the endpoint entirely when not configured. Worth an intentional decision either way.
Minor suggestions
bearer_token_from_authorization byte-slice approach.value.get(..6) is safe here because "bearer" is ASCII, but returns None on a multibyte boundary before position 6 rather than a parse failure. Using strip_prefix makes the intent clearer and removes the implicit byte count:
Content-type header key inconsistency.serverless.rs uses the raw string "content-type" while registry/http.rs uses http::header::CONTENT_TYPE.to_string(). Both work, but using the typed constant in both paths is more consistent.
What's good
Using subtle::ConstantTimeEq for token comparison is the right call — it prevents timing side-channels.
Separating auth/render logic into metrics_endpoint.rs and sharing it across both HTTP paths avoids duplicating the security-sensitive bits.
pub(crate) visibility on the module is appropriate.
The design requiring explicit opt-in (RIVETKIT_METRICS_ENABLED=1) before the endpoint activates is a good security default.
No tests
The PR checklist notes tests are missing. At minimum, unit tests for bearer_token_from_authorization and authorize_metrics_request in metrics_endpoint.rs would cover the auth boundary. Per CLAUDE.md, Rust tests belong in tests/ rather than inline #[cfg(test)] modules.
This PR is marked Draft — flagging the above before it moves to review.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Please include a summary of the changes and the related issue. Please also include relevant motivation and context.
Type of change
How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
Checklist: