-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Allow /metrics handler output filtering via name[] query param
#1925
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
base: main
Are you sure you want to change the base?
Conversation
da23a04 to
9bcabdc
Compare
9bcabdc to
80d1536
Compare
1c76a92 to
ba1b97a
Compare
/metrics handler output filtering via name[] query param
This forks the promhttp.Handler's code to serer/promhttpfork, and applies prometheus/client_golang#1925 on top of it. I'll remove the fork when it's merged and we can go back upstream. Signed-off-by: Oleg Zaytsev <[email protected]>
This commit adds support for filtering metrics by name using the name[] query parameter in HandlerForTransactional. Multiple metric names can be specified by providing the parameter multiple times. Example usage: /metrics?name[]=http_requests_total&name[]=process_cpu_seconds_total Implementation details: - Query parameters are parsed and converted to a map for O(1) lookup - Filtering happens inline during the encoding loop to avoid allocating a new slice - When no name[] parameters are provided, all metrics are returned (backward compatible) - When name[] parameters don't match any metrics, an empty response is returned with HTTP 200 Tests include: - Single and multiple metric filtering - Backward compatibility (no filter returns all) - Non-matching filters - Empty and duplicate values - Verification that transactional gather lifecycle is maintained Signed-off-by: Oleg Zaytsev <[email protected]>
ba1b97a to
11cda20
Compare
aknuds1
left a comment
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 lack experience with the code in question, but the new functionality looks sensible to me. Leaving some suggestions. Also, shouldn't there be a changelog entry?
Signed-off-by: Oleg Zaytsev <[email protected]>
Signed-off-by: Oleg Zaytsev <[email protected]>
Signed-off-by: Oleg Zaytsev <[email protected]>
aknuds1
left a comment
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.
LGTM, except I wonder if there shouldn't be a changelog entry. Thanks for applying my feedback :)
…s` endpoint filtering by `name[]` (#13746) <!-- Thanks for sending a pull request! Before submitting: 1. Read our CONTRIBUTING.md guide 2. Rebase your PR if it gets out of sync with main --> #### What this PR does Switches to a fork of `client_golang` that contains the PR prometheus/client_golang#1925 which supports `/metrics` endpoint handler filtering through the use of `name[]` query param. I added a test to make sure this functionality doesn't disappear in a possible future removal of this replace directive. Also updates the costattribution package as this version now has changes introduced by @duricanikolic in prometheus/client_golang#1902 #### Which issue(s) this PR fixes or relates to Fixes an internal issue #### Checklist - [x] Tests updated. - [ ] Documentation added. - [x] `CHANGELOG.md` updated - the order of entries should be `[CHANGE]`, `[FEATURE]`, `[ENHANCEMENT]`, `[BUGFIX]`. If changelog entry is not needed, please add the `changelog-not-needed` label to the PR. - [ ] [`about-versioning.md`](https://github.com/grafana/mimir/blob/main/docs/sources/mimir/configure/about-versioning.md) updated with experimental features. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Switch to a forked `client_golang` to add `/metrics` filtering via `name[]`, update cost-attribution validation and tests, adapt API usage, and bump `compress`. > > - **Server/HTTP metrics**: > - Enable metric filtering on `/metrics` via `name[]` query param (promhttp handler change). Added test `TestMetricsEndpointSupportsMetricFiltering`. > - **Dependencies**: > - Replace `github.com/prometheus/client_golang` with fork `github.com/colega/prometheus-client_golang` (pulls in filtering support) and vendor updates. > - Bump `github.com/klauspost/compress` to `v1.18.2` and vendor changes. > - **Cost attribution**: > - Simplify metric descriptor validation using `prometheus.Desc.Err()`; adjust error expectations in tests. > - **Integration tests client**: > - Adapt `LabelNames` to new `model.LabelNames` return type and convert to `[]string`. > - **Changelog**: > - Document `/metrics` filtering enhancement. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 94aa553. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Signed-off-by: Oleg Zaytsev <[email protected]>
Signed-off-by: Oleg Zaytsev <[email protected]>
|
Oh, right, sorry, I forgot about the CHANGELOG.md, updated now. |
Context
We have a huge application with thousands of metrics per pod, and we have a Prometheus instance that need to scrape a small subset of those metrics (5 to 10 metrics)
I've set up some relabeling rules, and it works great, but profiles say that this instance spends more than 50% of its CPU time just parsing openmetrics responses and dropping the metrics.
We could save some trees if there was a way to signal Prometheus that we just want a subset of them. I considered running a dumb nginx proxy that would strip out the unneeded metrics, but with native histograms being exposed in proto that won't be possible anymore, plus we'd still be spending precious CPU cycles encoding that response.
I have considered exposing those metrics on a different registry/handler, but:
What this PR does
This PR adds support for filtering metrics by name using the
name[]query parameter inHandlerForTransactional(and hence inHandlerForandpromhttp.DefaultHandler). The default behavior is unchanged.Related issue
I see this has been discussed already in #135
I don't see much consensus there, however I found out that this is something already implemented in
client_pythonref andclient_javaref through thename[]query param, so I hope there isn't much discussion about whether this is a good fit here.Example