diff --git a/config/config.go b/config/config.go index 20950a043..d12c8d651 100644 --- a/config/config.go +++ b/config/config.go @@ -22,6 +22,8 @@ import ( "strings" "time" + "github.com/prometheus/prometheus/pkg/relabel" + config_util "github.com/prometheus/common/config" "github.com/prometheus/common/model" sd_config "github.com/prometheus/prometheus/discovery/config" @@ -29,8 +31,7 @@ import ( ) var ( - patRulePath = regexp.MustCompile(`^[^*]*(\*[^/]*)?$`) - relabelTarget = regexp.MustCompile(`^(?:(?:[a-zA-Z_]|\$(?:\{\w+\}|\w+))+\w*)+$`) + patRulePath = regexp.MustCompile(`^[^*]*(\*[^/]*)?$`) ) // Load parses the YAML input s into a Config. @@ -92,14 +93,6 @@ var ( Timeout: model.Duration(10 * time.Second), } - // DefaultRelabelConfig is the default Relabel configuration. - DefaultRelabelConfig = RelabelConfig{ - Action: RelabelReplace, - Separator: ";", - Regex: MustNewRegexp("(.*)"), - Replacement: "$1", - } - // DefaultRemoteWriteConfig is the default remote write configuration. DefaultRemoteWriteConfig = RemoteWriteConfig{ RemoteTimeout: model.Duration(30 * time.Second), @@ -350,9 +343,9 @@ type ScrapeConfig struct { HTTPClientConfig config_util.HTTPClientConfig `yaml:",inline"` // List of target relabel configurations. - RelabelConfigs []*RelabelConfig `yaml:"relabel_configs,omitempty"` + RelabelConfigs []*relabel.Config `yaml:"relabel_configs,omitempty"` // List of metric relabel configurations. - MetricRelabelConfigs []*RelabelConfig `yaml:"metric_relabel_configs,omitempty"` + MetricRelabelConfigs []*relabel.Config `yaml:"metric_relabel_configs,omitempty"` } // UnmarshalYAML implements the yaml.Unmarshaler interface. @@ -414,7 +407,7 @@ func (c *ScrapeConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { // AlertingConfig configures alerting and alertmanager related configs. type AlertingConfig struct { - AlertRelabelConfigs []*RelabelConfig `yaml:"alert_relabel_configs,omitempty"` + AlertRelabelConfigs []*relabel.Config `yaml:"alert_relabel_configs,omitempty"` AlertmanagerConfigs []*AlertmanagerConfig `yaml:"alertmanagers,omitempty"` } @@ -452,7 +445,7 @@ type AlertmanagerConfig struct { Timeout model.Duration `yaml:"timeout,omitempty"` // List of Alertmanager relabel configurations. - RelabelConfigs []*RelabelConfig `yaml:"relabel_configs,omitempty"` + RelabelConfigs []*relabel.Config `yaml:"relabel_configs,omitempty"` } // UnmarshalYAML implements the yaml.Unmarshaler interface. @@ -524,151 +517,11 @@ type FileSDConfig struct { RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"` } -// RelabelAction is the action to be performed on relabeling. -type RelabelAction string - -const ( - // RelabelReplace performs a regex replacement. - RelabelReplace RelabelAction = "replace" - // RelabelKeep drops targets for which the input does not match the regex. - RelabelKeep RelabelAction = "keep" - // RelabelDrop drops targets for which the input does match the regex. - RelabelDrop RelabelAction = "drop" - // RelabelHashMod sets a label to the modulus of a hash of labels. - RelabelHashMod RelabelAction = "hashmod" - // RelabelLabelMap copies labels to other labelnames based on a regex. - RelabelLabelMap RelabelAction = "labelmap" - // RelabelLabelDrop drops any label matching the regex. - RelabelLabelDrop RelabelAction = "labeldrop" - // RelabelLabelKeep drops any label not matching the regex. - RelabelLabelKeep RelabelAction = "labelkeep" -) - -// UnmarshalYAML implements the yaml.Unmarshaler interface. -func (a *RelabelAction) UnmarshalYAML(unmarshal func(interface{}) error) error { - var s string - if err := unmarshal(&s); err != nil { - return err - } - switch act := RelabelAction(strings.ToLower(s)); act { - case RelabelReplace, RelabelKeep, RelabelDrop, RelabelHashMod, RelabelLabelMap, RelabelLabelDrop, RelabelLabelKeep: - *a = act - return nil - } - return fmt.Errorf("unknown relabel action %q", s) -} - -// RelabelConfig is the configuration for relabeling of target label sets. -type RelabelConfig struct { - // A list of labels from which values are taken and concatenated - // with the configured separator in order. - SourceLabels model.LabelNames `yaml:"source_labels,flow,omitempty"` - // Separator is the string between concatenated values from the source labels. - Separator string `yaml:"separator,omitempty"` - // Regex against which the concatenation is matched. - Regex Regexp `yaml:"regex,omitempty"` - // Modulus to take of the hash of concatenated values from the source labels. - Modulus uint64 `yaml:"modulus,omitempty"` - // TargetLabel is the label to which the resulting string is written in a replacement. - // Regexp interpolation is allowed for the replace action. - TargetLabel string `yaml:"target_label,omitempty"` - // Replacement is the regex replacement pattern to be used. - Replacement string `yaml:"replacement,omitempty"` - // Action is the action to be performed for the relabeling. - Action RelabelAction `yaml:"action,omitempty"` -} - -// UnmarshalYAML implements the yaml.Unmarshaler interface. -func (c *RelabelConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { - *c = DefaultRelabelConfig - type plain RelabelConfig - if err := unmarshal((*plain)(c)); err != nil { - return err - } - if c.Regex.Regexp == nil { - c.Regex = MustNewRegexp("") - } - if c.Modulus == 0 && c.Action == RelabelHashMod { - return fmt.Errorf("relabel configuration for hashmod requires non-zero modulus") - } - if (c.Action == RelabelReplace || c.Action == RelabelHashMod) && c.TargetLabel == "" { - return fmt.Errorf("relabel configuration for %s action requires 'target_label' value", c.Action) - } - if c.Action == RelabelReplace && !relabelTarget.MatchString(c.TargetLabel) { - return fmt.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action) - } - if c.Action == RelabelLabelMap && !relabelTarget.MatchString(c.Replacement) { - return fmt.Errorf("%q is invalid 'replacement' for %s action", c.Replacement, c.Action) - } - if c.Action == RelabelHashMod && !model.LabelName(c.TargetLabel).IsValid() { - return fmt.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action) - } - - if c.Action == RelabelLabelDrop || c.Action == RelabelLabelKeep { - if c.SourceLabels != nil || - c.TargetLabel != DefaultRelabelConfig.TargetLabel || - c.Modulus != DefaultRelabelConfig.Modulus || - c.Separator != DefaultRelabelConfig.Separator || - c.Replacement != DefaultRelabelConfig.Replacement { - return fmt.Errorf("%s action requires only 'regex', and no other fields", c.Action) - } - } - - return nil -} - -// Regexp encapsulates a regexp.Regexp and makes it YAML marshalable. -type Regexp struct { - *regexp.Regexp - original string -} - -// NewRegexp creates a new anchored Regexp and returns an error if the -// passed-in regular expression does not compile. -func NewRegexp(s string) (Regexp, error) { - regex, err := regexp.Compile("^(?:" + s + ")$") - return Regexp{ - Regexp: regex, - original: s, - }, err -} - -// MustNewRegexp works like NewRegexp, but panics if the regular expression does not compile. -func MustNewRegexp(s string) Regexp { - re, err := NewRegexp(s) - if err != nil { - panic(err) - } - return re -} - -// UnmarshalYAML implements the yaml.Unmarshaler interface. -func (re *Regexp) UnmarshalYAML(unmarshal func(interface{}) error) error { - var s string - if err := unmarshal(&s); err != nil { - return err - } - r, err := NewRegexp(s) - if err != nil { - return err - } - *re = r - return nil -} - -// MarshalYAML implements the yaml.Marshaler interface. -func (re Regexp) MarshalYAML() (interface{}, error) { - if re.original != "" { - return re.original, nil - } - return nil, nil -} - // RemoteWriteConfig is the configuration for writing to remote storage. type RemoteWriteConfig struct { - URL *config_util.URL `yaml:"url"` - RemoteTimeout model.Duration `yaml:"remote_timeout,omitempty"` - WriteRelabelConfigs []*RelabelConfig `yaml:"write_relabel_configs,omitempty"` + URL *config_util.URL `yaml:"url"` + RemoteTimeout model.Duration `yaml:"remote_timeout,omitempty"` + WriteRelabelConfigs []*relabel.Config `yaml:"write_relabel_configs,omitempty"` // We cannot do proper Go type embedding below as the parser will then parse // values arbitrarily into the overflow maps of further-down types. diff --git a/config/config_test.go b/config/config_test.go index e04fd56d2..3cf099ce7 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -23,6 +23,8 @@ import ( "testing" "time" + "github.com/prometheus/prometheus/pkg/relabel" + "github.com/prometheus/prometheus/discovery/azure" "github.com/prometheus/prometheus/discovery/consul" "github.com/prometheus/prometheus/discovery/dns" @@ -71,13 +73,13 @@ var expectedConf = &Config{ { URL: mustParseURL("http://remote1/push"), RemoteTimeout: model.Duration(30 * time.Second), - WriteRelabelConfigs: []*RelabelConfig{ + WriteRelabelConfigs: []*relabel.Config{ { SourceLabels: model.LabelNames{"__name__"}, Separator: ";", - Regex: MustNewRegexp("expensive.*"), + Regex: relabel.MustNewRegexp("expensive.*"), Replacement: "$1", - Action: RelabelDrop, + Action: relabel.Drop, }, }, QueueConfig: DefaultQueueConfig, @@ -145,33 +147,33 @@ var expectedConf = &Config{ }, }, - RelabelConfigs: []*RelabelConfig{ + RelabelConfigs: []*relabel.Config{ { SourceLabels: model.LabelNames{"job", "__meta_dns_name"}, TargetLabel: "job", Separator: ";", - Regex: MustNewRegexp("(.*)some-[regex]"), + Regex: relabel.MustNewRegexp("(.*)some-[regex]"), Replacement: "foo-${1}", - Action: RelabelReplace, + Action: relabel.Replace, }, { SourceLabels: model.LabelNames{"abc"}, TargetLabel: "cde", Separator: ";", - Regex: DefaultRelabelConfig.Regex, - Replacement: DefaultRelabelConfig.Replacement, - Action: RelabelReplace, + Regex: relabel.DefaultRelabelConfig.Regex, + Replacement: relabel.DefaultRelabelConfig.Replacement, + Action: relabel.Replace, }, { TargetLabel: "abc", Separator: ";", - Regex: DefaultRelabelConfig.Regex, + Regex: relabel.DefaultRelabelConfig.Regex, Replacement: "static", - Action: RelabelReplace, + Action: relabel.Replace, }, { TargetLabel: "abc", Separator: ";", - Regex: MustNewRegexp(""), + Regex: relabel.MustNewRegexp(""), Replacement: "static", - Action: RelabelReplace, + Action: relabel.Replace, }, }, }, @@ -212,56 +214,56 @@ var expectedConf = &Config{ }, }, - RelabelConfigs: []*RelabelConfig{ + RelabelConfigs: []*relabel.Config{ { SourceLabels: model.LabelNames{"job"}, - Regex: MustNewRegexp("(.*)some-[regex]"), + Regex: relabel.MustNewRegexp("(.*)some-[regex]"), Separator: ";", - Replacement: DefaultRelabelConfig.Replacement, - Action: RelabelDrop, + Replacement: relabel.DefaultRelabelConfig.Replacement, + Action: relabel.Drop, }, { SourceLabels: model.LabelNames{"__address__"}, TargetLabel: "__tmp_hash", - Regex: DefaultRelabelConfig.Regex, - Replacement: DefaultRelabelConfig.Replacement, + Regex: relabel.DefaultRelabelConfig.Regex, + Replacement: relabel.DefaultRelabelConfig.Replacement, Modulus: 8, Separator: ";", - Action: RelabelHashMod, + Action: relabel.HashMod, }, { SourceLabels: model.LabelNames{"__tmp_hash"}, - Regex: MustNewRegexp("1"), + Regex: relabel.MustNewRegexp("1"), Separator: ";", - Replacement: DefaultRelabelConfig.Replacement, - Action: RelabelKeep, + Replacement: relabel.DefaultRelabelConfig.Replacement, + Action: relabel.Keep, }, { - Regex: MustNewRegexp("1"), + Regex: relabel.MustNewRegexp("1"), Separator: ";", - Replacement: DefaultRelabelConfig.Replacement, - Action: RelabelLabelMap, + Replacement: relabel.DefaultRelabelConfig.Replacement, + Action: relabel.LabelMap, }, { - Regex: MustNewRegexp("d"), + Regex: relabel.MustNewRegexp("d"), Separator: ";", - Replacement: DefaultRelabelConfig.Replacement, - Action: RelabelLabelDrop, + Replacement: relabel.DefaultRelabelConfig.Replacement, + Action: relabel.LabelDrop, }, { - Regex: MustNewRegexp("k"), + Regex: relabel.MustNewRegexp("k"), Separator: ";", - Replacement: DefaultRelabelConfig.Replacement, - Action: RelabelLabelKeep, + Replacement: relabel.DefaultRelabelConfig.Replacement, + Action: relabel.LabelKeep, }, }, - MetricRelabelConfigs: []*RelabelConfig{ + MetricRelabelConfigs: []*relabel.Config{ { SourceLabels: model.LabelNames{"__name__"}, - Regex: MustNewRegexp("expensive_metric.*"), + Regex: relabel.MustNewRegexp("expensive_metric.*"), Separator: ";", - Replacement: DefaultRelabelConfig.Replacement, - Action: RelabelDrop, + Replacement: relabel.DefaultRelabelConfig.Replacement, + Action: relabel.Drop, }, }, }, @@ -296,14 +298,14 @@ var expectedConf = &Config{ }, }, - RelabelConfigs: []*RelabelConfig{ + RelabelConfigs: []*relabel.Config{ { SourceLabels: model.LabelNames{"__meta_sd_consul_tags"}, - Regex: MustNewRegexp("label:([^=]+)=([^,]+)"), + Regex: relabel.MustNewRegexp("label:([^=]+)=([^,]+)"), Separator: ",", TargetLabel: "${1}", Replacement: "${2}", - Action: RelabelReplace, + Action: relabel.Replace, }, }, }, @@ -845,33 +847,6 @@ func TestEmptyGlobalBlock(t *testing.T) { testutil.Equals(t, exp, *c) } -func TestTargetLabelValidity(t *testing.T) { - tests := []struct { - str string - valid bool - }{ - {"-label", false}, - {"label", true}, - {"label${1}", true}, - {"${1}label", true}, - {"${1}", true}, - {"${1}label", true}, - {"${", false}, - {"$", false}, - {"${}", false}, - {"foo${", false}, - {"$1", true}, - {"asd$2asd", true}, - {"-foo${1}bar-", false}, - {"_${1}_", true}, - {"foo${bar}foo", true}, - } - for _, test := range tests { - testutil.Assert(t, relabelTarget.Match([]byte(test.str)) == test.valid, - "Expected %q to be %v", test.str, test.valid) - } -} - func kubernetesSDHostURL() config_util.URL { tURL, _ := url.Parse("https://localhost:1234") return config_util.URL{URL: tURL} diff --git a/notifier/notifier.go b/notifier/notifier.go index d1c7814ab..dbf5996cf 100644 --- a/notifier/notifier.go +++ b/notifier/notifier.go @@ -123,7 +123,7 @@ type Manager struct { type Options struct { QueueCapacity int ExternalLabels model.LabelSet - RelabelConfigs []*config.RelabelConfig + RelabelConfigs []*relabel.Config // Used for sending HTTP requests to the Alertmanager. Do func(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) diff --git a/notifier/notifier_test.go b/notifier/notifier_test.go index a98d7d714..c5646e8eb 100644 --- a/notifier/notifier_test.go +++ b/notifier/notifier_test.go @@ -25,6 +25,8 @@ import ( "testing" "time" + "github.com/prometheus/prometheus/pkg/relabel" + yaml "gopkg.in/yaml.v2" config_util "github.com/prometheus/common/config" @@ -236,12 +238,12 @@ func TestExternalLabels(t *testing.T) { h := NewManager(&Options{ QueueCapacity: 3 * maxBatchSize, ExternalLabels: model.LabelSet{"a": "b"}, - RelabelConfigs: []*config.RelabelConfig{ + RelabelConfigs: []*relabel.Config{ { SourceLabels: model.LabelNames{"alertname"}, TargetLabel: "a", Action: "replace", - Regex: config.MustNewRegexp("externalrelabelthis"), + Regex: relabel.MustNewRegexp("externalrelabelthis"), Replacement: "c", }, }, @@ -269,17 +271,17 @@ func TestExternalLabels(t *testing.T) { func TestHandlerRelabel(t *testing.T) { h := NewManager(&Options{ QueueCapacity: 3 * maxBatchSize, - RelabelConfigs: []*config.RelabelConfig{ + RelabelConfigs: []*relabel.Config{ { SourceLabels: model.LabelNames{"alertname"}, Action: "drop", - Regex: config.MustNewRegexp("drop"), + Regex: relabel.MustNewRegexp("drop"), }, { SourceLabels: model.LabelNames{"alertname"}, TargetLabel: "alertname", Action: "replace", - Regex: config.MustNewRegexp("rename"), + Regex: relabel.MustNewRegexp("rename"), Replacement: "renamed", }, }, diff --git a/pkg/relabel/relabel.go b/pkg/relabel/relabel.go index 4f215ca7f..4335201e7 100644 --- a/pkg/relabel/relabel.go +++ b/pkg/relabel/relabel.go @@ -16,19 +16,170 @@ package relabel import ( "crypto/md5" "fmt" + "regexp" "strings" "github.com/prometheus/common/model" - "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/pkg/labels" ) +var ( + relabelTarget = regexp.MustCompile(`^(?:(?:[a-zA-Z_]|\$(?:\{\w+\}|\w+))+\w*)+$`) + + DefaultRelabelConfig = Config{ + Action: Replace, + Separator: ";", + Regex: MustNewRegexp("(.*)"), + Replacement: "$1", + } +) + +// Action is the action to be performed on relabeling. +type Action string + +const ( + // Replace performs a regex replacement. + Replace Action = "replace" + // Keep drops targets for which the input does not match the regex. + Keep Action = "keep" + // Drop drops targets for which the input does match the regex. + Drop Action = "drop" + // HashMod sets a label to the modulus of a hash of labels. + HashMod Action = "hashmod" + // LabelMap copies labels to other labelnames based on a regex. + LabelMap Action = "labelmap" + // LabelDrop drops any label matching the regex. + LabelDrop Action = "labeldrop" + // LabelKeep drops any label not matching the regex. + LabelKeep Action = "labelkeep" +) + +// UnmarshalYAML implements the yaml.Unmarshaler interface. +func (a *Action) UnmarshalYAML(unmarshal func(interface{}) error) error { + var s string + if err := unmarshal(&s); err != nil { + return err + } + switch act := Action(strings.ToLower(s)); act { + case Replace, Keep, Drop, HashMod, LabelMap, LabelDrop, LabelKeep: + *a = act + return nil + } + return fmt.Errorf("unknown relabel action %q", s) +} + +// Config is the configuration for relabeling of target label sets. +type Config struct { + // A list of labels from which values are taken and concatenated + // with the configured separator in order. + SourceLabels model.LabelNames `yaml:"source_labels,flow,omitempty"` + // Separator is the string between concatenated values from the source labels. + Separator string `yaml:"separator,omitempty"` + // Regex against which the concatenation is matched. + Regex Regexp `yaml:"regex,omitempty"` + // Modulus to take of the hash of concatenated values from the source labels. + Modulus uint64 `yaml:"modulus,omitempty"` + // TargetLabel is the label to which the resulting string is written in a replacement. + // Regexp interpolation is allowed for the replace action. + TargetLabel string `yaml:"target_label,omitempty"` + // Replacement is the regex replacement pattern to be used. + Replacement string `yaml:"replacement,omitempty"` + // Action is the action to be performed for the relabeling. + Action Action `yaml:"action,omitempty"` +} + +// UnmarshalYAML implements the yaml.Unmarshaler interface. +func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { + *c = DefaultRelabelConfig + type plain Config + if err := unmarshal((*plain)(c)); err != nil { + return err + } + if c.Regex.Regexp == nil { + c.Regex = MustNewRegexp("") + } + if c.Modulus == 0 && c.Action == HashMod { + return fmt.Errorf("relabel configuration for hashmod requires non-zero modulus") + } + if (c.Action == Replace || c.Action == HashMod) && c.TargetLabel == "" { + return fmt.Errorf("relabel configuration for %s action requires 'target_label' value", c.Action) + } + if c.Action == Replace && !relabelTarget.MatchString(c.TargetLabel) { + return fmt.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action) + } + if c.Action == LabelMap && !relabelTarget.MatchString(c.Replacement) { + return fmt.Errorf("%q is invalid 'replacement' for %s action", c.Replacement, c.Action) + } + if c.Action == HashMod && !model.LabelName(c.TargetLabel).IsValid() { + return fmt.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action) + } + + if c.Action == LabelDrop || c.Action == LabelKeep { + if c.SourceLabels != nil || + c.TargetLabel != DefaultRelabelConfig.TargetLabel || + c.Modulus != DefaultRelabelConfig.Modulus || + c.Separator != DefaultRelabelConfig.Separator || + c.Replacement != DefaultRelabelConfig.Replacement { + return fmt.Errorf("%s action requires only 'regex', and no other fields", c.Action) + } + } + + return nil +} + +// Regexp encapsulates a regexp.Regexp and makes it YAML marshalable. +type Regexp struct { + *regexp.Regexp + original string +} + +// NewRegexp creates a new anchored Regexp and returns an error if the +// passed-in regular expression does not compile. +func NewRegexp(s string) (Regexp, error) { + regex, err := regexp.Compile("^(?:" + s + ")$") + return Regexp{ + Regexp: regex, + original: s, + }, err +} + +// MustNewRegexp works like NewRegexp, but panics if the regular expression does not compile. +func MustNewRegexp(s string) Regexp { + re, err := NewRegexp(s) + if err != nil { + panic(err) + } + return re +} + +// UnmarshalYAML implements the yaml.Unmarshaler interface. +func (re *Regexp) UnmarshalYAML(unmarshal func(interface{}) error) error { + var s string + if err := unmarshal(&s); err != nil { + return err + } + r, err := NewRegexp(s) + if err != nil { + return err + } + *re = r + return nil +} + +// MarshalYAML implements the yaml.Marshaler interface. +func (re Regexp) MarshalYAML() (interface{}, error) { + if re.original != "" { + return re.original, nil + } + return nil, nil +} + // Process returns a relabeled copy of the given label set. The relabel configurations // are applied in order of input. // If a label set is dropped, nil is returned. // May return the input labelSet modified. -func Process(labels labels.Labels, cfgs ...*config.RelabelConfig) labels.Labels { +func Process(labels labels.Labels, cfgs ...*Config) labels.Labels { for _, cfg := range cfgs { labels = relabel(labels, cfg) if labels == nil { @@ -38,7 +189,7 @@ func Process(labels labels.Labels, cfgs ...*config.RelabelConfig) labels.Labels return labels } -func relabel(lset labels.Labels, cfg *config.RelabelConfig) labels.Labels { +func relabel(lset labels.Labels, cfg *Config) labels.Labels { values := make([]string, 0, len(cfg.SourceLabels)) for _, ln := range cfg.SourceLabels { values = append(values, lset.Get(string(ln))) @@ -48,15 +199,15 @@ func relabel(lset labels.Labels, cfg *config.RelabelConfig) labels.Labels { lb := labels.NewBuilder(lset) switch cfg.Action { - case config.RelabelDrop: + case Drop: if cfg.Regex.MatchString(val) { return nil } - case config.RelabelKeep: + case Keep: if !cfg.Regex.MatchString(val) { return nil } - case config.RelabelReplace: + case Replace: indexes := cfg.Regex.FindStringSubmatchIndex(val) // If there is no match no replacement must take place. if indexes == nil { @@ -73,23 +224,23 @@ func relabel(lset labels.Labels, cfg *config.RelabelConfig) labels.Labels { break } lb.Set(string(target), string(res)) - case config.RelabelHashMod: + case HashMod: mod := sum64(md5.Sum([]byte(val))) % cfg.Modulus lb.Set(cfg.TargetLabel, fmt.Sprintf("%d", mod)) - case config.RelabelLabelMap: + case LabelMap: for _, l := range lset { if cfg.Regex.MatchString(l.Name) { res := cfg.Regex.ReplaceAllString(l.Name, cfg.Replacement) lb.Set(res, l.Value) } } - case config.RelabelLabelDrop: + case LabelDrop: for _, l := range lset { if cfg.Regex.MatchString(l.Name) { lb.Del(l.Name) } } - case config.RelabelLabelKeep: + case LabelKeep: for _, l := range lset { if !cfg.Regex.MatchString(l.Name) { lb.Del(l.Name) diff --git a/pkg/relabel/relabel_test.go b/pkg/relabel/relabel_test.go index dd3efa120..538ac6593 100644 --- a/pkg/relabel/relabel_test.go +++ b/pkg/relabel/relabel_test.go @@ -18,7 +18,6 @@ import ( "github.com/prometheus/common/model" - "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/util/testutil" ) @@ -26,7 +25,7 @@ import ( func TestRelabel(t *testing.T) { tests := []struct { input labels.Labels - relabel []*config.RelabelConfig + relabel []*Config output labels.Labels }{ { @@ -35,14 +34,14 @@ func TestRelabel(t *testing.T) { "b": "bar", "c": "baz", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f(.*)"), + Regex: MustNewRegexp("f(.*)"), TargetLabel: "d", Separator: ";", Replacement: "ch${1}-ch${1}", - Action: config.RelabelReplace, + Action: Replace, }, }, output: labels.FromMap(map[string]string{ @@ -58,22 +57,22 @@ func TestRelabel(t *testing.T) { "b": "bar", "c": "baz", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a", "b"}, - Regex: config.MustNewRegexp("f(.*);(.*)r"), + Regex: MustNewRegexp("f(.*);(.*)r"), TargetLabel: "a", Separator: ";", Replacement: "b${1}${2}m", // boobam - Action: config.RelabelReplace, + Action: Replace, }, { SourceLabels: model.LabelNames{"c", "a"}, - Regex: config.MustNewRegexp("(b).*b(.*)ba(.*)"), + Regex: MustNewRegexp("(b).*b(.*)ba(.*)"), TargetLabel: "d", Separator: ";", Replacement: "$1$2$2$3", - Action: config.RelabelReplace, + Action: Replace, }, }, output: labels.FromMap(map[string]string{ @@ -87,18 +86,18 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "foo", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp(".*o.*"), - Action: config.RelabelDrop, + Regex: MustNewRegexp(".*o.*"), + Action: Drop, }, { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f(.*)"), + Regex: MustNewRegexp("f(.*)"), TargetLabel: "d", Separator: ";", Replacement: "ch$1-ch$1", - Action: config.RelabelReplace, + Action: Replace, }, }, output: nil, @@ -108,11 +107,11 @@ func TestRelabel(t *testing.T) { "a": "foo", "b": "bar", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp(".*o.*"), - Action: config.RelabelDrop, + Regex: MustNewRegexp(".*o.*"), + Action: Drop, }, }, output: nil, @@ -121,14 +120,14 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "abc", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp(".*(b).*"), + Regex: MustNewRegexp(".*(b).*"), TargetLabel: "d", Separator: ";", Replacement: "$1", - Action: config.RelabelReplace, + Action: Replace, }, }, output: labels.FromMap(map[string]string{ @@ -140,11 +139,11 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "foo", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("no-match"), - Action: config.RelabelDrop, + Regex: MustNewRegexp("no-match"), + Action: Drop, }, }, output: labels.FromMap(map[string]string{ @@ -155,11 +154,11 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "foo", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f|o"), - Action: config.RelabelDrop, + Regex: MustNewRegexp("f|o"), + Action: Drop, }, }, output: labels.FromMap(map[string]string{ @@ -170,11 +169,11 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "foo", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("no-match"), - Action: config.RelabelKeep, + Regex: MustNewRegexp("no-match"), + Action: Keep, }, }, output: nil, @@ -183,11 +182,11 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "foo", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f.*"), - Action: config.RelabelKeep, + Regex: MustNewRegexp("f.*"), + Action: Keep, }, }, output: labels.FromMap(map[string]string{ @@ -199,13 +198,13 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "boo", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f"), + Regex: MustNewRegexp("f"), TargetLabel: "b", Replacement: "bar", - Action: config.RelabelReplace, + Action: Replace, }, }, output: labels.FromMap(map[string]string{ @@ -218,12 +217,12 @@ func TestRelabel(t *testing.T) { "b": "bar", "c": "baz", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"c"}, TargetLabel: "d", Separator: ";", - Action: config.RelabelHashMod, + Action: HashMod, Modulus: 1000, }, }, @@ -240,11 +239,11 @@ func TestRelabel(t *testing.T) { "b1": "bar", "b2": "baz", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { - Regex: config.MustNewRegexp("(b.*)"), + Regex: MustNewRegexp("(b.*)"), Replacement: "bar_${1}", - Action: config.RelabelLabelMap, + Action: LabelMap, }, }, output: labels.FromMap(map[string]string{ @@ -262,11 +261,11 @@ func TestRelabel(t *testing.T) { "__meta_my_baz": "bbb", "__meta_other": "ccc", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { - Regex: config.MustNewRegexp("__meta_(my.*)"), + Regex: MustNewRegexp("__meta_(my.*)"), Replacement: "${1}", - Action: config.RelabelLabelMap, + Action: LabelMap, }, }, output: labels.FromMap(map[string]string{ @@ -282,11 +281,11 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "some-name-value", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: Replace, Replacement: "${2}", TargetLabel: "${1}", }, @@ -300,11 +299,11 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "some-name-value", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: Replace, Replacement: "${3}", TargetLabel: "${1}", }, @@ -317,25 +316,25 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "a": "some-name-value", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: Replace, Replacement: "${1}", TargetLabel: "${3}", }, { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: Replace, Replacement: "${1}", TargetLabel: "0${3}", }, { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: Replace, Replacement: "${1}", TargetLabel: "-${3}", }, @@ -348,25 +347,25 @@ func TestRelabel(t *testing.T) { input: labels.FromMap(map[string]string{ "__meta_sd_tags": "path:/secret,job:some-job,label:foo=bar", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { SourceLabels: model.LabelNames{"__meta_sd_tags"}, - Regex: config.MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"), - Action: config.RelabelReplace, + Regex: MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"), + Action: Replace, Replacement: "${1}", TargetLabel: "__metrics_path__", }, { SourceLabels: model.LabelNames{"__meta_sd_tags"}, - Regex: config.MustNewRegexp("(?:.+,|^)job:([^,]+).*"), - Action: config.RelabelReplace, + Regex: MustNewRegexp("(?:.+,|^)job:([^,]+).*"), + Action: Replace, Replacement: "${1}", TargetLabel: "job", }, { SourceLabels: model.LabelNames{"__meta_sd_tags"}, - Regex: config.MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"), - Action: config.RelabelReplace, + Regex: MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"), + Action: Replace, Replacement: "${2}", TargetLabel: "${1}", }, @@ -384,10 +383,10 @@ func TestRelabel(t *testing.T) { "b1": "bar", "b2": "baz", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { - Regex: config.MustNewRegexp("(b.*)"), - Action: config.RelabelLabelKeep, + Regex: MustNewRegexp("(b.*)"), + Action: LabelKeep, }, }, output: labels.FromMap(map[string]string{ @@ -401,10 +400,10 @@ func TestRelabel(t *testing.T) { "b1": "bar", "b2": "baz", }), - relabel: []*config.RelabelConfig{ + relabel: []*Config{ { - Regex: config.MustNewRegexp("(b.*)"), - Action: config.RelabelLabelDrop, + Regex: MustNewRegexp("(b.*)"), + Action: LabelDrop, }, }, output: labels.FromMap(map[string]string{ @@ -418,3 +417,30 @@ func TestRelabel(t *testing.T) { testutil.Equals(t, test.output, res) } } + +func TestTargetLabelValidity(t *testing.T) { + tests := []struct { + str string + valid bool + }{ + {"-label", false}, + {"label", true}, + {"label${1}", true}, + {"${1}label", true}, + {"${1}", true}, + {"${1}label", true}, + {"${", false}, + {"$", false}, + {"${}", false}, + {"foo${", false}, + {"$1", true}, + {"asd$2asd", true}, + {"-foo${1}bar-", false}, + {"_${1}_", true}, + {"foo${bar}foo", true}, + } + for _, test := range tests { + testutil.Assert(t, relabelTarget.Match([]byte(test.str)) == test.valid, + "Expected %q to be %v", test.str, test.valid) + } +} diff --git a/relabel/relabel.go b/relabel/relabel.go index d506620f1..1b6bd7fb2 100644 --- a/relabel/relabel.go +++ b/relabel/relabel.go @@ -20,14 +20,16 @@ import ( "github.com/prometheus/common/model" - "github.com/prometheus/prometheus/config" + pkgrelabel "github.com/prometheus/prometheus/pkg/relabel" ) // Process returns a relabeled copy of the given label set. The relabel configurations // are applied in order of input. // If a label set is dropped, nil is returned. // May return the input labelSet modified. -func Process(labels model.LabelSet, cfgs ...*config.RelabelConfig) model.LabelSet { +// TODO(https://github.com/prometheus/prometheus/issues/3647): Get rid of this package in favor of pkg/relabel +// once usage of `model.LabelSet` is removed. +func Process(labels model.LabelSet, cfgs ...*pkgrelabel.Config) model.LabelSet { for _, cfg := range cfgs { labels = relabel(labels, cfg) if labels == nil { @@ -37,7 +39,7 @@ func Process(labels model.LabelSet, cfgs ...*config.RelabelConfig) model.LabelSe return labels } -func relabel(labels model.LabelSet, cfg *config.RelabelConfig) model.LabelSet { +func relabel(labels model.LabelSet, cfg *pkgrelabel.Config) model.LabelSet { values := make([]string, 0, len(cfg.SourceLabels)) for _, ln := range cfg.SourceLabels { values = append(values, string(labels[ln])) @@ -45,15 +47,15 @@ func relabel(labels model.LabelSet, cfg *config.RelabelConfig) model.LabelSet { val := strings.Join(values, cfg.Separator) switch cfg.Action { - case config.RelabelDrop: + case pkgrelabel.Drop: if cfg.Regex.MatchString(val) { return nil } - case config.RelabelKeep: + case pkgrelabel.Keep: if !cfg.Regex.MatchString(val) { return nil } - case config.RelabelReplace: + case pkgrelabel.Replace: indexes := cfg.Regex.FindStringSubmatchIndex(val) // If there is no match no replacement must take place. if indexes == nil { @@ -70,10 +72,10 @@ func relabel(labels model.LabelSet, cfg *config.RelabelConfig) model.LabelSet { break } labels[target] = model.LabelValue(res) - case config.RelabelHashMod: + case pkgrelabel.HashMod: mod := sum64(md5.Sum([]byte(val))) % cfg.Modulus labels[model.LabelName(cfg.TargetLabel)] = model.LabelValue(fmt.Sprintf("%d", mod)) - case config.RelabelLabelMap: + case pkgrelabel.LabelMap: out := make(model.LabelSet, len(labels)) // Take a copy to avoid infinite loops. for ln, lv := range labels { @@ -86,13 +88,13 @@ func relabel(labels model.LabelSet, cfg *config.RelabelConfig) model.LabelSet { } } labels = out - case config.RelabelLabelDrop: + case pkgrelabel.LabelDrop: for ln := range labels { if cfg.Regex.MatchString(string(ln)) { delete(labels, ln) } } - case config.RelabelLabelKeep: + case pkgrelabel.LabelKeep: for ln := range labels { if !cfg.Regex.MatchString(string(ln)) { delete(labels, ln) diff --git a/relabel/relabel_test.go b/relabel/relabel_test.go index 52ab2d10a..ae66d0880 100644 --- a/relabel/relabel_test.go +++ b/relabel/relabel_test.go @@ -18,14 +18,14 @@ import ( "github.com/prometheus/common/model" - "github.com/prometheus/prometheus/config" + pkgrelabel "github.com/prometheus/prometheus/pkg/relabel" "github.com/prometheus/prometheus/util/testutil" ) func TestRelabel(t *testing.T) { tests := []struct { input model.LabelSet - relabel []*config.RelabelConfig + relabel []*pkgrelabel.Config output model.LabelSet }{ { @@ -34,14 +34,14 @@ func TestRelabel(t *testing.T) { "b": "bar", "c": "baz", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f(.*)"), + Regex: pkgrelabel.MustNewRegexp("f(.*)"), TargetLabel: "d", Separator: ";", Replacement: "ch${1}-ch${1}", - Action: config.RelabelReplace, + Action: pkgrelabel.Replace, }, }, output: model.LabelSet{ @@ -57,22 +57,22 @@ func TestRelabel(t *testing.T) { "b": "bar", "c": "baz", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a", "b"}, - Regex: config.MustNewRegexp("f(.*);(.*)r"), + Regex: pkgrelabel.MustNewRegexp("f(.*);(.*)r"), TargetLabel: "a", Separator: ";", Replacement: "b${1}${2}m", // boobam - Action: config.RelabelReplace, + Action: pkgrelabel.Replace, }, { SourceLabels: model.LabelNames{"c", "a"}, - Regex: config.MustNewRegexp("(b).*b(.*)ba(.*)"), + Regex: pkgrelabel.MustNewRegexp("(b).*b(.*)ba(.*)"), TargetLabel: "d", Separator: ";", Replacement: "$1$2$2$3", - Action: config.RelabelReplace, + Action: pkgrelabel.Replace, }, }, output: model.LabelSet{ @@ -86,18 +86,18 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "foo", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp(".*o.*"), - Action: config.RelabelDrop, + Regex: pkgrelabel.MustNewRegexp(".*o.*"), + Action: pkgrelabel.Drop, }, { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f(.*)"), + Regex: pkgrelabel.MustNewRegexp("f(.*)"), TargetLabel: "d", Separator: ";", Replacement: "ch$1-ch$1", - Action: config.RelabelReplace, + Action: pkgrelabel.Replace, }, }, output: nil, @@ -107,11 +107,11 @@ func TestRelabel(t *testing.T) { "a": "foo", "b": "bar", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp(".*o.*"), - Action: config.RelabelDrop, + Regex: pkgrelabel.MustNewRegexp(".*o.*"), + Action: pkgrelabel.Drop, }, }, output: nil, @@ -120,14 +120,14 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "abc", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp(".*(b).*"), + Regex: pkgrelabel.MustNewRegexp(".*(b).*"), TargetLabel: "d", Separator: ";", Replacement: "$1", - Action: config.RelabelReplace, + Action: pkgrelabel.Replace, }, }, output: model.LabelSet{ @@ -139,11 +139,11 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "foo", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("no-match"), - Action: config.RelabelDrop, + Regex: pkgrelabel.MustNewRegexp("no-match"), + Action: pkgrelabel.Drop, }, }, output: model.LabelSet{ @@ -154,11 +154,11 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "foo", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f|o"), - Action: config.RelabelDrop, + Regex: pkgrelabel.MustNewRegexp("f|o"), + Action: pkgrelabel.Drop, }, }, output: model.LabelSet{ @@ -169,11 +169,11 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "foo", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("no-match"), - Action: config.RelabelKeep, + Regex: pkgrelabel.MustNewRegexp("no-match"), + Action: pkgrelabel.Keep, }, }, output: nil, @@ -182,11 +182,11 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "foo", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f.*"), - Action: config.RelabelKeep, + Regex: pkgrelabel.MustNewRegexp("f.*"), + Action: pkgrelabel.Keep, }, }, output: model.LabelSet{ @@ -198,13 +198,13 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "boo", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("f"), + Regex: pkgrelabel.MustNewRegexp("f"), TargetLabel: "b", Replacement: "bar", - Action: config.RelabelReplace, + Action: pkgrelabel.Replace, }, }, output: model.LabelSet{ @@ -217,12 +217,12 @@ func TestRelabel(t *testing.T) { "b": "bar", "c": "baz", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"c"}, TargetLabel: "d", Separator: ";", - Action: config.RelabelHashMod, + Action: pkgrelabel.HashMod, Modulus: 1000, }, }, @@ -239,11 +239,11 @@ func TestRelabel(t *testing.T) { "b1": "bar", "b2": "baz", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { - Regex: config.MustNewRegexp("(b.*)"), + Regex: pkgrelabel.MustNewRegexp("(b.*)"), Replacement: "bar_${1}", - Action: config.RelabelLabelMap, + Action: pkgrelabel.LabelMap, }, }, output: model.LabelSet{ @@ -261,11 +261,11 @@ func TestRelabel(t *testing.T) { "__meta_my_baz": "bbb", "__meta_other": "ccc", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { - Regex: config.MustNewRegexp("__meta_(my.*)"), + Regex: pkgrelabel.MustNewRegexp("__meta_(my.*)"), Replacement: "${1}", - Action: config.RelabelLabelMap, + Action: pkgrelabel.LabelMap, }, }, output: model.LabelSet{ @@ -281,11 +281,11 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "some-name-value", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: pkgrelabel.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: pkgrelabel.Replace, Replacement: "${2}", TargetLabel: "${1}", }, @@ -299,11 +299,11 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "some-name-value", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: pkgrelabel.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: pkgrelabel.Replace, Replacement: "${3}", TargetLabel: "${1}", }, @@ -316,25 +316,25 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "a": "some-name-value", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: pkgrelabel.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: pkgrelabel.Replace, Replacement: "${1}", TargetLabel: "${3}", }, { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: pkgrelabel.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: pkgrelabel.Replace, Replacement: "${1}", TargetLabel: "0${3}", }, { SourceLabels: model.LabelNames{"a"}, - Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), - Action: config.RelabelReplace, + Regex: pkgrelabel.MustNewRegexp("some-([^-]+)-([^,]+)"), + Action: pkgrelabel.Replace, Replacement: "${1}", TargetLabel: "-${3}", }, @@ -347,25 +347,25 @@ func TestRelabel(t *testing.T) { input: model.LabelSet{ "__meta_sd_tags": "path:/secret,job:some-job,label:foo=bar", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { SourceLabels: model.LabelNames{"__meta_sd_tags"}, - Regex: config.MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"), - Action: config.RelabelReplace, + Regex: pkgrelabel.MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"), + Action: pkgrelabel.Replace, Replacement: "${1}", TargetLabel: "__metrics_path__", }, { SourceLabels: model.LabelNames{"__meta_sd_tags"}, - Regex: config.MustNewRegexp("(?:.+,|^)job:([^,]+).*"), - Action: config.RelabelReplace, + Regex: pkgrelabel.MustNewRegexp("(?:.+,|^)job:([^,]+).*"), + Action: pkgrelabel.Replace, Replacement: "${1}", TargetLabel: "job", }, { SourceLabels: model.LabelNames{"__meta_sd_tags"}, - Regex: config.MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"), - Action: config.RelabelReplace, + Regex: pkgrelabel.MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"), + Action: pkgrelabel.Replace, Replacement: "${2}", TargetLabel: "${1}", }, @@ -383,10 +383,10 @@ func TestRelabel(t *testing.T) { "b1": "bar", "b2": "baz", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { - Regex: config.MustNewRegexp("(b.*)"), - Action: config.RelabelLabelKeep, + Regex: pkgrelabel.MustNewRegexp("(b.*)"), + Action: pkgrelabel.LabelKeep, }, }, output: model.LabelSet{ @@ -400,10 +400,10 @@ func TestRelabel(t *testing.T) { "b1": "bar", "b2": "baz", }, - relabel: []*config.RelabelConfig{ + relabel: []*pkgrelabel.Config{ { - Regex: config.MustNewRegexp("(b.*)"), - Action: config.RelabelLabelDrop, + Regex: pkgrelabel.MustNewRegexp("(b.*)"), + Action: pkgrelabel.LabelDrop, }, }, output: model.LabelSet{ diff --git a/scrape/manager_test.go b/scrape/manager_test.go index 8a2cd1d9e..fa0765785 100644 --- a/scrape/manager_test.go +++ b/scrape/manager_test.go @@ -19,6 +19,8 @@ import ( "testing" "time" + "github.com/prometheus/prometheus/pkg/relabel" + "github.com/prometheus/common/model" "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/discovery/targetgroup" @@ -28,14 +30,6 @@ import ( yaml "gopkg.in/yaml.v2" ) -func mustNewRegexp(s string) config.Regexp { - re, err := config.NewRegexp(s) - if err != nil { - panic(err) - } - return re -} - func TestPopulateLabels(t *testing.T) { cases := []struct { in labels.Labels @@ -144,10 +138,10 @@ func TestPopulateLabels(t *testing.T) { Scheme: "https", MetricsPath: "/metrics", JobName: "job", - RelabelConfigs: []*config.RelabelConfig{ + RelabelConfigs: []*relabel.Config{ { - Action: config.RelabelReplace, - Regex: mustNewRegexp("(.*)"), + Action: relabel.Replace, + Regex: relabel.MustNewRegexp("(.*)"), SourceLabels: model.LabelNames{"custom"}, Replacement: "${1}", TargetLabel: string(model.AddressLabel), @@ -176,10 +170,10 @@ func TestPopulateLabels(t *testing.T) { Scheme: "https", MetricsPath: "/metrics", JobName: "job", - RelabelConfigs: []*config.RelabelConfig{ + RelabelConfigs: []*relabel.Config{ { - Action: config.RelabelReplace, - Regex: mustNewRegexp("(.*)"), + Action: relabel.Replace, + Regex: relabel.MustNewRegexp("(.*)"), SourceLabels: model.LabelNames{"custom"}, Replacement: "${1}", TargetLabel: string(model.AddressLabel), @@ -249,7 +243,7 @@ scrape_configs: scrapeManager.ApplyConfig(cfg) // As reload never happens, new loop should never be called. - newLoop := func(_ *Target, s scraper, _ int, _ bool, _ []*config.RelabelConfig) loop { + newLoop := func(_ *Target, s scraper, _ int, _ bool, _ []*relabel.Config) loop { t.Fatal("reload happened") return nil } diff --git a/scrape/scrape.go b/scrape/scrape.go index 7fcc41d36..5c8650dcb 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -129,7 +129,7 @@ type scrapePool struct { cancel context.CancelFunc // Constructor for new scrape loops. This is settable for testing convenience. - newLoop func(*Target, scraper, int, bool, []*config.RelabelConfig) loop + newLoop func(*Target, scraper, int, bool, []*relabel.Config) loop } const maxAheadTime = 10 * time.Minute @@ -159,7 +159,7 @@ func newScrapePool(cfg *config.ScrapeConfig, app Appendable, logger log.Logger) loops: map[uint64]loop{}, logger: logger, } - sp.newLoop = func(t *Target, s scraper, limit int, honor bool, mrc []*config.RelabelConfig) loop { + sp.newLoop = func(t *Target, s scraper, limit int, honor bool, mrc []*relabel.Config) loop { // Update the targets retrieval function for metadata to a new scrape cache. cache := newScrapeCache() t.setMetadataStore(cache) @@ -366,7 +366,7 @@ func (sp *scrapePool) sync(targets []*Target) { wg.Wait() } -func mutateSampleLabels(lset labels.Labels, target *Target, honor bool, rc []*config.RelabelConfig) labels.Labels { +func mutateSampleLabels(lset labels.Labels, target *Target, honor bool, rc []*relabel.Config) labels.Labels { lb := labels.NewBuilder(lset) if honor { diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index 29cad0527..35e4eeecd 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -29,6 +29,8 @@ import ( "testing" "time" + "github.com/prometheus/prometheus/pkg/relabel" + "github.com/prometheus/common/model" "github.com/stretchr/testify/require" @@ -68,10 +70,10 @@ func TestDroppedTargetsList(t *testing.T) { cfg = &config.ScrapeConfig{ JobName: "dropMe", ScrapeInterval: model.Duration(1), - RelabelConfigs: []*config.RelabelConfig{ + RelabelConfigs: []*relabel.Config{ { - Action: config.RelabelDrop, - Regex: mustNewRegexp("dropMe"), + Action: relabel.Drop, + Regex: relabel.MustNewRegexp("dropMe"), SourceLabels: model.LabelNames{"job"}, }, }, @@ -219,7 +221,7 @@ func TestScrapePoolReload(t *testing.T) { } // On starting to run, new loops created on reload check whether their preceding // equivalents have been stopped. - newLoop := func(_ *Target, s scraper, _ int, _ bool, _ []*config.RelabelConfig) loop { + newLoop := func(_ *Target, s scraper, _ int, _ bool, _ []*relabel.Config) loop { l := &testLoop{} l.startFunc = func(interval, timeout time.Duration, errc chan<- error) { if interval != 3*time.Second { diff --git a/storage/remote/queue_manager.go b/storage/remote/queue_manager.go index 50d1a0563..4c5368382 100644 --- a/storage/remote/queue_manager.go +++ b/storage/remote/queue_manager.go @@ -27,6 +27,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/config" + pkgrelabel "github.com/prometheus/prometheus/pkg/relabel" "github.com/prometheus/prometheus/prompb" "github.com/prometheus/prometheus/relabel" ) @@ -144,7 +145,7 @@ type QueueManager struct { flushDeadline time.Duration cfg config.QueueConfig externalLabels model.LabelSet - relabelConfigs []*config.RelabelConfig + relabelConfigs []*pkgrelabel.Config client StorageClient queueName string logLimiter *rate.Limiter @@ -161,7 +162,7 @@ type QueueManager struct { } // NewQueueManager builds a new QueueManager. -func NewQueueManager(logger log.Logger, cfg config.QueueConfig, externalLabels model.LabelSet, relabelConfigs []*config.RelabelConfig, client StorageClient, flushDeadline time.Duration) *QueueManager { +func NewQueueManager(logger log.Logger, cfg config.QueueConfig, externalLabels model.LabelSet, relabelConfigs []*pkgrelabel.Config, client StorageClient, flushDeadline time.Duration) *QueueManager { if logger == nil { logger = log.NewNopLogger() } else {