diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bdc480d88d..5cae298ab77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * [FEATURE] Ruler: Add support for percentage based sharding for rulers. #6680 * [FEATURE] Ruler: Add support for group labels. #6665 * [FEATURE] Support Parquet format: Implement parquet converter service to convert a TSDB block into Parquet. #6716 +* [FEATURE] Config: Name validation scheme for metric and label names can be set using the config file (`name_validation_scheme`) as well as a CLI flag (`-name.validation_scheme`) * [ENHANCEMENT] Query Frontend: Change to return 400 when the tenant resolving fail. #6715 * [ENHANCEMENT] Querier: Support query parameters to metadata api (/api/v1/metadata) to allow user to limit metadata to return. #6681 * [ENHANCEMENT] Ingester: Add a `cortex_ingester_active_native_histogram_series` metric to track # of active NH series. #6695 @@ -40,6 +41,7 @@ * [BUGFIX] Ingester: Avoid resharding for query when restart readonly ingesters. #6642 * [BUGFIX] Query Frontend: Fix query frontend per `user` metrics clean up. #6698 + ## 1.19.0 2025-02-27 * [CHANGE] Deprecate `-blocks-storage.tsdb.wal-compression-enabled` flag (use `blocks-storage.tsdb.wal-compression-type` instead). #6529 diff --git a/docs/configuration/config-file-reference.md b/docs/configuration/config-file-reference.md index 93293edf82b..85518287c8e 100644 --- a/docs/configuration/config-file-reference.md +++ b/docs/configuration/config-file-reference.md @@ -68,6 +68,11 @@ Where default_value is the value to use if the environment variable is undefined # CLI flag: -http.prefix [http_prefix: | default = "/api/prom"] +# Validation scheme for metric and label names. Set to utf8 to allow UTF-8 characters. +# Set to legacy as default +# CLI flag: -name.validation_scheme +[name_validation_scheme: | default = "legacy"] + # Comma-separated list of resources to monitor. Supported values are cpu and # heap, which tracks metrics from github.com/prometheus/procfs and # runtime/metrics that are close estimates. Empty string to disable. diff --git a/pkg/cortex/configinit/init.go b/pkg/cortex/configinit/init.go deleted file mode 100644 index 1c16f75eea1..00000000000 --- a/pkg/cortex/configinit/init.go +++ /dev/null @@ -1,7 +0,0 @@ -package configinit - -import "github.com/prometheus/common/model" - -func init() { - model.NameValidationScheme = model.LegacyValidation -} diff --git a/pkg/cortex/cortex.go b/pkg/cortex/cortex.go index 255c9c238a4..c3bf32f0706 100644 --- a/pkg/cortex/cortex.go +++ b/pkg/cortex/cortex.go @@ -14,6 +14,8 @@ import ( "github.com/go-kit/log/level" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/model" + prom_config "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/promql" prom_storage "github.com/prometheus/prometheus/storage" "github.com/weaveworks/common/server" @@ -31,7 +33,6 @@ import ( "github.com/cortexproject/cortex/pkg/configs" configAPI "github.com/cortexproject/cortex/pkg/configs/api" "github.com/cortexproject/cortex/pkg/configs/db" - _ "github.com/cortexproject/cortex/pkg/cortex/configinit" "github.com/cortexproject/cortex/pkg/cortex/storage" "github.com/cortexproject/cortex/pkg/cortexpb" "github.com/cortexproject/cortex/pkg/distributor" @@ -69,6 +70,7 @@ import ( var ( errInvalidHTTPPrefix = errors.New("HTTP prefix should be empty or start with /") + errInvalidNameValidationScheme = errors.New("Name validation scheme should either be empty, legacy or utf-8") ) // The design pattern for Cortex is a series of config objects, which are @@ -90,11 +92,12 @@ var ( // Config is the root config for Cortex. type Config struct { - Target flagext.StringSliceCSV `yaml:"target"` - AuthEnabled bool `yaml:"auth_enabled"` - PrintConfig bool `yaml:"-"` - HTTPPrefix string `yaml:"http_prefix"` - MonitoredResources flagext.StringSliceCSV `yaml:"monitored_resources"` + Target flagext.StringSliceCSV `yaml:"target"` + AuthEnabled bool `yaml:"auth_enabled"` + PrintConfig bool `yaml:"-"` + HTTPPrefix string `yaml:"http_prefix"` + NameValidationScheme string `yaml:"name_validation_scheme"` + MonitoredResources flagext.StringSliceCSV `yaml:"monitored_resources"` ExternalQueryable prom_storage.Queryable `yaml:"-"` ExternalPusher ruler.Pusher `yaml:"-"` @@ -146,6 +149,7 @@ func (c *Config) RegisterFlags(f *flag.FlagSet) { f.BoolVar(&c.AuthEnabled, "auth.enabled", true, "Set to false to disable auth.") f.BoolVar(&c.PrintConfig, "print.config", false, "Print the config and exit.") f.StringVar(&c.HTTPPrefix, "http.prefix", "/api/prom", "HTTP path prefix for Cortex API.") + f.StringVar(&c.NameValidationScheme, "name.validation_scheme", prom_config.LegacyValidationConfig, "Validation scheme for metric and label names. Set to utf8 to allow UTF-8 characters. legacy by default") c.MonitoredResources = []string{} f.Var(&c.MonitoredResources, "monitored.resources", "Comma-separated list of resources to monitor. "+ @@ -193,6 +197,10 @@ func (c *Config) Validate(log log.Logger) error { return errInvalidHTTPPrefix } + if (c.NameValidationScheme != "" && c.NameValidationScheme != prom_config.LegacyValidationConfig && c.NameValidationScheme != prom_config.UTF8ValidationConfig) { + return errInvalidNameValidationScheme + } + if err := c.API.Validate(); err != nil { return errors.Wrap(err, "invalid api config") } @@ -361,6 +369,16 @@ func New(cfg Config) (*Cortex, error) { os.Exit(0) } + // Sets the NameValidationScheme in prometheus/common + switch cfg.NameValidationScheme { + case "", prom_config.LegacyValidationConfig: + model.NameValidationScheme = model.LegacyValidation + case prom_config.UTF8ValidationConfig: + model.NameValidationScheme = model.UTF8Validation + default: + return nil, fmt.Errorf("invalid name validation scheme") + } + // Swap out the default resolver to support multiple tenant IDs separated by a '|' if cfg.TenantFederation.Enabled { util_log.WarnExperimentalUse("tenant-federation") diff --git a/pkg/cortex/cortex_test.go b/pkg/cortex/cortex_test.go index 74bf0750a33..605d52af9ac 100644 --- a/pkg/cortex/cortex_test.go +++ b/pkg/cortex/cortex_test.go @@ -14,6 +14,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + prom_config "github.com/prometheus/prometheus/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/weaveworks/common/server" @@ -184,6 +185,43 @@ func TestConfigValidation(t *testing.T) { }, expectedError: nil, }, + // NameValidationScheme tests + { + name: "should not fail validation for empty name validation scheme (use legacy by default)", + getTestConfig: func() *Config { + configuration := newDefaultConfig() + configuration.NameValidationScheme = "" + return configuration + }, + expectedError: nil, + }, + { + name: "should not fail validation for legacy name validation scheme", + getTestConfig: func() *Config { + configuration := newDefaultConfig() + configuration.NameValidationScheme = prom_config.LegacyValidationConfig + return configuration + }, + expectedError: nil, + }, + { + name: "should not fail validation for utf-8 name validation scheme", + getTestConfig: func() *Config { + configuration := newDefaultConfig() + configuration.NameValidationScheme = prom_config.UTF8ValidationConfig + return configuration + }, + expectedError: nil, + }, + { + name: "should fail validation for invalid name validation scheme", + getTestConfig: func() *Config { + configuration := newDefaultConfig() + configuration.NameValidationScheme = "invalid" + return configuration + }, + expectedError: errInvalidNameValidationScheme, + }, } { t.Run(tc.name, func(t *testing.T) { err := tc.getTestConfig().Validate(nil) diff --git a/pkg/distributor/distributor_test.go b/pkg/distributor/distributor_test.go index 3618f285fee..42bfdb19eef 100644 --- a/pkg/distributor/distributor_test.go +++ b/pkg/distributor/distributor_test.go @@ -35,7 +35,6 @@ import ( "google.golang.org/grpc/status" promchunk "github.com/cortexproject/cortex/pkg/chunk/encoding" - _ "github.com/cortexproject/cortex/pkg/cortex/configinit" "github.com/cortexproject/cortex/pkg/cortexpb" "github.com/cortexproject/cortex/pkg/ha" "github.com/cortexproject/cortex/pkg/ingester" diff --git a/pkg/util/validation/validate_test.go b/pkg/util/validation/validate_test.go index 6b3c15fca78..80eff186912 100644 --- a/pkg/util/validation/validate_test.go +++ b/pkg/util/validation/validate_test.go @@ -16,7 +16,6 @@ import ( "github.com/stretchr/testify/require" "github.com/weaveworks/common/httpgrpc" - _ "github.com/cortexproject/cortex/pkg/cortex/configinit" "github.com/cortexproject/cortex/pkg/cortexpb" util_log "github.com/cortexproject/cortex/pkg/util/log" )