Skip to content

Conversation

@aknuds1
Copy link
Contributor

@aknuds1 aknuds1 commented Jul 1, 2025

Modify model.ValidationScheme to support encoding as YAML. To facilitate this, I add a default value for the type: UnsetValidation. I also add a String method to the type, for use in error messages etc (exemplified in IsValidMetricName).

The motivation is to consolidate Prometheus around model.ValidationScheme, dropping the duplicated representations config.LegacyValidationConfig and config.UTF8ValidationConfig. This will in turn facilitate moving Prometheus (and e.g. Grafana Mimir) off the deprecated model.NameValidationScheme global.

See prometheus/prometheus#16806 for reference, where I implement the consolidation around model.ValidationScheme.

Default value changing to UnsetValidation

From my testing, without changing the default value to UnsetValidation, you'll get LegacyValidation when YAML unmarshalling an empty string. This means you can't tell whether the user has set the validation scheme in a configuration file or not.

@aknuds1 aknuds1 requested a review from Copilot July 1, 2025 08:43
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 enhances ValidationScheme to support YAML encoding/decoding, introduces a default UnsetValidation, and adds a String method for human-readable output.

  • Adds UnsetValidation as the zero-value scheme and shifts existing constants
  • Implements String(), MarshalYAML(), and UnmarshalYAML() on ValidationScheme
  • Provides unit tests covering string conversion and YAML round‐trip behavior

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
model/metric.go Define UnsetValidation, implement String, YAML marshal/unmarshal, and add interface assertions
model/metric_test.go Add tests for default value, String(), MarshalYAML(), and UnmarshalYAML() behaviors
Comments suppressed due to low confidence (3)

model/metric.go:68

  • Introducing UnsetValidation shifts the numeric values of LegacyValidation and UTF8Validation, which may break existing consumers; consider assigning explicit values (e.g., LegacyValidation = 0, UTF8Validation = 1) or documenting the breaking change.
	UnsetValidation ValidationScheme = iota

model/metric.go:27

  • The code calls fmt.Errorf and fmt.Sprintf but fmt is not imported, causing a compile error; add import "fmt".
	"gopkg.in/yaml.v2"

model/metric.go:120

  • [nitpick] Relying on the pre-existing value of *s when the input is empty can be unclear; explicitly setting *s = UnsetValidation may improve readability and avoid unintended state retention.
	case "":

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
@aknuds1 aknuds1 force-pushed the arve/augment-validation-scheme branch from 7de91e0 to ec69d9c Compare July 1, 2025 09:13
@aknuds1 aknuds1 marked this pull request as ready for review July 1, 2025 09:13
@aknuds1 aknuds1 requested a review from juliusmh July 1, 2025 09:16
return utf8.ValidString(string(n))
default:
panic(fmt.Sprintf("Invalid name validation scheme requested: %d", NameValidationScheme))
panic(fmt.Sprintf("Invalid name validation scheme requested: %s", NameValidationScheme.String()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since we implement fmt.Stringer anyways

Suggested change
panic(fmt.Sprintf("Invalid name validation scheme requested: %s", NameValidationScheme.String()))
panic(fmt.Sprintf("Invalid name validation scheme requested: %v", NameValidationScheme))

Copy link
Contributor Author

@aknuds1 aknuds1 Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the change to %v though, %s is more specific and thus better IMO. There's no real benefit to dropping the .String() call, it just becomes implicit.

Copy link
Member

@jesusvazquez jesusvazquez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me, left a few questions, lets have a round with the answers and then i can have another look.

// conform to the original Prometheus character requirements described by
// MetricNameRE and LabelNameRE.
LegacyValidation ValidationScheme = iota
LegacyValidation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you check if the change of ordering here is going to cause any issues?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really a change of ordering is it, but a change of default, right? It's a breaking change if anyone depends on LegacyValidation being the default, but that's a bad idea since you can't tell whether the enum is set or not. I'm not sure how to figure out if this will break anyone, but I can try to search for cases in Prometheus and Mimir.

Copy link
Member

@jesusvazquez jesusvazquez Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but that's a bad idea since you can't tell whether the enum is set or not.

I see that now,. Well if you cant find a dependency in mimir or prom to the current default then I'm happy with this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jesusvazquez - I will try to look a bit.

Copy link
Contributor Author

@aknuds1 aknuds1 Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see anything breaking in Prometheus/Mimir from this change at least.

I also did some more testing, and found that YAML decoding depends on UnsetValidation being the default enum value. The reason being that when unmarshalling from an empty string, ValidationScheme.UnmarshalYAML isn't called, so you always get the default value. If LegacyValidation remains the default, you can't tell whether the user has configured the validation scheme or not in YAML.

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
@aknuds1 aknuds1 requested a review from bwplotka July 3, 2025 07:56
@aknuds1 aknuds1 merged commit 7f8b2a0 into main Jul 3, 2025
9 checks passed
@aknuds1 aknuds1 deleted the arve/augment-validation-scheme branch July 3, 2025 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants