mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/promrelabel: allows regex capture groups in target_label like Prometheus does
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/569
This commit is contained in:
parent
ac3700ed1e
commit
5820c0ffb7
5 changed files with 160 additions and 103 deletions
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
@ -124,6 +125,9 @@ func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedR
|
||||||
Modulus: modulus,
|
Modulus: modulus,
|
||||||
Replacement: replacement,
|
Replacement: replacement,
|
||||||
Action: action,
|
Action: action,
|
||||||
|
|
||||||
|
hasCaptureGroupInTargetLabel: strings.Contains(targetLabel, "$"),
|
||||||
|
hasCaptureGroupInReplacement: strings.Contains(replacement, "$"),
|
||||||
})
|
})
|
||||||
return dst, nil
|
return dst, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ func TestParseRelabelConfigsSuccess(t *testing.T) {
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
|
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,9 @@ type ParsedRelabelConfig struct {
|
||||||
Modulus uint64
|
Modulus uint64
|
||||||
Replacement string
|
Replacement string
|
||||||
Action string
|
Action string
|
||||||
|
|
||||||
|
hasCaptureGroupInTargetLabel bool
|
||||||
|
hasCaptureGroupInReplacement bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns human-readable representation for prc.
|
// String returns human-readable representation for prc.
|
||||||
|
@ -103,51 +106,52 @@ func FinalizeLabels(dst, src []prompbmarshal.Label) []prompbmarshal.Label {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyRelabelConfig applies relabeling according to cfg.
|
// applyRelabelConfig applies relabeling according to prc.
|
||||||
//
|
//
|
||||||
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||||
func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, cfg *ParsedRelabelConfig) []prompbmarshal.Label {
|
func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *ParsedRelabelConfig) []prompbmarshal.Label {
|
||||||
src := labels[labelsOffset:]
|
src := labels[labelsOffset:]
|
||||||
switch cfg.Action {
|
switch prc.Action {
|
||||||
case "replace":
|
case "replace":
|
||||||
bb := relabelBufPool.Get()
|
bb := relabelBufPool.Get()
|
||||||
bb.B = concatLabelValues(bb.B[:0], src, cfg.SourceLabels, cfg.Separator)
|
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||||
if len(bb.B) == 0 && cfg.Regex == defaultRegexForRelabelConfig && !strings.Contains(cfg.Replacement, "$") {
|
if len(bb.B) == 0 && prc.Regex == defaultRegexForRelabelConfig && !prc.hasCaptureGroupInReplacement && !prc.hasCaptureGroupInTargetLabel {
|
||||||
// Fast path for the following rule that just sets label value:
|
// Fast path for the following rule that just sets label value:
|
||||||
// - target_label: foobar
|
// - target_label: foobar
|
||||||
// replacement: something-here
|
// replacement: something-here
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
return setLabelValue(labels, labelsOffset, cfg.TargetLabel, cfg.Replacement)
|
return setLabelValue(labels, labelsOffset, prc.TargetLabel, prc.Replacement)
|
||||||
}
|
}
|
||||||
match := cfg.Regex.FindSubmatchIndex(bb.B)
|
match := prc.Regex.FindSubmatchIndex(bb.B)
|
||||||
if match == nil {
|
if match == nil {
|
||||||
// Fast path - nothing to replace.
|
// Fast path - nothing to replace.
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
sourceStr := bytesutil.ToUnsafeString(bb.B)
|
sourceStr := bytesutil.ToUnsafeString(bb.B)
|
||||||
value := relabelBufPool.Get()
|
nameStr := prc.TargetLabel
|
||||||
value.B = cfg.Regex.ExpandString(value.B[:0], cfg.Replacement, sourceStr, match)
|
if prc.hasCaptureGroupInTargetLabel {
|
||||||
|
nameStr = prc.expandCaptureGroups(nameStr, sourceStr, match)
|
||||||
|
}
|
||||||
|
valueStr := prc.expandCaptureGroups(prc.Replacement, sourceStr, match)
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
valueStr := string(value.B)
|
return setLabelValue(labels, labelsOffset, nameStr, valueStr)
|
||||||
relabelBufPool.Put(value)
|
|
||||||
return setLabelValue(labels, labelsOffset, cfg.TargetLabel, valueStr)
|
|
||||||
case "replace_all":
|
case "replace_all":
|
||||||
bb := relabelBufPool.Get()
|
bb := relabelBufPool.Get()
|
||||||
bb.B = concatLabelValues(bb.B[:0], src, cfg.SourceLabels, cfg.Separator)
|
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||||
if !cfg.Regex.Match(bb.B) {
|
if !prc.Regex.Match(bb.B) {
|
||||||
// Fast path - nothing to replace.
|
// Fast path - nothing to replace.
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
sourceStr := string(bb.B) // Make a copy of bb, since it can be returned from ReplaceAllString
|
sourceStr := string(bb.B) // Make a copy of bb, since it can be returned from ReplaceAllString
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
valueStr := cfg.Regex.ReplaceAllString(sourceStr, cfg.Replacement)
|
valueStr := prc.Regex.ReplaceAllString(sourceStr, prc.Replacement)
|
||||||
return setLabelValue(labels, labelsOffset, cfg.TargetLabel, valueStr)
|
return setLabelValue(labels, labelsOffset, prc.TargetLabel, valueStr)
|
||||||
case "keep":
|
case "keep":
|
||||||
bb := relabelBufPool.Get()
|
bb := relabelBufPool.Get()
|
||||||
bb.B = concatLabelValues(bb.B[:0], src, cfg.SourceLabels, cfg.Separator)
|
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||||
keep := cfg.Regex.Match(bb.B)
|
keep := prc.Regex.Match(bb.B)
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
if !keep {
|
if !keep {
|
||||||
return labels[:labelsOffset]
|
return labels[:labelsOffset]
|
||||||
|
@ -155,8 +159,8 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, cfg *Par
|
||||||
return labels
|
return labels
|
||||||
case "drop":
|
case "drop":
|
||||||
bb := relabelBufPool.Get()
|
bb := relabelBufPool.Get()
|
||||||
bb.B = concatLabelValues(bb.B[:0], src, cfg.SourceLabels, cfg.Separator)
|
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||||
drop := cfg.Regex.Match(bb.B)
|
drop := prc.Regex.Match(bb.B)
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
if drop {
|
if drop {
|
||||||
return labels[:labelsOffset]
|
return labels[:labelsOffset]
|
||||||
|
@ -164,20 +168,20 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, cfg *Par
|
||||||
return labels
|
return labels
|
||||||
case "hashmod":
|
case "hashmod":
|
||||||
bb := relabelBufPool.Get()
|
bb := relabelBufPool.Get()
|
||||||
bb.B = concatLabelValues(bb.B[:0], src, cfg.SourceLabels, cfg.Separator)
|
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||||
h := xxhash.Sum64(bb.B) % cfg.Modulus
|
h := xxhash.Sum64(bb.B) % prc.Modulus
|
||||||
value := strconv.Itoa(int(h))
|
value := strconv.Itoa(int(h))
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
return setLabelValue(labels, labelsOffset, cfg.TargetLabel, value)
|
return setLabelValue(labels, labelsOffset, prc.TargetLabel, value)
|
||||||
case "labelmap":
|
case "labelmap":
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
match := cfg.Regex.FindStringSubmatchIndex(label.Name)
|
match := prc.Regex.FindStringSubmatchIndex(label.Name)
|
||||||
if match == nil {
|
if match == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
value := relabelBufPool.Get()
|
value := relabelBufPool.Get()
|
||||||
value.B = cfg.Regex.ExpandString(value.B[:0], cfg.Replacement, label.Name, match)
|
value.B = prc.Regex.ExpandString(value.B[:0], prc.Replacement, label.Name, match)
|
||||||
label.Name = string(value.B)
|
label.Name = string(value.B)
|
||||||
relabelBufPool.Put(value)
|
relabelBufPool.Put(value)
|
||||||
}
|
}
|
||||||
|
@ -185,16 +189,16 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, cfg *Par
|
||||||
case "labelmap_all":
|
case "labelmap_all":
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
if !cfg.Regex.MatchString(label.Name) {
|
if !prc.Regex.MatchString(label.Name) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
label.Name = cfg.Regex.ReplaceAllString(label.Name, cfg.Replacement)
|
label.Name = prc.Regex.ReplaceAllString(label.Name, prc.Replacement)
|
||||||
}
|
}
|
||||||
return labels
|
return labels
|
||||||
case "labeldrop":
|
case "labeldrop":
|
||||||
keepSrc := true
|
keepSrc := true
|
||||||
for i := range src {
|
for i := range src {
|
||||||
if cfg.Regex.MatchString(src[i].Name) {
|
if prc.Regex.MatchString(src[i].Name) {
|
||||||
keepSrc = false
|
keepSrc = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -205,7 +209,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, cfg *Par
|
||||||
dst := labels[:labelsOffset]
|
dst := labels[:labelsOffset]
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
if !cfg.Regex.MatchString(label.Name) {
|
if !prc.Regex.MatchString(label.Name) {
|
||||||
dst = append(dst, *label)
|
dst = append(dst, *label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +217,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, cfg *Par
|
||||||
case "labelkeep":
|
case "labelkeep":
|
||||||
keepSrc := true
|
keepSrc := true
|
||||||
for i := range src {
|
for i := range src {
|
||||||
if !cfg.Regex.MatchString(src[i].Name) {
|
if !prc.Regex.MatchString(src[i].Name) {
|
||||||
keepSrc = false
|
keepSrc = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -224,17 +228,25 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, cfg *Par
|
||||||
dst := labels[:labelsOffset]
|
dst := labels[:labelsOffset]
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
if cfg.Regex.MatchString(label.Name) {
|
if prc.Regex.MatchString(label.Name) {
|
||||||
dst = append(dst, *label)
|
dst = append(dst, *label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dst
|
return dst
|
||||||
default:
|
default:
|
||||||
logger.Panicf("BUG: unknown `action`: %q", cfg.Action)
|
logger.Panicf("BUG: unknown `action`: %q", prc.Action)
|
||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (prc *ParsedRelabelConfig) expandCaptureGroups(template, source string, match []int) string {
|
||||||
|
bb := relabelBufPool.Get()
|
||||||
|
bb.B = prc.Regex.ExpandString(bb.B[:0], template, source, match)
|
||||||
|
s := string(bb.B)
|
||||||
|
relabelBufPool.Put(bb)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
var relabelBufPool bytesutil.ByteBufferPool
|
var relabelBufPool bytesutil.ByteBufferPool
|
||||||
|
|
||||||
func concatLabelValues(dst []byte, labels []prompbmarshal.Label, labelNames []string, separator string) []byte {
|
func concatLabelValues(dst []byte, labels []prompbmarshal.Label, labelNames []string, separator string) []byte {
|
||||||
|
|
|
@ -57,28 +57,31 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
t.Run("replace-miss", func(t *testing.T) {
|
t.Run("replace-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, nil, false, []prompbmarshal.Label{})
|
}, nil, false, []prompbmarshal.Label{})
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
SourceLabels: []string{"foo"},
|
SourceLabels: []string{"foo"},
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, nil, false, []prompbmarshal.Label{})
|
}, nil, false, []prompbmarshal.Label{})
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
SourceLabels: []string{"foo"},
|
SourceLabels: []string{"foo"},
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, []prompbmarshal.Label{
|
}, []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
|
@ -93,11 +96,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
SourceLabels: []string{"foo"},
|
SourceLabels: []string{"foo"},
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: regexp.MustCompile(".+"),
|
Regex: regexp.MustCompile(".+"),
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, []prompbmarshal.Label{
|
}, []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
|
@ -114,12 +118,13 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
t.Run("replace-hit", func(t *testing.T) {
|
t.Run("replace-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
SourceLabels: []string{"xxx", "foo"},
|
SourceLabels: []string{"xxx", "foo"},
|
||||||
Separator: ";",
|
Separator: ";",
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "a-$1-b",
|
Replacement: "a-$1-b",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, []prompbmarshal.Label{
|
}, []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
|
@ -137,31 +142,62 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
t.Run("replace-hit-target-label-with-capture-group", func(t *testing.T) {
|
||||||
|
f([]ParsedRelabelConfig{
|
||||||
|
{
|
||||||
|
Action: "replace",
|
||||||
|
SourceLabels: []string{"xxx", "foo"},
|
||||||
|
Separator: ";",
|
||||||
|
TargetLabel: "bar-$1",
|
||||||
|
Regex: defaultRegexForRelabelConfig,
|
||||||
|
Replacement: "a-$1-b",
|
||||||
|
hasCaptureGroupInTargetLabel: true,
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
|
},
|
||||||
|
}, []prompbmarshal.Label{
|
||||||
|
{
|
||||||
|
Name: "xxx",
|
||||||
|
Value: "yyy",
|
||||||
|
},
|
||||||
|
}, false, []prompbmarshal.Label{
|
||||||
|
{
|
||||||
|
Name: "bar-yyy;",
|
||||||
|
Value: "a-yyy;-b",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "xxx",
|
||||||
|
Value: "yyy",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
t.Run("replace_all-miss", func(t *testing.T) {
|
t.Run("replace_all-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace_all",
|
Action: "replace_all",
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, nil, false, []prompbmarshal.Label{})
|
}, nil, false, []prompbmarshal.Label{})
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace_all",
|
Action: "replace_all",
|
||||||
SourceLabels: []string{"foo"},
|
SourceLabels: []string{"foo"},
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, nil, false, []prompbmarshal.Label{})
|
}, nil, false, []prompbmarshal.Label{})
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace_all",
|
Action: "replace_all",
|
||||||
SourceLabels: []string{"foo"},
|
SourceLabels: []string{"foo"},
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, []prompbmarshal.Label{
|
}, []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
|
@ -176,11 +212,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace_all",
|
Action: "replace_all",
|
||||||
SourceLabels: []string{"foo"},
|
SourceLabels: []string{"foo"},
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: regexp.MustCompile(".+"),
|
Regex: regexp.MustCompile(".+"),
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, []prompbmarshal.Label{
|
}, []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
|
@ -197,12 +234,13 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
t.Run("replace_all-hit", func(t *testing.T) {
|
t.Run("replace_all-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace_all",
|
Action: "replace_all",
|
||||||
SourceLabels: []string{"xxx", "foo"},
|
SourceLabels: []string{"xxx", "foo"},
|
||||||
Separator: ";",
|
Separator: ";",
|
||||||
TargetLabel: "xxx",
|
TargetLabel: "xxx",
|
||||||
Regex: regexp.MustCompile("(;)"),
|
Regex: regexp.MustCompile("(;)"),
|
||||||
Replacement: "-$1-",
|
Replacement: "-$1-",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, []prompbmarshal.Label{
|
}, []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
|
@ -219,11 +257,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
t.Run("replace-add-multi-labels", func(t *testing.T) {
|
t.Run("replace-add-multi-labels", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
SourceLabels: []string{"xxx"},
|
SourceLabels: []string{"xxx"},
|
||||||
TargetLabel: "bar",
|
TargetLabel: "bar",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "a-$1",
|
Replacement: "a-$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
|
@ -263,11 +302,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
t.Run("replace-self", func(t *testing.T) {
|
t.Run("replace-self", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f([]ParsedRelabelConfig{
|
||||||
{
|
{
|
||||||
Action: "replace",
|
Action: "replace",
|
||||||
SourceLabels: []string{"foo"},
|
SourceLabels: []string{"foo"},
|
||||||
TargetLabel: "foo",
|
TargetLabel: "foo",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Replacement: "a-$1",
|
Replacement: "a-$1",
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
},
|
},
|
||||||
}, []prompbmarshal.Label{
|
}, []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
|
|
|
@ -952,6 +952,14 @@ scrape_configs:
|
||||||
AuthConfig: &promauth.Config{},
|
AuthConfig: &promauth.Config{},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
prcs, err := promrelabel.ParseRelabelConfigs(nil, []promrelabel.RelabelConfig{{
|
||||||
|
SourceLabels: []string{"foo"},
|
||||||
|
TargetLabel: "abc",
|
||||||
|
}})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error when parsing relabel configs: %s", err)
|
||||||
|
}
|
||||||
f(`
|
f(`
|
||||||
scrape_configs:
|
scrape_configs:
|
||||||
- job_name: foo
|
- job_name: foo
|
||||||
|
@ -987,17 +995,8 @@ scrape_configs:
|
||||||
Value: "foo",
|
Value: "foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AuthConfig: &promauth.Config{},
|
AuthConfig: &promauth.Config{},
|
||||||
MetricRelabelConfigs: []promrelabel.ParsedRelabelConfig{
|
MetricRelabelConfigs: prcs,
|
||||||
{
|
|
||||||
SourceLabels: []string{"foo"},
|
|
||||||
Separator: ";",
|
|
||||||
TargetLabel: "abc",
|
|
||||||
Regex: defaultRegexForRelabelConfig,
|
|
||||||
Replacement: "$1",
|
|
||||||
Action: "replace",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f(`
|
f(`
|
||||||
|
|
Loading…
Reference in a new issue