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:
Julius Volz 2015-09-01 15:05:14 +02:00
parent dfbda8fd3f
commit f63a899744
6 changed files with 67 additions and 33 deletions

View file

@ -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
}

View file

@ -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,
},

View file

@ -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

View file

@ -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,
},

View file

@ -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,

View file

@ -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,