Skip to content

Commit

Permalink
feat(processor/regex): Add ability to check every tag for regex repla…
Browse files Browse the repository at this point in the history
…ce (#10927)
  • Loading branch information
PhoenixRion committed Apr 14, 2022
1 parent 351ab58 commit 577c046
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 8 deletions.
2 changes: 1 addition & 1 deletion plugins/processors/regex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ For metrics transforms, `key` denotes the element that should be transformed. Fu

# Tag and field conversions defined in a separate sub-tables
[[processors.regex.tags]]
## Tag to change
## Tag to change, "*" will change every tag
key = "resp_code"
## Regular expression to match on a tag value
pattern = "^(\\d)\\d\\d$"
Expand Down
26 changes: 19 additions & 7 deletions plugins/processors/regex/regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,17 @@ func (r *Regex) Init() error {
func (r *Regex) Apply(in ...telegraf.Metric) []telegraf.Metric {
for _, metric := range in {
for _, converter := range r.Tags {
if value, ok := metric.GetTag(converter.Key); ok {
if key, newValue := r.convert(converter, value); newValue != "" {
if converter.Append {
if v, ok := metric.GetTag(key); ok {
newValue = v + newValue
}
if converter.Key == "*" {
for _, tag := range metric.TagList() {
regex := r.regexCache[converter.Pattern]
if regex.MatchString(tag.Value) {
newValue := regex.ReplaceAllString(tag.Value, converter.Replacement)
updateTag(converter, metric, tag.Key, newValue)
}
metric.AddTag(key, newValue)
}
} else if value, ok := metric.GetTag(converter.Key); ok {
if key, newValue := r.convert(converter, value); newValue != "" {
updateTag(converter, metric, key, newValue)
}
}
}
Expand Down Expand Up @@ -212,6 +215,15 @@ func (r *Regex) convert(c converter, src string) (key string, value string) {
return c.Key, value
}

func updateTag(converter converter, metric telegraf.Metric, key string, newValue string) {
if converter.Append {
if v, ok := metric.GetTag(key); ok {
newValue = v + newValue
}
}
metric.AddTag(key, newValue)
}

func init() {
processors.Add("regex", func() telegraf.Processor { return &Regex{} })
}
57 changes: 57 additions & 0 deletions plugins/processors/regex/regex_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package regex

import (
"github.com/influxdata/telegraf/metric"
"github.com/stretchr/testify/assert"
"testing"
"time"

Expand Down Expand Up @@ -40,6 +42,21 @@ func newM2() telegraf.Metric {
)
}

func newUUIDTags() telegraf.Metric {
m1 := metric.New("access_log",
map[string]string{
"compound": "other-18cb0b46-73b8-4084-9fc4-5105f32a8a68",
"simple": "d60be57c-2f43-4e4f-a68a-4ca8204bae41",
"control": "not_uuid",
},
map[string]interface{}{
"request": "/users/42/",
},
time.Now(),
)
return m1
}

func TestFieldConversions(t *testing.T) {
tests := []struct {
message string
Expand Down Expand Up @@ -828,3 +845,43 @@ func BenchmarkConversions(b *testing.B) {
_ = processed
}
}

func TestAnyTagConversion(t *testing.T) {
tests := []struct {
message string
converter converter
expectedTags map[string]string
}{
{
message: "Should change existing tag",
converter: converter{
Key: "*",
Pattern: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
Replacement: "{UUID}",
},
expectedTags: map[string]string{
"compound": "other-{UUID}",
"simple": "{UUID}",
"control": "not_uuid",
},
},
}

for _, test := range tests {
regex := Regex{
Tags: []converter{test.converter},
Log: testutil.Logger{},
}
require.NoError(t, regex.Init())

processed := regex.Apply(newUUIDTags())

expectedFields := map[string]interface{}{
"request": "/users/42/",
}

assert.Equal(t, expectedFields, processed[0].Fields(), test.message, "Should not change fields")
assert.Equal(t, test.expectedTags, processed[0].Tags(), test.message)
assert.Equal(t, "access_log", processed[0].Name(), "Should not change name")
}
}

0 comments on commit 577c046

Please sign in to comment.