[icinga-checkins] icinga.org: icinga2/master: Fix InfluxdbWriter Trailing Backslash

git at icinga.org git at icinga.org
Thu Jul 28 14:11:36 CEST 2016


Module: icinga2
Branch: master
Commit: d1dbe2a02f9d1b6d43e7f2c610dafe223f7b7f71
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=d1dbe2a02f9d1b6d43e7f2c610dafe223f7b7f71

Author: Simon Murray <spjmurray at yahoo.co.uk>
Date:   Thu Jul 28 10:28:53 2016 +0100

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

---

 doc/6-object-types.md           |    5 +++++
 lib/base/string.hpp             |   10 ++++++++++
 lib/perfdata/influxdbwriter.cpp |   12 ++++++++++--
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/doc/6-object-types.md b/doc/6-object-types.md
index 9e3e7e9..3b87ff8 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/base/string.hpp b/lib/base/string.hpp
index d27cd3c..85692bf 100644
--- a/lib/base/string.hpp
+++ b/lib/base/string.hpp
@@ -317,6 +317,16 @@ public:
 		return m_Data.rend();
 	}
 
+	inline char Front(void) const
+	{
+		return m_Data.front();
+	}
+
+	inline char Back(void) const
+	{
+		return m_Data.back();
+	}
+
 	static const SizeType NPos;
 
 	static Object::Ptr GetPrototype(void);
diff --git a/lib/perfdata/influxdbwriter.cpp b/lib/perfdata/influxdbwriter.cpp
index 92091aa..c3add10 100644
--- a/lib/perfdata/influxdbwriter.cpp
+++ b/lib/perfdata/influxdbwriter.cpp
@@ -233,10 +233,18 @@ void InfluxdbWriter::SendPerfdata(const Dictionary::Ptr& tmpl, const Checkable::
 
 String InfluxdbWriter::EscapeKey(const String& str)
 {
-	// Iterate over the key name and escape commas and spaces with a backslash
 	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.
+	if (result.Back() == '\\')
+		result[result.GetLength() -1] = '_';
+
 	return result;
 }
 
@@ -284,7 +292,7 @@ void InfluxdbWriter::SendMetric(const Dictionary::Ptr& tmpl, const String& label
 		}
 	}
 
-	msgbuf << ",metric=" << label << " ";
+	msgbuf << ",metric=" << EscapeKey(label) << " ";
 
 	bool first = true;
 	ObjectLock fieldLock(fields);



More information about the icinga-checkins mailing list