mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Add lowercase and uppercase relabel action (#10641)
Signed-off-by: Julien Pivotto <roidelapluie@o11y.eu>
This commit is contained in:
parent
4e6374180d
commit
71dbb4d091
|
@ -858,6 +858,17 @@ var expectedConf = &Config{
|
|||
Scheme: DefaultScrapeConfig.Scheme,
|
||||
HTTPClientConfig: config.DefaultHTTPClientConfig,
|
||||
|
||||
RelabelConfigs: []*relabel.Config{
|
||||
{
|
||||
Action: relabel.Uppercase,
|
||||
Regex: relabel.DefaultRelabelConfig.Regex,
|
||||
Replacement: relabel.DefaultRelabelConfig.Replacement,
|
||||
Separator: relabel.DefaultRelabelConfig.Separator,
|
||||
SourceLabels: model.LabelNames{"instance"},
|
||||
TargetLabel: "instance",
|
||||
},
|
||||
},
|
||||
|
||||
ServiceDiscoveryConfigs: discovery.Configs{
|
||||
&hetzner.SDConfig{
|
||||
HTTPClientConfig: config.HTTPClientConfig{
|
||||
|
@ -1197,6 +1208,30 @@ var expectedErrors = []struct {
|
|||
filename: "labelmap.bad.yml",
|
||||
errMsg: "\"l-$1\" is invalid 'replacement' for labelmap action",
|
||||
},
|
||||
{
|
||||
filename: "lowercase.bad.yml",
|
||||
errMsg: "relabel configuration for lowercase action requires 'target_label' value",
|
||||
},
|
||||
{
|
||||
filename: "lowercase2.bad.yml",
|
||||
errMsg: "\"42lab\" is invalid 'target_label' for lowercase action",
|
||||
},
|
||||
{
|
||||
filename: "lowercase3.bad.yml",
|
||||
errMsg: "'replacement' can not be set for lowercase action",
|
||||
},
|
||||
{
|
||||
filename: "uppercase.bad.yml",
|
||||
errMsg: "relabel configuration for uppercase action requires 'target_label' value",
|
||||
},
|
||||
{
|
||||
filename: "uppercase2.bad.yml",
|
||||
errMsg: "\"42lab\" is invalid 'target_label' for uppercase action",
|
||||
},
|
||||
{
|
||||
filename: "uppercase3.bad.yml",
|
||||
errMsg: "'replacement' can not be set for uppercase action",
|
||||
},
|
||||
{
|
||||
filename: "rules.bad.yml",
|
||||
errMsg: "invalid rule file path",
|
||||
|
|
4
config/testdata/conf.good.yml
vendored
4
config/testdata/conf.good.yml
vendored
|
@ -328,6 +328,10 @@ scrape_configs:
|
|||
key_file: valid_key_file
|
||||
|
||||
- job_name: hetzner
|
||||
relabel_configs:
|
||||
- action: uppercase
|
||||
source_labels: [instance]
|
||||
target_label: instance
|
||||
hetzner_sd_configs:
|
||||
- role: hcloud
|
||||
authorization:
|
||||
|
|
5
config/testdata/lowercase.bad.yml
vendored
Normal file
5
config/testdata/lowercase.bad.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
relabel_configs:
|
||||
- action: lowercase
|
||||
source_labels: [__name__]
|
6
config/testdata/lowercase2.bad.yml
vendored
Normal file
6
config/testdata/lowercase2.bad.yml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
relabel_configs:
|
||||
- action: lowercase
|
||||
source_labels: [__name__]
|
||||
target_label: 42lab
|
7
config/testdata/lowercase3.bad.yml
vendored
Normal file
7
config/testdata/lowercase3.bad.yml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
relabel_configs:
|
||||
- action: lowercase
|
||||
source_labels: [__name__]
|
||||
target_label: __name__
|
||||
replacement: bar
|
5
config/testdata/uppercase.bad.yml
vendored
Normal file
5
config/testdata/uppercase.bad.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
relabel_configs:
|
||||
- action: uppercase
|
||||
source_labels: [__name__]
|
6
config/testdata/uppercase2.bad.yml
vendored
Normal file
6
config/testdata/uppercase2.bad.yml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
relabel_configs:
|
||||
- action: uppercase
|
||||
source_labels: [__name__]
|
||||
target_label: 42lab
|
7
config/testdata/uppercase3.bad.yml
vendored
Normal file
7
config/testdata/uppercase3.bad.yml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
relabel_configs:
|
||||
- action: uppercase
|
||||
source_labels: [__name__]
|
||||
target_label: __name__
|
||||
replacement: bar
|
|
@ -2536,6 +2536,8 @@ anchored on both ends. To un-anchor the regex, use `.*<regex>.*`.
|
|||
`target_label` to `replacement`, with match group references
|
||||
(`${1}`, `${2}`, ...) in `replacement` substituted by their value. If `regex`
|
||||
does not match, no replacement takes place.
|
||||
* `lowercase`: Maps the concatenated `source_labels` to their lower case.
|
||||
* `uppercase`: Maps the concatenated `source_labels` to their upper case.
|
||||
* `keep`: Drop targets for which `regex` does not match the concatenated `source_labels`.
|
||||
* `drop`: Drop targets for which `regex` matches the concatenated `source_labels`.
|
||||
* `hashmod`: Set `target_label` to the `modulus` of a hash of the concatenated `source_labels`.
|
||||
|
|
|
@ -54,6 +54,10 @@ const (
|
|||
LabelDrop Action = "labeldrop"
|
||||
// LabelKeep drops any label not matching the regex.
|
||||
LabelKeep Action = "labelkeep"
|
||||
// Lowercase maps input letters to their lower case.
|
||||
Lowercase Action = "lowercase"
|
||||
// Uppercase maps input letters to their upper case.
|
||||
Uppercase Action = "uppercase"
|
||||
)
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
|
@ -63,7 +67,7 @@ func (a *Action) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
return err
|
||||
}
|
||||
switch act := Action(strings.ToLower(s)); act {
|
||||
case Replace, Keep, Drop, HashMod, LabelMap, LabelDrop, LabelKeep:
|
||||
case Replace, Keep, Drop, HashMod, LabelMap, LabelDrop, LabelKeep, Lowercase, Uppercase:
|
||||
*a = act
|
||||
return nil
|
||||
}
|
||||
|
@ -106,12 +110,15 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
if c.Modulus == 0 && c.Action == HashMod {
|
||||
return errors.Errorf("relabel configuration for hashmod requires non-zero modulus")
|
||||
}
|
||||
if (c.Action == Replace || c.Action == HashMod) && c.TargetLabel == "" {
|
||||
if (c.Action == Replace || c.Action == HashMod || c.Action == Lowercase || c.Action == Uppercase) && c.TargetLabel == "" {
|
||||
return errors.Errorf("relabel configuration for %s action requires 'target_label' value", c.Action)
|
||||
}
|
||||
if c.Action == Replace && !relabelTarget.MatchString(c.TargetLabel) {
|
||||
if (c.Action == Replace || c.Action == Lowercase || c.Action == Uppercase) && !relabelTarget.MatchString(c.TargetLabel) {
|
||||
return errors.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action)
|
||||
}
|
||||
if (c.Action == Lowercase || c.Action == Uppercase) && c.Replacement != DefaultRelabelConfig.Replacement {
|
||||
return errors.Errorf("'replacement' can not be set for %s action", c.Action)
|
||||
}
|
||||
if c.Action == LabelMap && !relabelTarget.MatchString(c.Replacement) {
|
||||
return errors.Errorf("%q is invalid 'replacement' for %s action", c.Replacement, c.Action)
|
||||
}
|
||||
|
@ -228,6 +235,10 @@ func relabel(lset labels.Labels, cfg *Config) labels.Labels {
|
|||
break
|
||||
}
|
||||
lb.Set(string(target), string(res))
|
||||
case Lowercase:
|
||||
lb.Set(cfg.TargetLabel, strings.ToLower(val))
|
||||
case Uppercase:
|
||||
lb.Set(cfg.TargetLabel, strings.ToUpper(val))
|
||||
case HashMod:
|
||||
mod := sum64(md5.Sum([]byte(val))) % cfg.Modulus
|
||||
lb.Set(cfg.TargetLabel, fmt.Sprintf("%d", mod))
|
||||
|
|
|
@ -428,6 +428,28 @@ func TestRelabel(t *testing.T) {
|
|||
"a": "foo",
|
||||
}),
|
||||
},
|
||||
{
|
||||
input: labels.FromMap(map[string]string{
|
||||
"foo": "bAr123Foo",
|
||||
}),
|
||||
relabel: []*Config{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"foo"},
|
||||
Action: Uppercase,
|
||||
TargetLabel: "foo_uppercase",
|
||||
},
|
||||
{
|
||||
SourceLabels: model.LabelNames{"foo"},
|
||||
Action: Lowercase,
|
||||
TargetLabel: "foo_lowercase",
|
||||
},
|
||||
},
|
||||
output: labels.FromMap(map[string]string{
|
||||
"foo": "bAr123Foo",
|
||||
"foo_lowercase": "bar123foo",
|
||||
"foo_uppercase": "BAR123FOO",
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
Loading…
Reference in a new issue