From 7688b5fdf73679045fb0a4d6d2662995f28eb1a6 Mon Sep 17 00:00:00 2001 From: Federico De Giuli Date: Fri, 28 Aug 2026 12:07:40 -0700 Subject: [PATCH] bugfix: Make relabel application deterministic --- pkg/main.go | 1 + pkg/relabel_test.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/pkg/main.go b/pkg/main.go index a76e590c..4dcb3e78 100644 --- a/pkg/main.go +++ b/pkg/main.go @@ -195,6 +195,7 @@ func applyRelabelConfigs(labels model.LabelSet) model.LabelSet { } // Sort labels as required by Process + builder.Sort() promLabels := builder.Labels() // Apply relabeling diff --git a/pkg/relabel_test.go b/pkg/relabel_test.go index 95e13e36..5703f84c 100644 --- a/pkg/relabel_test.go +++ b/pkg/relabel_test.go @@ -3,6 +3,7 @@ package main import ( "testing" + "github.com/prometheus/common/model" "github.com/prometheus/prometheus/model/relabel" "github.com/stretchr/testify/require" @@ -127,3 +128,21 @@ func TestParseRelabelConfigs(t *testing.T) { }) } } + +// Process input is built by ranging a Go map, whose order is randomized. +// Without builder.Sort() the source_labels lookup intermittently misses and +// the rule silently no-ops. +func TestApplyRelabelConfigsSortsLabels(t *testing.T) { + var err error + relabelConfigs, err = parseRelabelConfigs( + `[{"source_labels":["_tst"],"regex":"^/svc/(.+)$","target_label":"out"}]`) + require.NoError(t, err) + t.Cleanup(func() { relabelConfigs = nil }) + + in := model.LabelSet{"_tst": "/svc/foo", "a": "1", "b": "2"} + + for i := 0; i < 100; i++ { + require.Equal(t, model.LabelValue("foo"), + applyRelabelConfigs(in)["out"], "iteration %d", i) + } +}