diff --git a/relabel/relabel.go b/relabel/relabel.go index 0e5d616ca..6ce37296c 100644 --- a/relabel/relabel.go +++ b/relabel/relabel.go @@ -61,12 +61,17 @@ func relabel(labels model.LabelSet, cfg *config.RelabelConfig) model.LabelSet { if indexes == nil { break } + target := model.LabelName(cfg.Regex.ExpandString([]byte{}, string(cfg.TargetLabel), val, indexes)) + if !target.IsValid() { + delete(labels, cfg.TargetLabel) + break + } res := cfg.Regex.ExpandString([]byte{}, cfg.Replacement, val, indexes) if len(res) == 0 { delete(labels, cfg.TargetLabel) - } else { - labels[cfg.TargetLabel] = model.LabelValue(res) + break } + labels[target] = model.LabelValue(res) case config.RelabelHashMod: mod := sum64(md5.Sum([]byte(val))) % cfg.Modulus labels[cfg.TargetLabel] = model.LabelValue(fmt.Sprintf("%d", mod)) diff --git a/relabel/relabel_test.go b/relabel/relabel_test.go index 6773ffeb4..4004fa96f 100644 --- a/relabel/relabel_test.go +++ b/relabel/relabel_test.go @@ -277,6 +277,106 @@ func TestRelabel(t *testing.T) { "my_baz": "bbb", }, }, + { // valid case + input: model.LabelSet{ + "a": "some-name-value", + }, + relabel: []*config.RelabelConfig{ + { + SourceLabels: model.LabelNames{"a"}, + Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: config.RelabelReplace, + Replacement: "${2}", + TargetLabel: model.LabelName("${1}"), + }, + }, + output: model.LabelSet{ + "a": "some-name-value", + "name": "value", + }, + }, + { // invalid replacement "" + input: model.LabelSet{ + "a": "some-name-value", + }, + relabel: []*config.RelabelConfig{ + { + SourceLabels: model.LabelNames{"a"}, + Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: config.RelabelReplace, + Replacement: "${3}", + TargetLabel: model.LabelName("${1}"), + }, + }, + output: model.LabelSet{ + "a": "some-name-value", + }, + }, + { // invalid target_labels + input: model.LabelSet{ + "a": "some-name-value", + }, + relabel: []*config.RelabelConfig{ + { + SourceLabels: model.LabelNames{"a"}, + Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: config.RelabelReplace, + Replacement: "${1}", + TargetLabel: model.LabelName("${3}"), + }, + { + SourceLabels: model.LabelNames{"a"}, + Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: config.RelabelReplace, + Replacement: "${1}", + TargetLabel: model.LabelName("0${3}"), + }, + { + SourceLabels: model.LabelNames{"a"}, + Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: config.RelabelReplace, + Replacement: "${1}", + TargetLabel: model.LabelName("-${3}"), + }, + }, + output: model.LabelSet{ + "a": "some-name-value", + }, + }, + { // more complex real-life like usecase + input: model.LabelSet{ + "__meta_sd_tags": "path:/secret,job:some-job,label:foo=bar", + }, + relabel: []*config.RelabelConfig{ + { + SourceLabels: model.LabelNames{"__meta_sd_tags"}, + Regex: config.MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"), + Action: config.RelabelReplace, + Replacement: "${1}", + TargetLabel: model.LabelName("__metrics_path__"), + }, + { + SourceLabels: model.LabelNames{"__meta_sd_tags"}, + Regex: config.MustNewRegexp("(?:.+,|^)job:([^,]+).*"), + Action: config.RelabelReplace, + Replacement: "${1}", + TargetLabel: model.LabelName("job"), + }, + { + SourceLabels: model.LabelNames{"__meta_sd_tags"}, + Regex: config.MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"), + Action: config.RelabelReplace, + Replacement: "${2}", + TargetLabel: model.LabelName("${1}"), + }, + }, + output: model.LabelSet{ + "__meta_sd_tags": "path:/secret,job:some-job,label:foo=bar", + "__metrics_path__": "/secret", + "job": "some-job", + "foo": "bar", + }, + }, } for i, test := range tests {