Skip to content

Conversation

@juliusmh
Copy link
Contributor

This PR introduces explicit APIs to set validation scheme for various components of prometheus.

Copy link
Contributor

@ywwg ywwg left a 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:"-"`
Copy link
Contributor

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?

Copy link
Contributor

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.

}
if c.Action == Replace && !varInRegexTemplate(c.TargetLabel) && !model.LabelName(c.TargetLabel).IsValid() {

if c.MetricNameValidationScheme == model.UnsetValidation {
Copy link
Contributor Author

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.

Copy link
Contributor

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.

@aknuds1 aknuds1 force-pushed the arve/parameterized-name-validation branch from a0a70e9 to 7fe8e08 Compare July 23, 2025 13:29
Copy link
Contributor

@aknuds1 aknuds1 left a 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.

This comment was marked as outdated.

node: &node.Record,
})
}
if !model.IsValidMetricName(model.LabelValue(r.Record)) {
Copy link
Contributor

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?

Copy link
Contributor

@aknuds1 aknuds1 Jul 23, 2025

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.

Copy link
Contributor

@dimitarvdimitrov dimitarvdimitrov Jul 23, 2025

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.IsValidmetricName and model.LabelName.IsValid() in Prometheus, and always use the explicit functions instead together with UTF8Validation.

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)

Copy link
Contributor

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()
Copy link
Contributor

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

Copy link
Contributor

@aknuds1 aknuds1 Jul 23, 2025

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.

@aknuds1 aknuds1 force-pushed the arve/parameterized-name-validation branch from 79860ff to 0d9a872 Compare July 24, 2025 12:50
Copy link
Contributor

Copilot AI left a 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 MetricNameValidationScheme field to relabel configurations
  • New validation functions in the labels package 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

@aknuds1 aknuds1 force-pushed the arve/parameterized-name-validation branch from 5dd1258 to e835981 Compare July 24, 2025 13:49
Copy link
Contributor

@dimitarvdimitrov dimitarvdimitrov left a 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

@aknuds1
Copy link
Contributor

aknuds1 commented Jul 25, 2025

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.

@dimitarvdimitrov
Copy link
Contributor

Maybe as part of the upstreaming.
i thought you were starting to work on this? https://raintank-corp.slack.com/archives/C0909GTDAUV/p1753362194915909?thread_ts=1753358923.288489&cid=C0909GTDAUV

Signed-off-by: Arve Knudsen <[email protected]>
@aknuds1 aknuds1 force-pushed the arve/parameterized-name-validation branch from 7ef6515 to 45de439 Compare July 25, 2025 12:08
@aknuds1
Copy link
Contributor

aknuds1 commented Jul 25, 2025

thought you were starting to work on this?

@dimitarvdimitrov Yes, making an upstreaming PR is next on my list. Already chatted a bit with @ywwg on potential improvements.

@juliusmh juliusmh merged commit c4bd4fa into main Jul 25, 2025
13 checks passed
@juliusmh juliusmh deleted the arve/parameterized-name-validation branch July 25, 2025 12:33
juliusmh added a commit to grafana/mimir that referenced this pull request Jul 25, 2025
#### 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]>
aknuds1 added a commit that referenced this pull request Jul 28, 2025
…validation"

This reverts commit c4bd4fa, reversing
changes made to 6dd7af9.
aknuds1 added a commit that referenced this pull request Aug 4, 2025
…validation"

This reverts commit c4bd4fa, reversing
changes made to 6dd7af9.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants