]> granicus.if.org Git - icinga2/commitdiff
Fix InfluxdbWriter Trailing Backslash
authorSimon Murray <spjmurray@yahoo.co.uk>
Thu, 28 Jul 2016 09:28:53 +0000 (10:28 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Fri, 29 Jul 2016 04:51:33 +0000 (06:51 +0200)
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>
doc/6-object-types.md
lib/perfdata/influxdbwriter.cpp

index 9e3e7e9af22d98d4364e1eb578d94bc72e4c39d8..3b87ff8a17dc8302c5ab3dceddf2d05d45f24373 100644 (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:
index 92091aafb83910565856e51ad5569739e9bca4da..6eb8d0091fed66e7427a8a82a950d3498a5fdb68 100644 (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);