From 643fb7decc83b9171b39b093f15858ac25d4443a Mon Sep 17 00:00:00 2001 From: Daniel Nelson Date: Fri, 12 Jun 2020 17:54:49 -0700 Subject: [PATCH] Remove trailing backslash from tag keys/values (#7652) --- plugins/outputs/influxdb/README.md | 5 ++ plugins/outputs/influxdb_v2/README.md | 5 ++ plugins/serializers/influx/README.md | 10 +++ plugins/serializers/influx/influx.go | 13 ++- plugins/serializers/influx/influx_test.go | 96 +++++++++++++++++++++++ 5 files changed, 127 insertions(+), 2 deletions(-) diff --git a/plugins/outputs/influxdb/README.md b/plugins/outputs/influxdb/README.md index a53b7a0f2..aefc03690 100644 --- a/plugins/outputs/influxdb/README.md +++ b/plugins/outputs/influxdb/README.md @@ -84,4 +84,9 @@ The InfluxDB output plugin writes metrics to the [InfluxDB v1.x] HTTP or UDP ser # influx_uint_support = false ``` +### Metrics + +Reference the [influx serializer][] for details about metric production. + [InfluxDB v1.x]: https://github.com/influxdata/influxdb +[influx serializer]: /plugins/serializers/influx/README.md#Metrics diff --git a/plugins/outputs/influxdb_v2/README.md b/plugins/outputs/influxdb_v2/README.md index 49c080f33..1605bda0c 100644 --- a/plugins/outputs/influxdb_v2/README.md +++ b/plugins/outputs/influxdb_v2/README.md @@ -58,4 +58,9 @@ The InfluxDB output plugin writes metrics to the [InfluxDB v2.x] HTTP service. # insecure_skip_verify = false ``` +### Metrics + +Reference the [influx serializer][] for details about metric production. + [InfluxDB v2.x]: https://github.com/influxdata/influxdb +[influx serializer]: /plugins/serializers/influx/README.md#Metrics diff --git a/plugins/serializers/influx/README.md b/plugins/serializers/influx/README.md index d97fd42c8..d21ead875 100644 --- a/plugins/serializers/influx/README.md +++ b/plugins/serializers/influx/README.md @@ -5,6 +5,7 @@ protocol]. This is the recommended format unless another format is required for interoperability. ### Configuration + ```toml [[outputs.file]] ## Files to write to, "stdout" is a specially handled file. @@ -31,4 +32,13 @@ for interoperability. influx_uint_support = false ``` +### Metrics + +Conversion is direct taking into account some limitations of the Line Protocol +format: +- Float fields that are `NaN` or `Inf` are skipped. +- Trailing backslash `\` characters are removed from tag keys and values. +- Tags with a key or value that is the empty string are skipped. +- When not using `influx_uint_support`, unsigned integers are capped at the max int64. + [line protocol]: https://docs.influxdata.com/influxdb/latest/write_protocols/line_protocol_tutorial/ diff --git a/plugins/serializers/influx/influx.go b/plugins/serializers/influx/influx.go index a675add4b..aa76b8acc 100644 --- a/plugins/serializers/influx/influx.go +++ b/plugins/serializers/influx/influx.go @@ -8,6 +8,7 @@ import ( "math" "sort" "strconv" + "strings" "github.com/influxdata/telegraf" ) @@ -154,8 +155,16 @@ func (s *Serializer) buildHeader(m telegraf.Metric) error { key := escape(tag.Key) value := escape(tag.Value) - // Some keys and values are not encodeable as line protocol, such as - // those with a trailing '\' or empty strings. + // Tag keys and values that end with a backslash cannot be encoded by + // line protocol. + if strings.HasSuffix(key, `\`) { + key = strings.TrimRight(key, `\`) + } + if strings.HasSuffix(value, `\`) { + value = strings.TrimRight(value, `\`) + } + + // Tag keys and values must not be the empty string. if key == "" || value == "" { continue } diff --git a/plugins/serializers/influx/influx_test.go b/plugins/serializers/influx/influx_test.go index eae3d755c..a86215d94 100644 --- a/plugins/serializers/influx/influx_test.go +++ b/plugins/serializers/influx/influx_test.go @@ -323,6 +323,102 @@ var tests = []struct { ), output: []byte("cpu,host=x\\ny value=42i 0\n"), }, + { + name: "empty tag value is removed", + input: MustMetric( + metric.New( + "cpu", + map[string]string{ + "host": "", + }, + map[string]interface{}{ + "value": 42, + }, + time.Unix(0, 0), + ), + ), + output: []byte("cpu value=42i 0\n"), + }, + { + name: "empty tag key is removed", + input: MustMetric( + metric.New( + "cpu", + map[string]string{ + "": "example.org", + }, + map[string]interface{}{ + "value": 42, + }, + time.Unix(0, 0), + ), + ), + output: []byte("cpu value=42i 0\n"), + }, + { + name: "tag value ends with backslash is trimmed", + input: MustMetric( + metric.New( + "disk", + map[string]string{ + "path": `C:\`, + }, + map[string]interface{}{ + "value": 42, + }, + time.Unix(0, 0), + ), + ), + output: []byte("disk,path=C: value=42i 0\n"), + }, + { + name: "tag key ends with backslash is trimmed", + input: MustMetric( + metric.New( + "disk", + map[string]string{ + `path\`: "/", + }, + map[string]interface{}{ + "value": 42, + }, + time.Unix(0, 0), + ), + ), + output: []byte("disk,path=/ value=42i 0\n"), + }, + { + name: "tag key backslash is trimmed and removed", + input: MustMetric( + metric.New( + "disk", + map[string]string{ + `\`: "example.org", + }, + map[string]interface{}{ + "value": 42, + }, + time.Unix(0, 0), + ), + ), + output: []byte("disk value=42i 0\n"), + }, + { + name: "tag value backslash is trimmed and removed", + input: MustMetric( + metric.New( + "disk", + map[string]string{ + "host": `\`, + }, + map[string]interface{}{ + "value": 42, + }, + time.Unix(0, 0), + ), + ), + output: []byte("disk value=42i 0\n"), + }, { name: "string newline", input: MustMetric(