From 20e3c295aea5992a4d8ea8e7e45ed9c9d6639813 Mon Sep 17 00:00:00 2001 From: "Xiaochao Dong (@damnever)" Date: Fri, 24 Mar 2023 17:18:24 +0800 Subject: [PATCH] Optimize constant label pair adding with relabel.Replace Signed-off-by: Xiaochao Dong (@damnever) --- model/relabel/relabel.go | 15 +++++++++ model/relabel/relabel_test.go | 60 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/model/relabel/relabel.go b/model/relabel/relabel.go index d29c3d07a..83b1a9147 100644 --- a/model/relabel/relabel.go +++ b/model/relabel/relabel.go @@ -267,6 +267,17 @@ func relabel(cfg *Config, lb *labels.Builder) (keep bool) { return false } case Replace: + // Fast path to add or delete label pair. + if val == "" && cfg.Regex == DefaultRelabelConfig.Regex && + !varInRegexTemplate(cfg.TargetLabel) && !varInRegexTemplate(cfg.Replacement) { + if !model.LabelName(cfg.TargetLabel).IsValid() || cfg.Replacement == "" { + lb.Del(cfg.TargetLabel) + } else { + lb.Set(cfg.TargetLabel, cfg.Replacement) + } + break + } + indexes := cfg.Regex.FindStringSubmatchIndex(val) // If there is no match no replacement must take place. if indexes == nil { @@ -316,3 +327,7 @@ func relabel(cfg *Config, lb *labels.Builder) (keep bool) { return true } + +func varInRegexTemplate(template string) bool { + return strings.Contains(template, "$") +} diff --git a/model/relabel/relabel_test.go b/model/relabel/relabel_test.go index 517b9b822..d3815afe6 100644 --- a/model/relabel/relabel_test.go +++ b/model/relabel/relabel_test.go @@ -15,6 +15,7 @@ package relabel import ( "fmt" + "sort" "testing" "github.com/prometheus/common/model" @@ -850,3 +851,62 @@ func BenchmarkRelabel(b *testing.B) { }) } } + +func BenchmarkRelabel_ReplaceAddLabel(b *testing.B) { + cfgs := []*Config{} + for k, v := range map[string]string{ + "wwwwww": "wwwwww", + "xxxxxxxxx": "xxxxxxxxx", + "yyyyyyyyyyyy": "yyyyyyyyyyyy", + "${0}": "dropped", + "dropped": "${0}", + } { + cfgs = append(cfgs, &Config{ + Action: DefaultRelabelConfig.Action, + Separator: DefaultRelabelConfig.Separator, + Regex: DefaultRelabelConfig.Regex, + TargetLabel: k, + Replacement: v, + }) + } + expectLset := labels.Labels{ + labels.Label{Name: "abcdefg01", Value: "hijklmn1"}, + labels.Label{Name: "abcdefg02", Value: "hijklmn2"}, + labels.Label{Name: "abcdefg03", Value: "hijklmn3"}, + labels.Label{Name: "abcdefg04", Value: "hijklmn4"}, + labels.Label{Name: "abcdefg05", Value: "hijklmn5"}, + labels.Label{Name: "abcdefg06", Value: "hijklmn6"}, + labels.Label{Name: "abcdefg07", Value: "hijklmn7"}, + labels.Label{Name: "abcdefg08", Value: "hijklmn8"}, + labels.Label{Name: "abcdefg09", Value: "hijklmn9"}, + labels.Label{Name: "abcdefg10", Value: "hijklmn10"}, + labels.Label{Name: "abcdefg11", Value: "hijklmn11"}, + labels.Label{Name: "abcdefg12", Value: "hijklmn12"}, + labels.Label{Name: "abcdefg13", Value: "hijklmn13"}, + labels.Label{Name: "wwwwww", Value: "wwwwww"}, + labels.Label{Name: "xxxxxxxxx", Value: "xxxxxxxxx"}, + labels.Label{Name: "yyyyyyyyyyyy", Value: "yyyyyyyyyyyy"}, + } + sort.Sort(expectLset) + + for i := 0; i < b.N; i++ { + lset := labels.Labels{ + labels.Label{Name: "abcdefg01", Value: "hijklmn1"}, + labels.Label{Name: "abcdefg02", Value: "hijklmn2"}, + labels.Label{Name: "abcdefg03", Value: "hijklmn3"}, + labels.Label{Name: "abcdefg04", Value: "hijklmn4"}, + labels.Label{Name: "abcdefg05", Value: "hijklmn5"}, + labels.Label{Name: "abcdefg06", Value: "hijklmn6"}, + labels.Label{Name: "abcdefg07", Value: "hijklmn7"}, + labels.Label{Name: "abcdefg08", Value: "hijklmn8"}, + labels.Label{Name: "abcdefg09", Value: "hijklmn9"}, + labels.Label{Name: "abcdefg10", Value: "hijklmn10"}, + labels.Label{Name: "abcdefg11", Value: "hijklmn11"}, + labels.Label{Name: "abcdefg12", Value: "hijklmn12"}, + labels.Label{Name: "abcdefg13", Value: "hijklmn13"}, + } + actual, _ := Process(lset, cfgs...) + var _ = actual + // require.Equal(b, actual, expectLset) + } +}