feat(processor/regex): Add ability to check every tag for regex replace (#10927)
This commit is contained in:
parent
351ab58ac8
commit
577c0462b8
|
|
@ -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
|
# Tag and field conversions defined in a separate sub-tables
|
||||||
[[processors.regex.tags]]
|
[[processors.regex.tags]]
|
||||||
## Tag to change
|
## Tag to change, "*" will change every tag
|
||||||
key = "resp_code"
|
key = "resp_code"
|
||||||
## Regular expression to match on a tag value
|
## Regular expression to match on a tag value
|
||||||
pattern = "^(\\d)\\d\\d$"
|
pattern = "^(\\d)\\d\\d$"
|
||||||
|
|
|
||||||
|
|
@ -97,14 +97,17 @@ func (r *Regex) Init() error {
|
||||||
func (r *Regex) Apply(in ...telegraf.Metric) []telegraf.Metric {
|
func (r *Regex) Apply(in ...telegraf.Metric) []telegraf.Metric {
|
||||||
for _, metric := range in {
|
for _, metric := range in {
|
||||||
for _, converter := range r.Tags {
|
for _, converter := range r.Tags {
|
||||||
if value, ok := metric.GetTag(converter.Key); ok {
|
if converter.Key == "*" {
|
||||||
if key, newValue := r.convert(converter, value); newValue != "" {
|
for _, tag := range metric.TagList() {
|
||||||
if converter.Append {
|
regex := r.regexCache[converter.Pattern]
|
||||||
if v, ok := metric.GetTag(key); ok {
|
if regex.MatchString(tag.Value) {
|
||||||
newValue = v + newValue
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -212,6 +215,15 @@ func (r *Regex) convert(c converter, src string) (key string, value string) {
|
||||||
return c.Key, value
|
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() {
|
func init() {
|
||||||
processors.Add("regex", func() telegraf.Processor { return &Regex{} })
|
processors.Add("regex", func() telegraf.Processor { return &Regex{} })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package regex
|
package regex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/influxdata/telegraf/metric"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -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) {
|
func TestFieldConversions(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
message string
|
message string
|
||||||
|
|
@ -828,3 +845,43 @@ func BenchmarkConversions(b *testing.B) {
|
||||||
_ = processed
|
_ = 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue