-
Notifications
You must be signed in to change notification settings - Fork 11
Parameterized metric/label name validation scheme #946
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
Conversation
ywwg
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.
this looks like a good approach. I have not looked at the relabel code before, it does seem like we will want to backport the new config to upstream prometheus. Does that sound right?
| // Action is the action to be performed for the relabeling. | ||
| Action Action `yaml:"action,omitempty" json:"action,omitempty"` | ||
| // MetricNameValidationScheme to use when validating labels. | ||
| MetricNameValidationScheme model.ValidationScheme `yaml:"-" json:"-"` |
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.
Oo I hadn't noticed this. If this is needed here then we probably want to do this in upstream prometheus as well, right?
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.
The idea is to upstream changes after we've battle tested them a bit in mimir-prometheus.
model/relabel/relabel.go
Outdated
| } | ||
| if c.Action == Replace && !varInRegexTemplate(c.TargetLabel) && !model.LabelName(c.TargetLabel).IsValid() { | ||
|
|
||
| if c.MetricNameValidationScheme == model.UnsetValidation { |
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.
See above. This check might not be necessary. If scheme is Unset, then IsValidLabelName below uses NameValidationScheme.
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 better to be robust I think. IsValidLabelName could always change to be less lenient.
a0a70e9 to
7fe8e08
Compare
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 it looks good at this point. Awaiting @dimitarvdimitrov's review though.
| node: &node.Record, | ||
| }) | ||
| } | ||
| if !model.IsValidMetricName(model.LabelValue(r.Record)) { |
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.
why not change the implementation of model.IsValidMetricName instead of creating a new function with the same name in a separate package?
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.
That would require changing prometheus/common/model.IsValidMetricName's signature wouldn't it? That would be a much more intrusive change, due to all the dependencies on prometheus/common/model.IsValidMetricName throughout the whole ecosystem.
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.
That would require changing
prometheus/common/model.IsValidMetricName's signature wouldn't it?
yes, but it would at least give us some safety. Right now nothing prevent something on the write path to use model.IsValidMetricName instead of labels.IsValidMetricName.
The alternative would be to ban the use of
model.IsValidmetricNameandmodel.LabelName.IsValid()in Prometheus, and always use the explicit functions instead together withUTF8Validation.
this sounds better. we should do the same in mimir too
Also it feels like labels.IsValidMetricName should be in model too, maybe named differently. Right now, it's a bit confusing which one you're supposed to use (or you have to wait for the linter to tell you you're using the wrong one)
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.
yes, but it would at least give us some safety.
We started out by doing that, but it required forking a lot of dependencies etc. Not sure how it would affect the greater ecosystem on top of that.
| // UTF-8 allows ${} characters, so standard validation allow $variables by default. | ||
| // TODO(bwplotka): Relabelling users cannot put $ and ${<...>} characters in metric names or values. | ||
| // Design escaping mechanism to allow that, once valid use case appears. | ||
| return model.LabelName(value).IsValid() |
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.
what about uses of the old model.IsValidmetricName and model.LabelName.IsValid()? Are you going to parametarize those too?
IMO having both globally-set and parametarized behaviours is confusing and will likely lead to bugs
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.
This is the compromise we came up with I'm afraid. The rationale is that only the write path is supposed to be configurable wrt. the name validation scheme, and we will otherwise always use the UTF-8 validation mode. The global variable is not supposed to be used, and it's deprecated (staticcheck catches if you use it).
The alternative would be to ban the use of model.IsValidmetricName and model.LabelName.IsValid() in Prometheus, and always use the explicit functions instead together with UTF8Validation.
79860ff to
0d9a872
Compare
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.
Pull Request Overview
This PR introduces parameterized metric/label name validation schemes throughout the Prometheus codebase. The changes allow different components to explicitly specify and use either legacy validation or UTF-8 validation for metric and label names, moving away from a global default validation scheme.
Key changes include:
- Addition of explicit
MetricNameValidationSchemefield to relabel configurations - New validation functions in the
labelspackage that accept validation scheme parameters - Updates to rule parsing to support configurable validation schemes through options
- Comprehensive test updates to specify validation schemes explicitly
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
model/labels/validate.go |
New validation functions that accept validation scheme parameters |
model/labels/validate_test.go |
Tests for the new parameterized validation functions |
model/relabel/relabel.go |
Added MetricNameValidationScheme field and updated validation logic |
model/relabel/relabel_test.go |
Updated tests to set validation schemes explicitly |
model/rulefmt/rulefmt.go |
Refactored parsing to accept validation scheme options |
model/rulefmt/rulefmt_test.go |
Updated tests to use new parsing API with options |
scrape/scrape.go |
Added validation scheme checks in scrape pool creation and reload |
scrape/scrape_test.go |
Set validation schemes in test configurations |
notifier/manager.go |
Added validation scheme handling for relabel configurations |
rules/manager.go |
Updated to use new rulefmt parsing API |
5dd1258 to
e835981
Compare
dimitarvdimitrov
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, we agreed you guys will add some linting to prevent using the model versions in favour of the parametarized labels versions
Thanks @dimitarvdimitrov, yes. Maybe as part of the upstreaming. |
|
Signed-off-by: Arve Knudsen <[email protected]>
Signed-off-by: Arve Knudsen <[email protected]>
Co-authored-by: Julius Hinze <[email protected]> Signed-off-by: Arve Knudsen <[email protected]>
Signed-off-by: Arve Knudsen <[email protected]>
Signed-off-by: Arve Knudsen <[email protected]>
…n to NewManager/ApplyConfig Signed-off-by: Arve Knudsen <[email protected]>
Signed-off-by: Arve Knudsen <[email protected]>
Signed-off-by: Arve Knudsen <[email protected]>
Signed-off-by: Arve Knudsen <[email protected]>
Signed-off-by: Arve Knudsen <[email protected]>
Signed-off-by: Arve Knudsen <[email protected]>
7ef6515 to
45de439
Compare
Signed-off-by: Arve Knudsen <[email protected]>
@dimitarvdimitrov Yes, making an upstreaming PR is next on my list. Already chatted a bit with @ywwg on potential improvements. |
#### What this PR does Direct and indirect references to the global name validation scheme were removed in favor of a per-tenant override. - Distributors have a validation middleware that ensures metric and label names are valid. - Rulers validate rule(group)s using this naming scheme. - Queriers use UTF8 validation *everywhere*. TODO: - [x] Reach consensus on whether `streamingpromqlcompat.NameValidatingEngine` is the right approach: Decided to do UTF8 validation in query path. - [x] Get Alertmanager updated with fix, stop using our own fork #### Which issue(s) this PR fixes or relates to Depends on - grafana/mimir-prometheus#946 - grafana/prometheus-alertmanager#116 Fixes: #11503 #### 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. --------- Signed-off-by: Julius Hinze <[email protected]> Co-authored-by: Arve Knudsen <[email protected]>
This PR introduces explicit APIs to set validation scheme for various components of prometheus.