From 4e70a0a14e33ceb40c95bac15ca42458b341ea75 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Wed, 12 Aug 2015 10:21:20 +0100 Subject: [PATCH] Retrieval: Add relabel action to map label names with a regex. The intended use case is where a user has tags/labels coming from metadata in Kubernetes or EC2, and wants to make some subset of them into target labels. --- config/config.go | 2 ++ retrieval/relabel.go | 13 ++++++++++++ retrieval/relabel_test.go | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/config/config.go b/config/config.go index 514e55356..fe8053a49 100644 --- a/config/config.go +++ b/config/config.go @@ -610,6 +610,8 @@ const ( RelabelDrop RelabelAction = "drop" // Sets a label to the modulus of a hash of labels. RelabelHashMod RelabelAction = "hashmod" + // Copy labels to other labelnames based on a regex. + RelabelLabelMap RelabelAction = "labelmap" ) // UnmarshalYAML implements the yaml.Unmarshaler interface. diff --git a/retrieval/relabel.go b/retrieval/relabel.go index 0b2785f58..c8d67278d 100644 --- a/retrieval/relabel.go +++ b/retrieval/relabel.go @@ -62,6 +62,19 @@ func relabel(labels clientmodel.LabelSet, cfg *config.RelabelConfig) (clientmode hasher.Write([]byte(val)) mod := hasher.Sum64() % cfg.Modulus labels[cfg.TargetLabel] = clientmodel.LabelValue(fmt.Sprintf("%d", mod)) + case config.RelabelLabelMap: + out := make(clientmodel.LabelSet, len(labels)) + // Take a copy to avoid infinite loops. + for ln, lv := range labels { + out[ln] = lv + } + for ln, lv := range labels { + if cfg.Regex.MatchString(string(ln)) { + res := cfg.Regex.ReplaceAllString(string(ln), cfg.Replacement) + out[clientmodel.LabelName(res)] = lv + } + } + labels = out default: panic(fmt.Errorf("retrieval.relabel: unknown relabel action type %q", cfg.Action)) } diff --git a/retrieval/relabel_test.go b/retrieval/relabel_test.go index 455067c83..84e6cd04a 100644 --- a/retrieval/relabel_test.go +++ b/retrieval/relabel_test.go @@ -173,6 +173,50 @@ func TestRelabel(t *testing.T) { "d": "58", }, }, + { + input: clientmodel.LabelSet{ + "a": "foo", + "b1": "bar", + "b2": "baz", + }, + relabel: []*config.RelabelConfig{ + { + Regex: &config.Regexp{*regexp.MustCompile("^(b.*)")}, + Replacement: "bar_${1}", + Action: config.RelabelLabelMap, + }, + }, + output: clientmodel.LabelSet{ + "a": "foo", + "b1": "bar", + "b2": "baz", + "bar_b1": "bar", + "bar_b2": "baz", + }, + }, + { + input: clientmodel.LabelSet{ + "a": "foo", + "__meta_my_bar": "aaa", + "__meta_my_baz": "bbb", + "__meta_other": "ccc", + }, + relabel: []*config.RelabelConfig{ + { + Regex: &config.Regexp{*regexp.MustCompile("^__meta_(my.*)")}, + Replacement: "${1}", + Action: config.RelabelLabelMap, + }, + }, + output: clientmodel.LabelSet{ + "a": "foo", + "__meta_my_bar": "aaa", + "__meta_my_baz": "bbb", + "__meta_other": "ccc", + "my_bar": "aaa", + "my_baz": "bbb", + }, + }, } for i, test := range tests {