Fix combined tagdrop/tagpass filtering (#3031)

This commit is contained in:
DanKans 2017-07-19 21:08:40 +01:00 committed by Daniel Nelson
parent 6dd9bf5d1a
commit 7f3716b2b8
2 changed files with 60 additions and 2 deletions

View File

@ -175,7 +175,8 @@ func (f *Filter) shouldFieldPass(key string) bool {
// shouldTagsPass returns true if the metric should pass, false if should drop
// based on the tagdrop/tagpass filter parameters
func (f *Filter) shouldTagsPass(tags map[string]string) bool {
if f.TagPass != nil {
tagPass := func(f *Filter) bool {
for _, pat := range f.TagPass {
if pat.filter == nil {
continue
@ -189,7 +190,7 @@ func (f *Filter) shouldTagsPass(tags map[string]string) bool {
return false
}
if f.TagDrop != nil {
tagDrop := func(f *Filter) bool {
for _, pat := range f.TagDrop {
if pat.filter == nil {
continue
@ -203,6 +204,18 @@ func (f *Filter) shouldTagsPass(tags map[string]string) bool {
return true
}
// Add additional logic in case where both parameters are set.
// see: https://github.com/influxdata/telegraf/issues/2860
if f.TagPass != nil && f.TagDrop != nil {
// return true only in case when tag pass and won't be dropped (true, true).
// in case when the same tag should be passed and dropped it will be dropped (true, false).
return tagPass(f) && tagDrop(f)
} else if f.TagPass != nil {
return tagPass(f)
} else if f.TagDrop != nil {
return tagDrop(f)
}
return true
}

View File

@ -357,3 +357,48 @@ func TestFilter_FilterTagsMatches(t *testing.T) {
"mytag": "foobar",
}, pretags)
}
// TestFilter_FilterTagsPassAndDrop used for check case when
// both parameters were defined
// see: https://github.com/influxdata/telegraf/issues/2860
func TestFilter_FilterTagsPassAndDrop(t *testing.T) {
inputData := []map[string]string{
{"tag1": "1", "tag2": "3"},
{"tag1": "1", "tag2": "2"},
{"tag1": "2", "tag2": "1"},
{"tag1": "4", "tag2": "1"},
}
expectedResult := []bool{false, true, false, false}
filterPass := []TagFilter{
TagFilter{
Name: "tag1",
Filter: []string{"1", "4"},
},
}
filterDrop := []TagFilter{
TagFilter{
Name: "tag1",
Filter: []string{"4"},
},
TagFilter{
Name: "tag2",
Filter: []string{"3"},
},
}
f := Filter{
TagDrop: filterDrop,
TagPass: filterPass,
}
require.NoError(t, f.Compile())
for i, tag := range inputData {
assert.Equal(t, f.shouldTagsPass(tag), expectedResult[i])
}
}