Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Drop Strings Processor #3763

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/processors/all/all.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package all

import (
_ "github.com/influxdata/telegraf/plugins/processors/drop_strings"
_ "github.com/influxdata/telegraf/plugins/processors/printer"
)
14 changes: 14 additions & 0 deletions plugins/processors/drop_strings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Drop Strings Processor Plugin

The drop strings processor plugin drops all fields of type string.

### Configuration:

```toml
# Drop all fields of type string, that pass through this processor.
[[processors.drop_strings]]
```

### Tags:

No tags are applied by this processor.
60 changes: 60 additions & 0 deletions plugins/processors/drop_strings/drop_strings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package drop_strings

import (
"fmt"

"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
"github.com/influxdata/telegraf/plugins/processors"
)

type DropStrings struct {
}

var sampleConfig = `
`

func (d *DropStrings) SampleConfig() string {
return sampleConfig
}

func (d *DropStrings) Description() string {
return "Drops all metrics of type string that pass through this filter."
}

func (d *DropStrings) Apply(in ...telegraf.Metric) []telegraf.Metric {
out := make([]telegraf.Metric, 0, len(in))
for _, source := range in {
target, error := dropStrings(source)
if error == nil {
out = append(out, target)
}
}
return out
}

func dropStrings(source telegraf.Metric) (telegraf.Metric, error) {
inFields := source.Fields()
outFields := make(map[string]interface{}, len(inFields))
changed := false
for key, value := range inFields {
if _, drop := value.(string); !drop {
outFields[key] = value
} else {
changed = true
}
}
if !changed {
return source, nil
}
if changed && len(outFields) > 0 {
return metric.New(source.Name(), source.Tags(), outFields, source.Time(), source.Type())
}
return nil, fmt.Errorf("No more fields in metric '%s'", source.Name())
}

func init() {
processors.Add("drop_strings", func() telegraf.Processor {
return &DropStrings{}
})
}
60 changes: 60 additions & 0 deletions plugins/processors/drop_strings/drop_strings_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package drop_strings

import (
"testing"
"time"

"github.com/influxdata/telegraf/metric"
"github.com/stretchr/testify/assert"
)

func TestDropStrings(t *testing.T) {
var metric, _ = metric.New("Test Metric",
map[string]string{"state": "full"},
map[string]interface{}{
"integer": int64(23),
"float": float64(3.1415),
"bool": true,
"string": "should be dropped",
},
time.Now(),
)

dropStrings := DropStrings{}

result := dropStrings.Apply(metric)[0]
fields := result.Fields()

assert.NotContains(t, fields, "string")

assertFieldValue(t, int64(23), "integer", fields)
assertFieldValue(t, float64(3.1415), "float", fields)
assertFieldValue(t, true, "bool", fields)

assert.Equal(t, "Test Metric", result.Name())
assert.Equal(t, metric.Tags(), result.Tags())
assert.Equal(t, metric.Time(), result.Time())
}

func assertFieldValue(t *testing.T, expected interface{}, field string, fields map[string]interface{}) {
value, present := fields[field]
assert.True(t, present, "value of field '"+field+"' was not present")
assert.EqualValues(t, expected, value)
}

func TestDropEntireMetricIfOnlyStrings(t *testing.T) {
var metric, _ = metric.New("Test Metric",
map[string]string{"state": "full"},
map[string]interface{}{
"string1": "should be dropped",
"string2": "should be dropped, also",
},
time.Now(),
)

dropStrings := DropStrings{}

result := dropStrings.Apply(metric)

assert.Len(t, result, 0, "No metric should be emitted.")
}