diff --git a/doc/6-object-types.md b/doc/6-object-types.md index 9e3e7e9af..3b87ff8a1 100644 --- a/doc/6-object-types.md +++ b/doc/6-object-types.md @@ -900,6 +900,11 @@ perfdata label. Fields (value, warn, crit, min, max) are created from data if av and the configuration allows it. If a value associated with a tag is not able to be resolved, it will be dropped and not sent to the target host. +Backslashes are allowed in tag keys, tag values and field keys, however they are also +escape characters when followed by a space or comma, but cannot be escaped themselves. +As a result all trailling slashes in these fields are replaced with an underscore. This +predominantly affects Windows paths e.g. `C:\` becomes `C:_`. + The database is assumed to exist so this object will make no attempt to create it currently. Configuration Attributes: diff --git a/lib/perfdata/influxdbwriter.cpp b/lib/perfdata/influxdbwriter.cpp index 92091aafb..6eb8d0091 100644 --- a/lib/perfdata/influxdbwriter.cpp +++ b/lib/perfdata/influxdbwriter.cpp @@ -237,6 +237,16 @@ String InfluxdbWriter::EscapeKey(const String& str) String result = str; boost::algorithm::replace_all(result, ",", "\\,"); boost::algorithm::replace_all(result, " ", "\\ "); + + // InfluxDB 'feature': although backslashes are allowed in keys they also act + // as escape sequences when followed by ',' or ' '. When your tag is like + // 'metric=C:\' bad things happen. Backslashes themselves cannot be escaped + // and through experimentation they also escape '='. To be safe we replace + // trailing backslashes with and underscore. + size_t length = result.GetLength(); + if (result[length - 1] == '\\') + result[length - 1] = '_'; + return result; } @@ -284,7 +294,7 @@ void InfluxdbWriter::SendMetric(const Dictionary::Ptr& tmpl, const String& label } } - msgbuf << ",metric=" << label << " "; + msgbuf << ",metric=" << EscapeKey(label) << " "; bool first = true; ObjectLock fieldLock(fields);