Fix InfluxdbWriter Trailing Backslash

Backslashes escape spaces or commas (and evidently equals), given tags are
separated by commas, tag keys and values are separated by equals and tags
are separated from fields by a space we need to take action when these end
in a backslash e.g. 'C:\'.  Also discovered a bug whereby the metric tag was
missing out on escaping.

fixes #12227

Signed-off-by: Gunnar Beutner <gunnar.beutner@netways.de>
This commit is contained in:
Simon Murray 2016-07-28 10:28:53 +01:00 committed by Gunnar Beutner
parent dcfda534b1
commit 84ea0065b2
2 changed files with 16 additions and 1 deletions

View File

@ -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:

View File

@ -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);