diff --git a/plugins/processors/strings/README.md b/plugins/processors/strings/README.md index d00bf03db..a7aa0e2a5 100644 --- a/plugins/processors/strings/README.md +++ b/plugins/processors/strings/README.md @@ -5,6 +5,7 @@ The `strings` plugin maps certain go string functions onto measurement, tag, and Implemented functions are: - lowercase - uppercase +- titlecase - trim - trim_left - trim_right @@ -35,6 +36,10 @@ If you'd like to apply multiple processings to the same `tag_key` or `field_key` # [[processors.strings.uppercase]] # tag = "method" + ## Convert a field value to titlecase + # [[processors.strings.titlecase]] + # field = "status" + ## Trim leading and trailing whitespace using the default cutset # [[processors.strings.trim]] # field = "message" diff --git a/plugins/processors/strings/strings.go b/plugins/processors/strings/strings.go index 4a8a6e7ff..1ac6c6101 100644 --- a/plugins/processors/strings/strings.go +++ b/plugins/processors/strings/strings.go @@ -13,6 +13,7 @@ import ( type Strings struct { Lowercase []converter `toml:"lowercase"` Uppercase []converter `toml:"uppercase"` + Titlecase []converter `toml:"titlecase"` Trim []converter `toml:"trim"` TrimLeft []converter `toml:"trim_left"` TrimRight []converter `toml:"trim_right"` @@ -55,6 +56,10 @@ const sampleConfig = ` # field = "uri_stem" # dest = "uri_stem_normalised" + ## Convert a field value to titlecase + # [[processors.strings.titlecase]] + # field = "status" + ## Trim leading and trailing whitespace using the default cutset # [[processors.strings.trim]] # field = "message" @@ -235,6 +240,10 @@ func (s *Strings) initOnce() { c.fn = strings.ToUpper s.converters = append(s.converters, c) } + for _, c := range s.Titlecase { + c.fn = strings.Title + s.converters = append(s.converters, c) + } for _, c := range s.Trim { c := c if c.Cutset != "" { diff --git a/plugins/processors/strings/strings_test.go b/plugins/processors/strings/strings_test.go index ae35acecf..2c1be510e 100644 --- a/plugins/processors/strings/strings_test.go +++ b/plugins/processors/strings/strings_test.go @@ -78,6 +78,21 @@ func TestFieldConversions(t *testing.T) { require.Equal(t, "/MIXED/CASE/PATH/?FROM=-1D&TO=NOW", fv) }, }, + { + name: "Should change existing field to titlecase", + plugin: &Strings{ + Titlecase: []converter{ + { + Field: "request", + }, + }, + }, + check: func(t *testing.T, actual telegraf.Metric) { + fv, ok := actual.GetField("request") + require.True(t, ok) + require.Equal(t, "/Mixed/CASE/PaTH/?From=-1D&To=Now", fv) + }, + }, { name: "Should add new lowercase field", plugin: &Strings{ @@ -331,6 +346,7 @@ func TestFieldKeyConversions(t *testing.T) { // Tag/field key multiple executions occur in the following order: (initOnce) // Lowercase // Uppercase + // Titlecase // Trim // TrimLeft // TrimRight @@ -595,6 +611,30 @@ func TestTagConversions(t *testing.T) { require.Equal(t, "MIXEDCASE_HOSTNAME", tv) }, }, + { + name: "Should add new titlecase tag", + plugin: &Strings{ + Titlecase: []converter{ + { + Tag: "s-computername", + Dest: "s-computername_titlecase", + }, + }, + }, + check: func(t *testing.T, actual telegraf.Metric) { + tv, ok := actual.GetTag("verb") + require.True(t, ok) + require.Equal(t, "GET", tv) + + tv, ok = actual.GetTag("s-computername") + require.True(t, ok) + require.Equal(t, "MIXEDCASE_hostname", tv) + + tv, ok = actual.GetTag("s-computername_titlecase") + require.True(t, ok) + require.Equal(t, "MIXEDCASE_hostname", tv) + }, + }, } for _, tt := range tests { @@ -736,6 +776,11 @@ func TestMultipleConversions(t *testing.T) { Tag: "verb", }, }, + Titlecase: []converter{ + { + Field: "status", + }, + }, Replace: []converter{ { Tag: "foo", @@ -763,6 +808,7 @@ func TestMultipleConversions(t *testing.T) { "cs-host": "AAAbbb", "ignore_number": int64(200), "ignore_bool": true, + "status": "green", }, time.Now(), ) @@ -775,6 +821,7 @@ func TestMultipleConversions(t *testing.T) { "ignore_bool": true, "cs-host": "AAAbbb", "cs-host_lowercase": "aaabbb", + "status": "Green", } expectedTags := map[string]string{ "verb": "GET",