mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-27 07:34:15 +02:00
Add service metadata to InfluxDB Writer
Adds a new configuration variable in keeping with the graphite writer which defaults to false to save network bandwidth. All metrics currently supported by graphite are now available to InfluxDB. I added in some formatting functions, to handle integers and booleans as we know and control their types, and the supporting regexes in the sanity checker. Updating to InfluxDB 0.13.X started giving 400 errors due to the missing Host header in HTTP/1.1 requests. HttpRequest has been updated to auto- magically add the host and port to these requests if not explicitly stated by the client code. The exception code has been cleaned up to break out of the function early if such a condition is raised, this avoids unnecessarily executing code which will ultimately fail. fixes #11912 Signed-off-by: Gunnar Beutner <gunnar.beutner@netways.de>
This commit is contained in:
parent
899592c8ad
commit
2e8c8809ea
@ -905,6 +905,7 @@ Configuration Attributes:
|
|||||||
host_template | **Required.** Host template to define the InfluxDB line protocol.
|
host_template | **Required.** Host template to define the InfluxDB line protocol.
|
||||||
service_template | **Required.** Service template to define the influxDB line protocol.
|
service_template | **Required.** Service template to define the influxDB line protocol.
|
||||||
enable_send_thresholds | **Optional.** Whether to send warn, crit, min & max tagged data.
|
enable_send_thresholds | **Optional.** Whether to send warn, crit, min & max tagged data.
|
||||||
|
enable_send_metadata | **Optional.** Whether to send check metadata e.g. states, execution time, latency etc.
|
||||||
flush_interval | **Optional.** How long to buffer data points before transfering to InfluxDB. Defaults to `10s`.
|
flush_interval | **Optional.** How long to buffer data points before transfering to InfluxDB. Defaults to `10s`.
|
||||||
flush_threshold | **Optional.** How many data points to buffer before forcing a transfer to InfluxDB. Defaults to `1024`.
|
flush_threshold | **Optional.** How many data points to buffer before forcing a transfer to InfluxDB. Defaults to `1024`.
|
||||||
|
|
||||||
|
@ -157,10 +157,20 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendPerfdata(tmpl, cr, ts);
|
SendPerfdata(tmpl, checkable, cr, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfluxdbWriter::SendPerfdata(const Dictionary::Ptr& tmpl, const CheckResult::Ptr& cr, double ts)
|
String InfluxdbWriter::FormatInteger(const int val)
|
||||||
|
{
|
||||||
|
return Convert::ToString(val) + "i";
|
||||||
|
}
|
||||||
|
|
||||||
|
String InfluxdbWriter::FormatBoolean(const bool val)
|
||||||
|
{
|
||||||
|
return val ? "true" : "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfluxdbWriter::SendPerfdata(const Dictionary::Ptr& tmpl, const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, double ts)
|
||||||
{
|
{
|
||||||
Array::Ptr perfdata = cr->GetPerformanceData();
|
Array::Ptr perfdata = cr->GetPerformanceData();
|
||||||
|
|
||||||
@ -185,6 +195,7 @@ void InfluxdbWriter::SendPerfdata(const Dictionary::Ptr& tmpl, const CheckResult
|
|||||||
|
|
||||||
Dictionary::Ptr fields = new Dictionary();
|
Dictionary::Ptr fields = new Dictionary();
|
||||||
fields->Set(String("value"), pdv->GetValue());
|
fields->Set(String("value"), pdv->GetValue());
|
||||||
|
|
||||||
if (GetEnableSendThresholds()) {
|
if (GetEnableSendThresholds()) {
|
||||||
if (pdv->GetCrit())
|
if (pdv->GetCrit())
|
||||||
fields->Set(String("crit"), pdv->GetCrit());
|
fields->Set(String("crit"), pdv->GetCrit());
|
||||||
@ -196,6 +207,25 @@ void InfluxdbWriter::SendPerfdata(const Dictionary::Ptr& tmpl, const CheckResult
|
|||||||
fields->Set(String("max"), pdv->GetMax());
|
fields->Set(String("max"), pdv->GetMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetEnableSendMetadata()) {
|
||||||
|
Host::Ptr host;
|
||||||
|
Service::Ptr service;
|
||||||
|
boost::tie(host, service) = GetHostService(checkable);
|
||||||
|
|
||||||
|
if (service)
|
||||||
|
fields->Set(String("state"), FormatInteger(service->GetState()));
|
||||||
|
else
|
||||||
|
fields->Set(String("state"), FormatInteger(host->GetState()));
|
||||||
|
|
||||||
|
fields->Set(String("current_attempt"), FormatInteger(checkable->GetCheckAttempt()));
|
||||||
|
fields->Set(String("max_check_attempts"), FormatInteger(checkable->GetMaxCheckAttempts()));
|
||||||
|
fields->Set(String("state_type"), FormatInteger(checkable->GetStateType()));
|
||||||
|
fields->Set(String("reachable"), FormatBoolean(checkable->IsReachable()));
|
||||||
|
fields->Set(String("downtime_depth"), FormatInteger(checkable->GetDowntimeDepth()));
|
||||||
|
fields->Set(String("latency"), cr->CalculateLatency());
|
||||||
|
fields->Set(String("execution_time"), cr->CalculateExecutionTime());
|
||||||
|
}
|
||||||
|
|
||||||
SendMetric(tmpl, pdv->GetLabel(), fields, ts);
|
SendMetric(tmpl, pdv->GetLabel(), fields, ts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,8 +241,11 @@ String InfluxdbWriter::EscapeKey(const String& str)
|
|||||||
|
|
||||||
String InfluxdbWriter::EscapeField(const String& str)
|
String InfluxdbWriter::EscapeField(const String& str)
|
||||||
{
|
{
|
||||||
// Technically everything entering here from PerfdataValue is a
|
// Handle integers
|
||||||
// double, but best have the safety net in place.
|
boost::regex integer("-?\\d+i");
|
||||||
|
if (boost::regex_match(str.GetData(), integer)) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle numerics
|
// Handle numerics
|
||||||
boost::regex numeric("-?\\d+(\\.\\d+)?((e|E)[+-]?\\d+)?");
|
boost::regex numeric("-?\\d+(\\.\\d+)?((e|E)[+-]?\\d+)?");
|
||||||
@ -335,6 +368,7 @@ void InfluxdbWriter::Flush(void)
|
|||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
Log(LogWarning, "InfluxdbWriter")
|
Log(LogWarning, "InfluxdbWriter")
|
||||||
<< "Cannot write to TCP socket on host '" << GetHost() << "' port '" << GetPort() << "'.";
|
<< "Cannot write to TCP socket on host '" << GetHost() << "' port '" << GetPort() << "'.";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponse resp(stream, req);
|
HttpResponse resp(stream, req);
|
||||||
@ -342,9 +376,10 @@ void InfluxdbWriter::Flush(void)
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
resp.Parse(context, true);
|
resp.Parse(context, true);
|
||||||
} catch (const std::exception) {
|
} catch (const std::exception&) {
|
||||||
Log(LogWarning, "InfluxdbWriter")
|
Log(LogWarning, "InfluxdbWriter")
|
||||||
<< "Cannot read from TCP socket from host '" << GetHost() << "' port '" << GetPort() << "'.";
|
<< "Cannot read from TCP socket from host '" << GetHost() << "' port '" << GetPort() << "'.";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.StatusCode != 204) {
|
if (resp.StatusCode != 204) {
|
||||||
|
@ -54,11 +54,14 @@ private:
|
|||||||
Array::Ptr m_DataBuffer;
|
Array::Ptr m_DataBuffer;
|
||||||
|
|
||||||
void CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr);
|
void CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr);
|
||||||
void SendPerfdata(const Dictionary::Ptr& tmpl, const CheckResult::Ptr& cr, double ts);
|
void SendPerfdata(const Dictionary::Ptr& tmpl, const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, double ts);
|
||||||
void SendMetric(const Dictionary::Ptr& tmpl, const String& label, const Dictionary::Ptr& fields, double ts);
|
void SendMetric(const Dictionary::Ptr& tmpl, const String& label, const Dictionary::Ptr& fields, double ts);
|
||||||
void FlushTimeout(void);
|
void FlushTimeout(void);
|
||||||
void Flush(void);
|
void Flush(void);
|
||||||
|
|
||||||
|
static String FormatInteger(const int val);
|
||||||
|
static String FormatBoolean(const bool val);
|
||||||
|
|
||||||
static String EscapeKey(const String& str);
|
static String EscapeKey(const String& str);
|
||||||
static String EscapeField(const String& str);
|
static String EscapeField(const String& str);
|
||||||
|
|
||||||
|
@ -81,6 +81,9 @@ class InfluxdbWriter : ConfigObject
|
|||||||
[config] bool enable_send_thresholds {
|
[config] bool enable_send_thresholds {
|
||||||
default {{{ return false; }}}
|
default {{{ return false; }}}
|
||||||
};
|
};
|
||||||
|
[config] bool enable_send_metadata {
|
||||||
|
default {{{ return false; }}}
|
||||||
|
};
|
||||||
[config] int flush_interval {
|
[config] int flush_interval {
|
||||||
default {{{ return 10; }}}
|
default {{{ return 10; }}}
|
||||||
};
|
};
|
||||||
|
@ -174,8 +174,11 @@ void HttpRequest::FinishHeaders(void)
|
|||||||
if (m_State == HttpRequestHeaders) {
|
if (m_State == HttpRequestHeaders) {
|
||||||
AddHeader("User-Agent", "Icinga/" + Application::GetAppVersion());
|
AddHeader("User-Agent", "Icinga/" + Application::GetAppVersion());
|
||||||
|
|
||||||
if (ProtocolVersion == HttpVersion11)
|
if (ProtocolVersion == HttpVersion11) {
|
||||||
AddHeader("Transfer-Encoding", "chunked");
|
AddHeader("Transfer-Encoding", "chunked");
|
||||||
|
if (!Headers->Contains("Host"))
|
||||||
|
AddHeader("Host", RequestUrl->GetHost() + ":" + RequestUrl->GetPort());
|
||||||
|
}
|
||||||
|
|
||||||
ObjectLock olock(Headers);
|
ObjectLock olock(Headers);
|
||||||
BOOST_FOREACH(const Dictionary::Pair& kv, Headers)
|
BOOST_FOREACH(const Dictionary::Pair& kv, Headers)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user