Merge pull request #14705 from prometheus/owilliams/default-on
Some checks failed
CI / Go tests (push) Has been cancelled
CI / More Go tests (push) Has been cancelled
CI / Go tests with previous Go version (push) Has been cancelled
CI / UI tests (push) Has been cancelled
CI / Go tests on Windows (push) Has been cancelled
CI / Mixins tests (push) Has been cancelled
CI / Build Prometheus for common architectures (0) (push) Has been cancelled
CI / Build Prometheus for common architectures (1) (push) Has been cancelled
CI / Build Prometheus for common architectures (2) (push) Has been cancelled
CI / Build Prometheus for all architectures (0) (push) Has been cancelled
CI / Build Prometheus for all architectures (1) (push) Has been cancelled
CI / Build Prometheus for all architectures (10) (push) Has been cancelled
CI / Build Prometheus for all architectures (11) (push) Has been cancelled
CI / Build Prometheus for all architectures (2) (push) Has been cancelled
CI / Build Prometheus for all architectures (3) (push) Has been cancelled
CI / Build Prometheus for all architectures (4) (push) Has been cancelled
CI / Build Prometheus for all architectures (5) (push) Has been cancelled
CI / Build Prometheus for all architectures (6) (push) Has been cancelled
CI / Build Prometheus for all architectures (7) (push) Has been cancelled
CI / Build Prometheus for all architectures (8) (push) Has been cancelled
CI / Build Prometheus for all architectures (9) (push) Has been cancelled
CI / Check generated parser (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
CI / fuzzing (push) Has been cancelled
CI / codeql (push) Has been cancelled
CI / Report status of build Prometheus for all architectures (push) Has been cancelled
CI / Publish main branch artifacts (push) Has been cancelled
CI / Publish release artefacts (push) Has been cancelled
CI / Publish UI on npm Registry (push) Has been cancelled

utf8: enable utf-8 support by default
This commit is contained in:
Björn Rabenstein 2024-09-06 17:24:37 +02:00 committed by GitHub
commit 694d98032b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 69 additions and 33 deletions

View file

@ -101,6 +101,8 @@ var (
) )
func init() { func init() {
// This can be removed when the default validation scheme in common is updated.
model.NameValidationScheme = model.UTF8Validation
prometheus.MustRegister(versioncollector.NewCollector(strings.ReplaceAll(appName, "-", "_"))) prometheus.MustRegister(versioncollector.NewCollector(strings.ReplaceAll(appName, "-", "_")))
var err error var err error
@ -231,9 +233,6 @@ func (c *flagConfig) setFeatureListOptions(logger log.Logger) error {
case "promql-delayed-name-removal": case "promql-delayed-name-removal":
c.promqlEnableDelayedNameRemoval = true c.promqlEnableDelayedNameRemoval = true
level.Info(logger).Log("msg", "Experimental PromQL delayed name removal enabled.") level.Info(logger).Log("msg", "Experimental PromQL delayed name removal enabled.")
case "utf8-names":
model.NameValidationScheme = model.UTF8Validation
level.Info(logger).Log("msg", "Experimental UTF-8 support enabled")
case "": case "":
continue continue
default: default:

View file

@ -42,6 +42,11 @@ import (
"github.com/prometheus/prometheus/rules" "github.com/prometheus/prometheus/rules"
) )
func init() {
// This can be removed when the default validation scheme in common is updated.
model.NameValidationScheme = model.UTF8Validation
}
const startupTime = 10 * time.Second const startupTime = 10 * time.Second
var ( var (

View file

@ -62,6 +62,11 @@ import (
"github.com/prometheus/prometheus/util/documentcli" "github.com/prometheus/prometheus/util/documentcli"
) )
func init() {
// This can be removed when the default validation scheme in common is updated.
model.NameValidationScheme = model.UTF8Validation
}
const ( const (
successExitCode = 0 successExitCode = 0
failureExitCode = 1 failureExitCode = 1

View file

@ -31,12 +31,18 @@ import (
"testing" "testing"
"time" "time"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/model/rulefmt" "github.com/prometheus/prometheus/model/rulefmt"
) )
func init() {
// This can be removed when the default validation scheme in common is updated.
model.NameValidationScheme = model.UTF8Validation
}
var promtoolPath = os.Args[0] var promtoolPath = os.Args[0]
func TestMain(m *testing.M) { func TestMain(m *testing.M) {

View file

@ -774,10 +774,10 @@ func (c *ScrapeConfig) Validate(globalConfig GlobalConfig) error {
} }
switch globalConfig.MetricNameValidationScheme { switch globalConfig.MetricNameValidationScheme {
case "", LegacyValidationConfig: case LegacyValidationConfig:
case UTF8ValidationConfig: case "", UTF8ValidationConfig:
if model.NameValidationScheme != model.UTF8Validation { if model.NameValidationScheme != model.UTF8Validation {
return fmt.Errorf("utf8 name validation requested but feature not enabled via --enable-feature=utf8-names") panic("utf8 name validation requested but model.NameValidationScheme is not set to UTF8")
} }
default: default:
return fmt.Errorf("unknown name validation method specified, must be either 'legacy' or 'utf8', got %s", globalConfig.MetricNameValidationScheme) return fmt.Errorf("unknown name validation method specified, must be either 'legacy' or 'utf8', got %s", globalConfig.MetricNameValidationScheme)

View file

@ -62,6 +62,11 @@ import (
"github.com/prometheus/prometheus/util/testutil" "github.com/prometheus/prometheus/util/testutil"
) )
func init() {
// This can be removed when the default validation scheme in common is updated.
model.NameValidationScheme = model.UTF8Validation
}
func mustParseURL(u string) *config.URL { func mustParseURL(u string) *config.URL {
parsed, err := url.Parse(u) parsed, err := url.Parse(u)
if err != nil { if err != nil {
@ -2042,6 +2047,10 @@ var expectedErrors = []struct {
} }
func TestBadConfigs(t *testing.T) { func TestBadConfigs(t *testing.T) {
model.NameValidationScheme = model.LegacyValidation
defer func() {
model.NameValidationScheme = model.UTF8Validation
}()
for _, ee := range expectedErrors { for _, ee := range expectedErrors {
_, err := LoadFile("testdata/"+ee.filename, false, false, log.NewNopLogger()) _, err := LoadFile("testdata/"+ee.filename, false, false, log.NewNopLogger())
require.Error(t, err, "%s", ee.filename) require.Error(t, err, "%s", ee.filename)
@ -2051,6 +2060,10 @@ func TestBadConfigs(t *testing.T) {
} }
func TestBadStaticConfigsJSON(t *testing.T) { func TestBadStaticConfigsJSON(t *testing.T) {
model.NameValidationScheme = model.LegacyValidation
defer func() {
model.NameValidationScheme = model.UTF8Validation
}()
content, err := os.ReadFile("testdata/static_config.bad.json") content, err := os.ReadFile("testdata/static_config.bad.json")
require.NoError(t, err) require.NoError(t, err)
var tg targetgroup.Group var tg targetgroup.Group
@ -2059,6 +2072,10 @@ func TestBadStaticConfigsJSON(t *testing.T) {
} }
func TestBadStaticConfigsYML(t *testing.T) { func TestBadStaticConfigsYML(t *testing.T) {
model.NameValidationScheme = model.LegacyValidation
defer func() {
model.NameValidationScheme = model.UTF8Validation
}()
content, err := os.ReadFile("testdata/static_config.bad.yml") content, err := os.ReadFile("testdata/static_config.bad.yml")
require.NoError(t, err) require.NoError(t, err)
var tg targetgroup.Group var tg targetgroup.Group
@ -2323,17 +2340,17 @@ func TestScrapeConfigNameValidationSettings(t *testing.T) {
{ {
name: "global setting implies local settings", name: "global setting implies local settings",
inputFile: "scrape_config_global_validation_mode", inputFile: "scrape_config_global_validation_mode",
expectScheme: "utf8", expectScheme: "legacy",
}, },
{ {
name: "local setting", name: "local setting",
inputFile: "scrape_config_local_validation_mode", inputFile: "scrape_config_local_validation_mode",
expectScheme: "utf8", expectScheme: "legacy",
}, },
{ {
name: "local setting overrides global setting", name: "local setting overrides global setting",
inputFile: "scrape_config_local_global_validation_mode", inputFile: "scrape_config_local_global_validation_mode",
expectScheme: "legacy", expectScheme: "utf8",
}, },
} }

View file

@ -1,4 +1,6 @@
# Two scrape configs with the same job names are not allowed. # Two scrape configs with the same job names are not allowed.
global:
metric_name_validation_scheme: legacy
scrape_configs: scrape_configs:
- job_name: prometheus - job_name: prometheus
- job_name: service-x - job_name: service-x

View file

@ -1,3 +1,5 @@
global:
metric_name_validation_scheme: legacy
scrape_configs: scrape_configs:
- job_name: prometheus - job_name: prometheus
relabel_configs: relabel_configs:

View file

@ -1,4 +1,4 @@
global: global:
metric_name_validation_scheme: utf8 metric_name_validation_scheme: legacy
scrape_configs: scrape_configs:
- job_name: prometheus - job_name: prometheus

View file

@ -1,5 +1,5 @@
global: global:
metric_name_validation_scheme: utf8 metric_name_validation_scheme: legacy
scrape_configs: scrape_configs:
- job_name: prometheus - job_name: prometheus
metric_name_validation_scheme: legacy metric_name_validation_scheme: utf8

View file

@ -1,3 +1,3 @@
scrape_configs: scrape_configs:
- job_name: prometheus - job_name: prometheus
metric_name_validation_scheme: utf8 metric_name_validation_scheme: legacy

View file

@ -122,9 +122,9 @@ global:
[ keep_dropped_targets: <int> | default = 0 ] [ keep_dropped_targets: <int> | default = 0 ]
# Specifies the validation scheme for metric and label names. Either blank or # Specifies the validation scheme for metric and label names. Either blank or
# "legacy" for letters, numbers, colons, and underscores; or "utf8" for full # "utf8" for for full UTF-8 support, or "legacy" for letters, numbers, colons,
# UTF-8 support. # and underscores.
[ metric_name_validation_scheme <string> | default "legacy" ] [ metric_name_validation_scheme <string> | default "utf8" ]
runtime: runtime:
# Configure the Go garbage collector GOGC parameter # Configure the Go garbage collector GOGC parameter
@ -478,9 +478,9 @@ metric_relabel_configs:
[ keep_dropped_targets: <int> | default = 0 ] [ keep_dropped_targets: <int> | default = 0 ]
# Specifies the validation scheme for metric and label names. Either blank or # Specifies the validation scheme for metric and label names. Either blank or
# "legacy" for letters, numbers, colons, and underscores; or "utf8" for full # "utf8" for full UTF-8 support, or "legacy" for letters, numbers, colons, and
# UTF-8 support. # underscores.
[ metric_name_validation_scheme <string> | default "legacy" ] [ metric_name_validation_scheme <string> | default "utf8" ]
# Limit on total number of positive and negative buckets allowed in a single # Limit on total number of positive and negative buckets allowed in a single
# native histogram. The resolution of a histogram with more buckets will be # native histogram. The resolution of a histogram with more buckets will be

View file

@ -236,10 +236,3 @@ When enabled, Prometheus will change the way in which the `__name__` label is re
This allows optionally preserving the `__name__` label via the `label_replace` and `label_join` functions, and helps prevent the "vector cannot contain metrics with the same labelset" error, which can happen when applying a regex-matcher to the `__name__` label. This allows optionally preserving the `__name__` label via the `label_replace` and `label_join` functions, and helps prevent the "vector cannot contain metrics with the same labelset" error, which can happen when applying a regex-matcher to the `__name__` label.
## UTF-8 Name Support
`--enable-feature=utf8-names`
When enabled, changes the metric and label name validation scheme inside Prometheus to allow the full UTF-8 character set.
By itself, this flag does not enable the request of UTF-8 names via content negotiation.
Users will also have to set `metric_name_validation_scheme` in scrape configs to enable the feature either on the global config or on a per-scrape config basis.

View file

@ -45,6 +45,11 @@ import (
"github.com/prometheus/prometheus/util/testutil" "github.com/prometheus/prometheus/util/testutil"
) )
func init() {
// This can be removed when the default validation scheme in common is updated.
model.NameValidationScheme = model.UTF8Validation
}
func TestPopulateLabels(t *testing.T) { func TestPopulateLabels(t *testing.T) {
cases := []struct { cases := []struct {
in labels.Labels in labels.Labels

View file

@ -305,9 +305,9 @@ func (sp *scrapePool) restartLoops(reuseCache bool) {
mrc = sp.config.MetricRelabelConfigs mrc = sp.config.MetricRelabelConfigs
) )
validationScheme := model.LegacyValidation validationScheme := model.UTF8Validation
if sp.config.MetricNameValidationScheme == config.UTF8ValidationConfig { if sp.config.MetricNameValidationScheme == config.LegacyValidationConfig {
validationScheme = model.UTF8Validation validationScheme = model.LegacyValidation
} }
sp.targetMtx.Lock() sp.targetMtx.Lock()
@ -460,9 +460,9 @@ func (sp *scrapePool) sync(targets []*Target) {
scrapeClassicHistograms = sp.config.ScrapeClassicHistograms scrapeClassicHistograms = sp.config.ScrapeClassicHistograms
) )
validationScheme := model.LegacyValidation validationScheme := model.UTF8Validation
if sp.config.MetricNameValidationScheme == config.UTF8ValidationConfig { if sp.config.MetricNameValidationScheme == config.LegacyValidationConfig {
validationScheme = model.UTF8Validation validationScheme = model.LegacyValidation
} }
sp.targetMtx.Lock() sp.targetMtx.Lock()

View file

@ -1040,6 +1040,7 @@ func TestScrapeLoopSeriesAdded(t *testing.T) {
} }
func TestScrapeLoopFailWithInvalidLabelsAfterRelabel(t *testing.T) { func TestScrapeLoopFailWithInvalidLabelsAfterRelabel(t *testing.T) {
model.NameValidationScheme = model.LegacyValidation
s := teststorage.New(t) s := teststorage.New(t)
defer s.Close() defer s.Close()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@ -3768,6 +3769,7 @@ func testNativeHistogramMaxSchemaSet(t *testing.T, minBucketFactor string, expec
// Create a scrape loop with the HTTP server as the target. // Create a scrape loop with the HTTP server as the target.
configStr := fmt.Sprintf(` configStr := fmt.Sprintf(`
global: global:
metric_name_validation_scheme: legacy
scrape_interval: 1s scrape_interval: 1s
scrape_timeout: 1s scrape_timeout: 1s
scrape_configs: scrape_configs: