diff --git a/plugins/outputs/wavefront/wavefront.go b/plugins/outputs/wavefront/wavefront.go index 04a8e3396..f81566edf 100644 --- a/plugins/outputs/wavefront/wavefront.go +++ b/plugins/outputs/wavefront/wavefront.go @@ -42,24 +42,7 @@ type Wavefront struct { Log telegraf.Logger `toml:"-"` } -// catch many of the invalid chars that could appear in a metric or tag name -var sanitizedChars = strings.NewReplacer( - "!", "-", "@", "-", "#", "-", "$", "-", "%", "-", "^", "-", "&", "-", - "*", "-", "(", "-", ")", "-", "+", "-", "`", "-", "'", "-", "\"", "-", - "[", "-", "]", "-", "{", "-", "}", "-", ":", "-", ";", "-", "<", "-", - ">", "-", ",", "-", "?", "-", "/", "-", "\\", "-", "|", "-", " ", "-", - "=", "-", -) - -// catch many of the invalid chars that could appear in a metric or tag name -var strictSanitizedChars = strings.NewReplacer( - "!", "-", "@", "-", "#", "-", "$", "-", "%", "-", "^", "-", "&", "-", - "*", "-", "(", "-", ")", "-", "+", "-", "`", "-", "'", "-", "\"", "-", - "[", "-", "]", "-", "{", "-", "}", "-", ":", "-", ";", "-", "<", "-", - ">", "-", "?", "-", "\\", "-", "|", "-", " ", "-", "=", "-", -) - -// instead of Replacer which may miss some special characters we can use a regex pattern, but this is significantly slower than Replacer +// instead of Sanitize which may miss some special characters we can use a regex pattern, but this is significantly slower than Sanitize var sanitizedRegex = regexp.MustCompile(`[^a-zA-Z\d_.-]`) var tagValueReplacer = strings.NewReplacer("*", "-") @@ -166,10 +149,8 @@ func (w *Wavefront) buildMetrics(m telegraf.Metric) []*serializer.MetricPoint { if w.UseRegex { name = sanitizedRegex.ReplaceAllLiteralString(name, "-") - } else if w.UseStrict { - name = strictSanitizedChars.Replace(name) } else { - name = sanitizedChars.Replace(name) + name = serializer.Sanitize(w.UseStrict, name) } if w.ConvertPaths { @@ -245,10 +226,8 @@ func (w *Wavefront) buildTags(mTags map[string]string) (string, map[string]strin var key string if w.UseRegex { key = sanitizedRegex.ReplaceAllLiteralString(k, "-") - } else if w.UseStrict { - key = strictSanitizedChars.Replace(k) } else { - key = sanitizedChars.Replace(k) + key = serializer.Sanitize(w.UseStrict, k) } val := tagValueReplacer.Replace(v) if w.TruncateTags { diff --git a/plugins/outputs/wavefront/wavefront_test.go b/plugins/outputs/wavefront/wavefront_test.go index 86b499d4e..60e1ffbdc 100644 --- a/plugins/outputs/wavefront/wavefront_test.go +++ b/plugins/outputs/wavefront/wavefront_test.go @@ -380,7 +380,7 @@ func TestDefaults(t *testing.T) { require.Equal(t, 10000, defaultWavefront.HTTPMaximumBatchSize) } -// Benchmarks to test performance of string replacement via Regex and Replacer +// Benchmarks to test performance of string replacement via Regex and Sanitize var testString = "this_is*my!test/string\\for=replacement" func BenchmarkReplaceAllString(b *testing.B) { @@ -397,6 +397,6 @@ func BenchmarkReplaceAllLiteralString(b *testing.B) { func BenchmarkReplacer(b *testing.B) { for n := 0; n < b.N; n++ { - sanitizedChars.Replace(testString) + serializer.Sanitize(false, testString) } } diff --git a/plugins/serializers/wavefront/replacers.go b/plugins/serializers/wavefront/replacers.go new file mode 100644 index 000000000..46465904d --- /dev/null +++ b/plugins/serializers/wavefront/replacers.go @@ -0,0 +1,31 @@ +package wavefront + +import "strings" + +// catch many of the invalid chars that could appear in a metric or tag name +var sanitizedChars = strings.NewReplacer( + "!", "-", "@", "-", "#", "-", "$", "-", "%", "-", "^", "-", "&", "-", + "*", "-", "(", "-", ")", "-", "+", "-", "`", "-", "'", "-", "\"", "-", + "[", "-", "]", "-", "{", "-", "}", "-", ":", "-", ";", "-", "<", "-", + ">", "-", ",", "-", "?", "-", "/", "-", "\\", "-", "|", "-", " ", "-", + "=", "-", +) + +// catch many of the invalid chars that could appear in a metric or tag name +var strictSanitizedChars = strings.NewReplacer( + "!", "-", "@", "-", "#", "-", "$", "-", "%", "-", "^", "-", "&", "-", + "*", "-", "(", "-", ")", "-", "+", "-", "`", "-", "'", "-", "\"", "-", + "[", "-", "]", "-", "{", "-", "}", "-", ":", "-", ";", "-", "<", "-", + ">", "-", "?", "-", "\\", "-", "|", "-", " ", "-", "=", "-", +) + +var tagValueReplacer = strings.NewReplacer("\"", "\\\"", "*", "-") + +var pathReplacer = strings.NewReplacer("_", ".") + +func Sanitize(strict bool, val string) string { + if strict { + return strictSanitizedChars.Replace(val) + } + return sanitizedChars.Replace(val) +} diff --git a/plugins/serializers/wavefront/wavefront.go b/plugins/serializers/wavefront/wavefront.go index 7086ba79b..c99145394 100755 --- a/plugins/serializers/wavefront/wavefront.go +++ b/plugins/serializers/wavefront/wavefront.go @@ -3,7 +3,6 @@ package wavefront import ( "log" "strconv" - "strings" "sync" "github.com/influxdata/telegraf" @@ -19,27 +18,6 @@ type WavefrontSerializer struct { mu sync.Mutex // buffer mutex } -// catch many of the invalid chars that could appear in a metric or tag name -var sanitizedChars = strings.NewReplacer( - "!", "-", "@", "-", "#", "-", "$", "-", "%", "-", "^", "-", "&", "-", - "*", "-", "(", "-", ")", "-", "+", "-", "`", "-", "'", "-", "\"", "-", - "[", "-", "]", "-", "{", "-", "}", "-", ":", "-", ";", "-", "<", "-", - ">", "-", ",", "-", "?", "-", "/", "-", "\\", "-", "|", "-", " ", "-", - "=", "-", -) - -// catch many of the invalid chars that could appear in a metric or tag name -var strictSanitizedChars = strings.NewReplacer( - "!", "-", "@", "-", "#", "-", "$", "-", "%", "-", "^", "-", "&", "-", - "*", "-", "(", "-", ")", "-", "+", "-", "`", "-", "'", "-", "\"", "-", - "[", "-", "]", "-", "{", "-", "}", "-", ":", "-", ";", "-", "<", "-", - ">", "-", "?", "-", "\\", "-", "|", "-", " ", "-", "=", "-", -) - -var tagValueReplacer = strings.NewReplacer("\"", "\\\"", "*", "-") - -var pathReplacer = strings.NewReplacer("_", ".") - type MetricPoint struct { Metric string Value float64 @@ -70,11 +48,7 @@ func (s *WavefrontSerializer) serializeMetric(m telegraf.Metric) { name = s.Prefix + m.Name() + metricSeparator + fieldName } - if s.UseStrict { - name = strictSanitizedChars.Replace(name) - } else { - name = sanitizedChars.Replace(name) - } + name = Sanitize(s.UseStrict, name) if !s.DisablePrefixConversions { name = pathReplacer.Replace(name) @@ -182,11 +156,7 @@ func formatMetricPoint(b *buffer, metricPoint *MetricPoint, s *WavefrontSerializ for k, v := range metricPoint.Tags { b.WriteString(` "`) - if s.UseStrict { - b.WriteString(strictSanitizedChars.Replace(k)) - } else { - b.WriteString(sanitizedChars.Replace(k)) - } + b.WriteString(Sanitize(s.UseStrict, k)) b.WriteString(`"="`) b.WriteString(tagValueReplacer.Replace(v)) b.WriteChar('"')