From 34c042c7dc29b96b2fbdbf3ff352e2cd6519b015 Mon Sep 17 00:00:00 2001 From: DanKans Date: Wed, 19 Jul 2017 21:08:40 +0100 Subject: [PATCH] Fix combined tagdrop/tagpass filtering (#3031) --- internal/models/filter.go | 17 +++++++++++-- internal/models/filter_test.go | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/internal/models/filter.go b/internal/models/filter.go index 8e080f4a8..445ce3434 100644 --- a/internal/models/filter.go +++ b/internal/models/filter.go @@ -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 } diff --git a/internal/models/filter_test.go b/internal/models/filter_test.go index 95b63e30a..5bbbc4a8f 100644 --- a/internal/models/filter_test.go +++ b/internal/models/filter_test.go @@ -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]) + } + +}