Skip to content

Commit

Permalink
Fix metric and tag escaping for OpenTSDB writer
Browse files Browse the repository at this point in the history
Currently only the following characters are allowed: a to z, A to Z,
0 to 9, -, _, ., / so use a regex to replace other characters with an
_ (underscore).

refs #12879
  • Loading branch information
Tobias von der Krone committed Oct 20, 2016
1 parent d264a0d commit ba81472
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 25 deletions.
30 changes: 7 additions & 23 deletions lib/perfdata/opentsdbwriter.cpp
Expand Up @@ -39,6 +39,7 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/regex.hpp>

using namespace icinga;

Expand Down Expand Up @@ -109,14 +110,14 @@ void OpenTsdbWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C
String metric;
std::map<String, String> tags;

String escaped_hostName = EscapeMetric(host->GetName());
String escaped_hostName = EscapeMetricTag(host->GetName());
tags["host"] = escaped_hostName;

double ts = cr->GetExecutionEnd();

if (service) {
String serviceName = service->GetShortName();
String escaped_serviceName = EscapeMetric(serviceName);
String escaped_serviceName = EscapeMetricTag(serviceName);
metric = "icinga.service." + escaped_serviceName;

SendMetric(metric + ".state", tags, service->GetState(), ts);
Expand All @@ -137,7 +138,7 @@ void OpenTsdbWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C
if (service) {
tags["type"] = "service";
String serviceName = service->GetShortName();
String escaped_serviceName = EscapeTag(serviceName);
String escaped_serviceName = EscapeMetricTag(serviceName);
tags["service"] = escaped_serviceName;
} else {
tags["type"] = "host";
Expand Down Expand Up @@ -172,7 +173,7 @@ void OpenTsdbWriter::SendPerfdata(const String& metric, const std::map<String, S
}
}

String escaped_key = EscapeMetric(pdv->GetLabel());
String escaped_key = EscapeMetricTag(pdv->GetLabel());
boost::algorithm::replace_all(escaped_key, "::", ".");

SendMetric(metric + "." + escaped_key, tags, pdv->GetValue(), ts);
Expand Down Expand Up @@ -225,26 +226,9 @@ void OpenTsdbWriter::SendMetric(const String& metric, const std::map<String, Str
}
}

/* for metric and tag name rules, see
* http://opentsdb.net/docs/build/html/user_guide/writing.html#metrics-and-tags
*/
String OpenTsdbWriter::EscapeTag(const String& str)
String OpenTsdbWriter::EscapeMetricTag(const String& str)
{
String result = str;

boost::replace_all(result, " ", "_");
boost::replace_all(result, "\\", "_");

return result;
}

String OpenTsdbWriter::EscapeMetric(const String& str)
{
String result = str;

boost::replace_all(result, " ", "_");
boost::replace_all(result, ".", "_");
boost::replace_all(result, "\\", "_");
String result = boost::regex_replace(str, replaceMetricTagRe, "_");

return result;
}
17 changes: 15 additions & 2 deletions lib/perfdata/opentsdbwriter.hpp
Expand Up @@ -26,6 +26,7 @@
#include "base/tcpsocket.hpp"
#include "base/timer.hpp"
#include <fstream>
#include <boost/regex.hpp>

namespace icinga
{
Expand All @@ -51,11 +52,23 @@ class OpenTsdbWriter : public ObjectImpl<OpenTsdbWriter>

Timer::Ptr m_ReconnectTimer;

/* for metric and tag name rules, see
* http://opentsdb.net/docs/build/html/user_guide/writing.html#metrics-and-tags
* as of writing this the rule is:
*
* - Strings are case sensitive, i.e. "Sys.Cpu.User" will be stored separately from "sys.cpu.user"
* - Spaces are not allowed
* - Only the following characters are allowed: a to z, A to Z, 0 to 9, -, _, ., /
* or Unicode letters (as per the specification)
* - Metric and tags are not limited in length, though you should try to keep the values fairly short.
*/
const boost::regex replaceMetricTagRe("[^a-zA-Z0-9_./-]");


void CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr);
void SendMetric(const String& metric, const std::map<String, String>& tags, double value, double ts);
void SendPerfdata(const String& metric, const std::map<String, String>& tags, const CheckResult::Ptr& cr, double ts);
static String EscapeTag(const String& str);
static String EscapeMetric(const String& str);
static String EscapeMetricTag(const String& str);

void ReconnectTimerHandler(void);
};
Expand Down

0 comments on commit ba81472

Please sign in to comment.