Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Grafana Mimir

* [CHANGE] Query-frontend: Add support for UTF-8 label and metric names in `/api/v1/cardinality/{label_values|label_values|active_series}` endpoints. #11848.
* [CHANGE] Querier: Add support for UTF-8 label and metric names in `label_join`, `label_replace` and `count_values` PromQL functions. #11848.
* [CHANGE] Remove support for Redis as a cache backend. #12163
* [CHANGE] Memcached: Remove experimental `-<prefix>.memcached.addresses-provider` flag to use alternate DNS service discovery backends. The more reliable backend introduced in 2.16.0 (#10895) is now the default. As a result of this change, DNS-based cache service discovery no longer supports search domains. #12175
* [FEATURE] Distributor: Add experimental `-distributor.otel-native-delta-ingestion` option to allow primitive delta metrics ingestion via the OTLP endpoint. #11631
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ lint: check-makefiles
faillint -paths "github.com/grafana/mimir/pkg/..." ./pkg/querier/api/...
faillint -paths "github.com/grafana/mimir/pkg/..." ./pkg/util/math/...

# Ensure all errors are report as APIError
# Ensure all errors are reported as APIError
faillint -paths "github.com/weaveworks/common/httpgrpc.{Errorf}=github.com/grafana/mimir/pkg/api/error.Newf" ./pkg/frontend/querymiddleware/...

# errors.Cause() only work on errors wrapped by github.com/pkg/errors, while it doesn't work
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ require (
sigs.k8s.io/yaml v1.4.0 // indirect
)

replace github.com/prometheus/prometheus => github.com/grafana/mimir-prometheus v1.8.2-0.20250725113505-6dd7af9abc56
replace github.com/prometheus/prometheus => github.com/grafana/mimir-prometheus v1.8.2-0.20250725123259-c4bd4faba234

// Replace memberlist with our fork which includes some fixes that haven't been
// merged upstream yet:
Expand All @@ -370,7 +370,7 @@ replace github.com/opentracing-contrib/go-stdlib => github.com/grafana/opentraci
replace github.com/opentracing-contrib/go-grpc => github.com/charleskorn/go-grpc v0.0.0-20231024023642-e9298576254f

// Replacing prometheus/alertmanager with our fork.
replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20250620093340-be61a673dee6
replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20250722103749-329f0c4df1ba

// Use Mimir fork of prometheus/otlptranslator to allow for higher velocity of upstream development,
// while allowing Mimir to move at a more conservative pace.
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -571,14 +571,14 @@ github.com/grafana/memberlist v0.3.1-0.20250428154222-f7d51a6f6700 h1:0t7iOQ5ZkB
github.com/grafana/memberlist v0.3.1-0.20250428154222-f7d51a6f6700/go.mod h1:Ri9p/tRShbjYnpNf4FFPXG7wxEGY4Nrcn6E7jrVa//4=
github.com/grafana/mimir-otlptranslator v0.0.0-20250703083430-c31a9568ad96 h1:kq5zJVW9LyFOB5xCeQPTON2HNjwwEkefhegZXGIhQPk=
github.com/grafana/mimir-otlptranslator v0.0.0-20250703083430-c31a9568ad96/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI=
github.com/grafana/mimir-prometheus v1.8.2-0.20250725113505-6dd7af9abc56 h1:HdQyhMJ+AkDUTlFAU7qIIkC3C2n0R/cV8T2S7JnbK7U=
github.com/grafana/mimir-prometheus v1.8.2-0.20250725113505-6dd7af9abc56/go.mod h1:bi1IiCulyFfPIsfFMaCqlggqiLO4PyqNwK/DiqTaYDI=
github.com/grafana/mimir-prometheus v1.8.2-0.20250725123259-c4bd4faba234 h1:hwME5D5GMogJkN9yobyKTEvOk/SzUFDnYNkUjLsg3ik=
github.com/grafana/mimir-prometheus v1.8.2-0.20250725123259-c4bd4faba234/go.mod h1:Pe/2vVv91zryCeOwLSjIFJFsw4Pvd2VNHbTUGu6kUls=
github.com/grafana/opentracing-contrib-go-stdlib v0.0.0-20230509071955-f410e79da956 h1:em1oddjXL8c1tL0iFdtVtPloq2hRPen2MJQKoAWpxu0=
github.com/grafana/opentracing-contrib-go-stdlib v0.0.0-20230509071955-f410e79da956/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU=
github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8=
github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls=
github.com/grafana/prometheus-alertmanager v0.25.1-0.20250620093340-be61a673dee6 h1:oJnbhG6ZNy10AjsgNeAtAKeGHogIGOMfAsBH6fYYa5M=
github.com/grafana/prometheus-alertmanager v0.25.1-0.20250620093340-be61a673dee6/go.mod h1:O/QP1BCm0HHIzbKvgMzqb5sSyH88rzkFk84F4TfJjBU=
github.com/grafana/prometheus-alertmanager v0.25.1-0.20250722103749-329f0c4df1ba h1:8u5N0btFygn+2S+B6Xs0HFfq4NJ0kJsX9UpIOlidDmQ=
github.com/grafana/prometheus-alertmanager v0.25.1-0.20250722103749-329f0c4df1ba/go.mod h1:O/QP1BCm0HHIzbKvgMzqb5sSyH88rzkFk84F4TfJjBU=
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg=
github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=
github.com/grafana/regexp v0.0.0-20240531075221-3685f1377d7b h1:oMAq12GxTpwo9jxbnG/M4F/HdpwbibTaVoxNA0NZprY=
Expand Down
4 changes: 2 additions & 2 deletions integration/kv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package integration
import (
"context"
"errors"
"sort"
"slices"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -40,7 +40,7 @@ func TestKVList(t *testing.T) {
// Get list of keys and sort them
keys, err := client.List(context.Background(), "")
require.NoError(t, err, "could not list keys")
sort.Strings(keys)
slices.Sort(keys)
require.Equal(t, keysToCreate, keys, "returned key paths did not match created paths")

verifyClientMetricsHistogram(t, reg, "cortex_kv_request_duration_seconds", map[string]uint64{
Expand Down
15 changes: 6 additions & 9 deletions pkg/distributor/distributor.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ import (

var tracer = otel.Tracer("pkg/distributor")

func init() {
// Mimir doesn't support Prometheus' UTF-8 metric/label name scheme yet.
// nolint:staticcheck
model.NameValidationScheme = model.LegacyValidation
}

var (
// Validation errors.
errInvalidTenantShardSize = errors.New("invalid tenant shard size, the value must be greater than or equal to zero")
Expand Down Expand Up @@ -1098,15 +1092,18 @@ func (d *Distributor) prePushRelabelMiddleware(next PushFunc) PushFunc {
return err
}

dropLabels := d.limits.DropLabels(userID)
relabelConfigs := d.limits.MetricRelabelConfigs(userID)

var removeTsIndexes []int
lb := labels.NewBuilder(labels.EmptyLabels())
for tsIdx := 0; tsIdx < len(req.Timeseries); tsIdx++ {
ts := req.Timeseries[tsIdx]

if mrc := d.limits.MetricRelabelConfigs(userID); len(mrc) > 0 {
if len(relabelConfigs) > 0 {
mimirpb.FromLabelAdaptersToBuilder(ts.Labels, lb)
lb.Set(metaLabelTenantID, userID)
keep := relabel.ProcessBuilder(lb, mrc...)
keep := relabel.ProcessBuilder(lb, relabelConfigs...)
if !keep {
removeTsIndexes = append(removeTsIndexes, tsIdx)
continue
Expand All @@ -1115,7 +1112,7 @@ func (d *Distributor) prePushRelabelMiddleware(next PushFunc) PushFunc {
req.Timeseries[tsIdx].SetLabels(mimirpb.FromBuilderToLabelAdapters(lb, ts.Labels))
}

for _, labelName := range d.limits.DropLabels(userID) {
for _, labelName := range dropLabels {
req.Timeseries[tsIdx].RemoveLabel(labelName)
}

Expand Down
8 changes: 6 additions & 2 deletions pkg/distributor/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/model/labels"

"github.com/grafana/mimir/pkg/costattribution"
"github.com/grafana/mimir/pkg/mimirpb"
Expand Down Expand Up @@ -390,6 +391,7 @@ type labelValidationConfig interface {
MaxLabelNamesPerInfoSeries(userID string) int
MaxLabelNameLength(userID string) int
MaxLabelValueLength(userID string) int
ValidationScheme(userID string) model.ValidationScheme
}

func removeNonASCIIChars(in string) (out string) {
Expand Down Expand Up @@ -421,7 +423,9 @@ func validateLabels(m *sampleValidationMetrics, cfg labelValidationConfig, userI
return errors.New(noMetricNameMsgFormat)
}

if !model.IsValidMetricName(model.LabelValue(unsafeMetricName)) {
validationScheme := cfg.ValidationScheme(userID)

if !labels.IsValidMetricName(unsafeMetricName, validationScheme) {
cat.IncrementDiscardedSamples(ls, 1, reasonInvalidMetricName, ts)
m.invalidMetricName.WithLabelValues(userID, group).Inc()
return fmt.Errorf(invalidMetricNameMsgFormat, removeNonASCIIChars(unsafeMetricName))
Expand All @@ -447,7 +451,7 @@ func validateLabels(m *sampleValidationMetrics, cfg labelValidationConfig, userI
maxLabelValueLength := cfg.MaxLabelValueLength(userID)
lastLabelName := ""
for _, l := range ls {
if !skipLabelValidation && !model.LabelName(l.Name).IsValid() {
if !skipLabelValidation && !labels.IsValidLabelName(l.Name, validationScheme) {
m.invalidLabel.WithLabelValues(userID, group).Inc()
cat.IncrementDiscardedSamples(ls, 1, reasonInvalidLabel, ts)
return fmt.Errorf(invalidLabelMsgFormat, l.Name, mimirpb.FromLabelAdaptersToString(ls))
Expand Down
Loading