mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Change config regexes to full-string matches.
This anchors all regular expressions entered via the config to match a full string vs. a substring. THIS IS A BREAKING CHANGE! Fixes part of https://github.com/prometheus/prometheus/issues/996
This commit is contained in:
parent
dfbda8fd3f
commit
f63a899744
|
@ -723,6 +723,29 @@ func (c *RelabelConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
// Regexp encapsulates a regexp.Regexp and makes it YAML marshallable.
|
||||
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 + ")$")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Regexp{
|
||||
Regexp: *regex,
|
||||
original: s,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
@ -731,18 +754,18 @@ func (re *Regexp) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
if err := unmarshal(&s); err != nil {
|
||||
return err
|
||||
}
|
||||
regex, err := regexp.Compile(s)
|
||||
r, err := NewRegexp(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
re.Regexp = *regex
|
||||
*re = *r
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalYAML implements the yaml.Marshaler interface.
|
||||
func (re *Regexp) MarshalYAML() (interface{}, error) {
|
||||
if re != nil {
|
||||
return re.String(), nil
|
||||
return re.original, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -86,7 +85,7 @@ var expectedConf = &Config{
|
|||
SourceLabels: model.LabelNames{"job", "__meta_dns_srv_name"},
|
||||
TargetLabel: "job",
|
||||
Separator: ";",
|
||||
Regex: &Regexp{*regexp.MustCompile("(.*)some-[regex]$")},
|
||||
Regex: MustNewRegexp("(.*)some-[regex]"),
|
||||
Replacement: "foo-${1}",
|
||||
Action: RelabelReplace,
|
||||
},
|
||||
|
@ -126,7 +125,7 @@ var expectedConf = &Config{
|
|||
RelabelConfigs: []*RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"job"},
|
||||
Regex: &Regexp{*regexp.MustCompile("(.*)some-[regex]$")},
|
||||
Regex: MustNewRegexp("(.*)some-[regex]"),
|
||||
Separator: ";",
|
||||
Action: RelabelDrop,
|
||||
},
|
||||
|
@ -139,7 +138,7 @@ var expectedConf = &Config{
|
|||
},
|
||||
{
|
||||
SourceLabels: model.LabelNames{"__tmp_hash"},
|
||||
Regex: &Regexp{*regexp.MustCompile("^1$")},
|
||||
Regex: MustNewRegexp("1"),
|
||||
Separator: ";",
|
||||
Action: RelabelKeep,
|
||||
},
|
||||
|
@ -147,7 +146,7 @@ var expectedConf = &Config{
|
|||
MetricRelabelConfigs: []*RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"__name__"},
|
||||
Regex: &Regexp{*regexp.MustCompile("expensive_metric.*$")},
|
||||
Regex: MustNewRegexp("expensive_metric.*"),
|
||||
Separator: ";",
|
||||
Action: RelabelDrop,
|
||||
},
|
||||
|
|
8
config/testdata/conf.good.yml
vendored
8
config/testdata/conf.good.yml
vendored
|
@ -40,7 +40,7 @@ scrape_configs:
|
|||
|
||||
relabel_configs:
|
||||
- source_labels: [job, __meta_dns_srv_name]
|
||||
regex: (.*)some-[regex]$
|
||||
regex: (.*)some-[regex]
|
||||
target_label: job
|
||||
replacement: foo-${1}
|
||||
# action defaults to 'replace'
|
||||
|
@ -71,19 +71,19 @@ scrape_configs:
|
|||
|
||||
relabel_configs:
|
||||
- source_labels: [job]
|
||||
regex: (.*)some-[regex]$
|
||||
regex: (.*)some-[regex]
|
||||
action: drop
|
||||
- source_labels: [__address__]
|
||||
modulus: 8
|
||||
target_label: __tmp_hash
|
||||
action: hashmod
|
||||
- source_labels: [__tmp_hash]
|
||||
regex: ^1$
|
||||
regex: 1
|
||||
action: keep
|
||||
|
||||
metric_relabel_configs:
|
||||
- source_labels: [__name__]
|
||||
regex: expensive_metric.*$
|
||||
regex: expensive_metric.*
|
||||
action: drop
|
||||
|
||||
- job_name: service-y
|
||||
|
|
|
@ -15,7 +15,6 @@ package retrieval
|
|||
|
||||
import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus/common/model"
|
||||
|
@ -38,7 +37,7 @@ func TestRelabel(t *testing.T) {
|
|||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("f(.*)")},
|
||||
Regex: config.MustNewRegexp("f(.*)"),
|
||||
TargetLabel: model.LabelName("d"),
|
||||
Separator: ";",
|
||||
Replacement: "ch${1}-ch${1}",
|
||||
|
@ -61,7 +60,7 @@ func TestRelabel(t *testing.T) {
|
|||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a", "b"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("^f(.*);(.*)r$")},
|
||||
Regex: config.MustNewRegexp("f(.*);(.*)r"),
|
||||
TargetLabel: model.LabelName("a"),
|
||||
Separator: ";",
|
||||
Replacement: "b${1}${2}m", // boobam
|
||||
|
@ -69,7 +68,7 @@ func TestRelabel(t *testing.T) {
|
|||
},
|
||||
{
|
||||
SourceLabels: model.LabelNames{"c", "a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("(b).*b(.*)ba(.*)")},
|
||||
Regex: config.MustNewRegexp("(b).*b(.*)ba(.*)"),
|
||||
TargetLabel: model.LabelName("d"),
|
||||
Separator: ";",
|
||||
Replacement: "$1$2$2$3",
|
||||
|
@ -90,11 +89,11 @@ func TestRelabel(t *testing.T) {
|
|||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("o$")},
|
||||
Regex: config.MustNewRegexp(".*o.*"),
|
||||
Action: config.RelabelDrop,
|
||||
}, {
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("f(.*)")},
|
||||
Regex: config.MustNewRegexp("f(.*)"),
|
||||
TargetLabel: model.LabelName("d"),
|
||||
Separator: ";",
|
||||
Replacement: "ch$1-ch$1",
|
||||
|
@ -110,7 +109,7 @@ func TestRelabel(t *testing.T) {
|
|||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("(b)")},
|
||||
Regex: config.MustNewRegexp(".*(b).*"),
|
||||
TargetLabel: model.LabelName("d"),
|
||||
Separator: ";",
|
||||
Replacement: "$1",
|
||||
|
@ -129,7 +128,7 @@ func TestRelabel(t *testing.T) {
|
|||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("no-match")},
|
||||
Regex: config.MustNewRegexp("no-match"),
|
||||
Action: config.RelabelDrop,
|
||||
},
|
||||
},
|
||||
|
@ -144,7 +143,22 @@ func TestRelabel(t *testing.T) {
|
|||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("no-match")},
|
||||
Regex: config.MustNewRegexp("f|o"),
|
||||
Action: config.RelabelDrop,
|
||||
},
|
||||
},
|
||||
output: model.LabelSet{
|
||||
"a": "foo",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: model.LabelSet{
|
||||
"a": "foo",
|
||||
},
|
||||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: config.MustNewRegexp("no-match"),
|
||||
Action: config.RelabelKeep,
|
||||
},
|
||||
},
|
||||
|
@ -157,7 +171,7 @@ func TestRelabel(t *testing.T) {
|
|||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("^f")},
|
||||
Regex: config.MustNewRegexp("f.*"),
|
||||
Action: config.RelabelKeep,
|
||||
},
|
||||
},
|
||||
|
@ -173,7 +187,7 @@ func TestRelabel(t *testing.T) {
|
|||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"a"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("^f")},
|
||||
Regex: config.MustNewRegexp("f"),
|
||||
TargetLabel: model.LabelName("b"),
|
||||
Replacement: "bar",
|
||||
Action: config.RelabelReplace,
|
||||
|
@ -213,7 +227,7 @@ func TestRelabel(t *testing.T) {
|
|||
},
|
||||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
Regex: &config.Regexp{*regexp.MustCompile("^(b.*)")},
|
||||
Regex: config.MustNewRegexp("(b.*)"),
|
||||
Replacement: "bar_${1}",
|
||||
Action: config.RelabelLabelMap,
|
||||
},
|
||||
|
@ -235,7 +249,7 @@ func TestRelabel(t *testing.T) {
|
|||
},
|
||||
relabel: []*config.RelabelConfig{
|
||||
{
|
||||
Regex: &config.Regexp{*regexp.MustCompile("^__meta_(my.*)")},
|
||||
Regex: config.MustNewRegexp("__meta_(my.*)"),
|
||||
Replacement: "${1}",
|
||||
Action: config.RelabelLabelMap,
|
||||
},
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"net/http/httptest"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -181,12 +180,12 @@ func TestTargetScrapeMetricRelabelConfigs(t *testing.T) {
|
|||
testTarget.metricRelabelConfigs = []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{"__name__"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile(".*drop.*")},
|
||||
Regex: config.MustNewRegexp(".*drop.*"),
|
||||
Action: config.RelabelDrop,
|
||||
},
|
||||
{
|
||||
SourceLabels: model.LabelNames{"__name__"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile(".*(relabel|up).*")},
|
||||
Regex: config.MustNewRegexp(".*(relabel|up).*"),
|
||||
TargetLabel: "foo",
|
||||
Replacement: "bar",
|
||||
Action: config.RelabelReplace,
|
||||
|
|
|
@ -16,7 +16,6 @@ package retrieval
|
|||
import (
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -219,7 +218,7 @@ func TestTargetManagerConfigUpdate(t *testing.T) {
|
|||
{
|
||||
// Copy out the URL parameter.
|
||||
SourceLabels: model.LabelNames{"__param_testParam"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("^(.*)$")},
|
||||
Regex: config.MustNewRegexp("(.*)"),
|
||||
TargetLabel: "testParam",
|
||||
Replacement: "$1",
|
||||
Action: config.RelabelReplace,
|
||||
|
@ -255,7 +254,7 @@ func TestTargetManagerConfigUpdate(t *testing.T) {
|
|||
RelabelConfigs: []*config.RelabelConfig{
|
||||
{
|
||||
SourceLabels: model.LabelNames{model.AddressLabel},
|
||||
Regex: &config.Regexp{*regexp.MustCompile(`^test\.(.*?):(.*)`)},
|
||||
Regex: config.MustNewRegexp(`test\.(.*?):(.*)`),
|
||||
Replacement: "foo.${1}:${2}",
|
||||
TargetLabel: model.AddressLabel,
|
||||
Action: config.RelabelReplace,
|
||||
|
@ -263,7 +262,7 @@ func TestTargetManagerConfigUpdate(t *testing.T) {
|
|||
{
|
||||
// Add a new label for example.* targets.
|
||||
SourceLabels: model.LabelNames{model.AddressLabel, "boom", "foo"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile("^example.*?-b([a-z-]+)r$")},
|
||||
Regex: config.MustNewRegexp("example.*?-b([a-z-]+)r"),
|
||||
TargetLabel: "new",
|
||||
Replacement: "$1",
|
||||
Separator: "-",
|
||||
|
@ -272,7 +271,7 @@ func TestTargetManagerConfigUpdate(t *testing.T) {
|
|||
{
|
||||
// Drop an existing label.
|
||||
SourceLabels: model.LabelNames{"boom"},
|
||||
Regex: &config.Regexp{*regexp.MustCompile(".*")},
|
||||
Regex: config.MustNewRegexp(".*"),
|
||||
TargetLabel: "boom",
|
||||
Replacement: "",
|
||||
Action: config.RelabelReplace,
|
||||
|
|
Loading…
Reference in a new issue