Skip to content

Commit 16ca9b4

Browse files
puckpuckbitcharmer
authored andcommitted
Add option to use strict sanitization rules to wavefront output (influxdata#5664)
1 parent 871f6d2 commit 16ca9b4

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

plugins/outputs/wavefront/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ This plugin writes to a [Wavefront](https://www.wavefront.com) proxy, in Wavefro
3232
## When true will convert all _ (underscore) characters in final metric name. default is true
3333
#convert_paths = true
3434

35+
## Use Strict rules to sanitize metric and tag names from invalid characters
36+
## When enabled forward slash (/) and comma (,) will be accpeted
37+
#use_strict = false
38+
3539
## Use Regex to sanitize metric and tag names from invalid characters
3640
## Regex is more thorough, but significantly slower. default is false
3741
#use_regex = false

plugins/outputs/wavefront/wavefront.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Wavefront struct {
2222
ConvertPaths bool
2323
ConvertBool bool
2424
UseRegex bool
25+
UseStrict bool
2526
SourceOverride []string
2627
StringToNumber map[string][]map[string]float64
2728

@@ -37,6 +38,14 @@ var sanitizedChars = strings.NewReplacer(
3738
"=", "-",
3839
)
3940

41+
// catch many of the invalid chars that could appear in a metric or tag name
42+
var strictSanitizedChars = strings.NewReplacer(
43+
"!", "-", "@", "-", "#", "-", "$", "-", "%", "-", "^", "-", "&", "-",
44+
"*", "-", "(", "-", ")", "-", "+", "-", "`", "-", "'", "-", "\"", "-",
45+
"[", "-", "]", "-", "{", "-", "}", "-", ":", "-", ";", "-", "<", "-",
46+
">", "-", "?", "-", "\\", "-", "|", "-", " ", "-", "=", "-",
47+
)
48+
4049
// instead of Replacer which may miss some special characters we can use a regex pattern, but this is significantly slower than Replacer
4150
var sanitizedRegex = regexp.MustCompile("[^a-zA-Z\\d_.-]")
4251

@@ -71,6 +80,10 @@ var sampleConfig = `
7180
## When true will convert all _ (underscore) characters in final metric name. default is true
7281
#convert_paths = true
7382
83+
## Use Strict rules to sanitize metric and tag names from invalid characters
84+
## When enabled forward slash (/) and comma (,) will be accpeted
85+
#use_strict = false
86+
7487
## Use Regex to sanitize metric and tag names from invalid characters
7588
## Regex is more thorough, but significantly slower. default is false
7689
#use_regex = false
@@ -163,6 +176,8 @@ func buildMetrics(m telegraf.Metric, w *Wavefront) []*MetricPoint {
163176

164177
if w.UseRegex {
165178
name = sanitizedRegex.ReplaceAllLiteralString(name, "-")
179+
} else if w.UseStrict {
180+
name = strictSanitizedChars.Replace(name)
166181
} else {
167182
name = sanitizedChars.Replace(name)
168183
}
@@ -238,6 +253,8 @@ func buildTags(mTags map[string]string, w *Wavefront) (string, map[string]string
238253
var key string
239254
if w.UseRegex {
240255
key = sanitizedRegex.ReplaceAllLiteralString(k, "-")
256+
} else if w.UseStrict {
257+
key = strictSanitizedChars.Replace(k)
241258
} else {
242259
key = sanitizedChars.Replace(k)
243260
}

plugins/outputs/wavefront/wavefront_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ func TestBuildMetrics(t *testing.T) {
5050
{Metric: w.Prefix + "testing.metric2", Value: 1, Timestamp: timestamp, Tags: map[string]string{"tag1": "value1"}},
5151
},
5252
},
53+
{
54+
testutil.TestMetric(float64(1), "testing_just/another,metric:float", "metric2"),
55+
[]MetricPoint{
56+
{Metric: w.Prefix + "testing.just-another-metric-float", Value: 1, Timestamp: timestamp, Tags: map[string]string{"tag1": "value1"}},
57+
{Metric: w.Prefix + "testing.metric2", Value: 1, Timestamp: timestamp, Tags: map[string]string{"tag1": "value1"}},
58+
},
59+
},
5360
{
5461
testMetric1,
5562
[]MetricPoint{{Metric: w.Prefix + "test.simple.metric", Value: 123, Timestamp: timestamp, Source: "testHost", Tags: map[string]string{"tag1": "value1"}}},
@@ -67,6 +74,46 @@ func TestBuildMetrics(t *testing.T) {
6774

6875
}
6976

77+
func TestBuildMetricsStrict(t *testing.T) {
78+
w := defaultWavefront()
79+
w.Prefix = "testthis."
80+
w.UseStrict = true
81+
82+
pathReplacer = strings.NewReplacer("_", w.MetricSeparator)
83+
84+
var timestamp int64 = 1257894000
85+
86+
var metricTests = []struct {
87+
metric telegraf.Metric
88+
metricPoints []MetricPoint
89+
}{
90+
{
91+
testutil.TestMetric(float64(1), "testing_just*a%metric:float", "metric2"),
92+
[]MetricPoint{
93+
{Metric: w.Prefix + "testing.just-a-metric-float", Value: 1, Timestamp: timestamp, Tags: map[string]string{"tag1": "value1"}},
94+
{Metric: w.Prefix + "testing.metric2", Value: 1, Timestamp: timestamp, Tags: map[string]string{"tag1": "value1"}},
95+
},
96+
},
97+
{
98+
testutil.TestMetric(float64(1), "testing_just/another,metric:float", "metric2"),
99+
[]MetricPoint{
100+
{Metric: w.Prefix + "testing.just/another,metric-float", Value: 1, Timestamp: timestamp, Tags: map[string]string{"tag/1": "value1", "tag,2": "value2"}},
101+
{Metric: w.Prefix + "testing.metric2", Value: 1, Timestamp: timestamp, Tags: map[string]string{"tag/1": "value1", "tag,2": "value2"}},
102+
},
103+
},
104+
}
105+
106+
for _, mt := range metricTests {
107+
ml := buildMetrics(mt.metric, w)
108+
for i, line := range ml {
109+
if mt.metricPoints[i].Metric != line.Metric || mt.metricPoints[i].Value != line.Value {
110+
t.Errorf("\nexpected\t%+v %+v\nreceived\t%+v %+v\n", mt.metricPoints[i].Metric, mt.metricPoints[i].Value, line.Metric, line.Value)
111+
}
112+
}
113+
}
114+
115+
}
116+
70117
func TestBuildMetricsWithSimpleFields(t *testing.T) {
71118
w := defaultWavefront()
72119
w.Prefix = "testthis."

0 commit comments

Comments
 (0)