Graphite/PerfdataWriter: Add host perfdata.

Fixes #5908
This commit is contained in:
Michael Friedrich 2014-04-01 20:30:44 +02:00
parent 22c9caa6ec
commit 3fe169cd7a
10 changed files with 127 additions and 57 deletions

View File

@ -99,8 +99,9 @@ void GraphiteWriter::CheckResultHandler(const Service::Ptr& service, const Check
if (!IcingaApplication::GetInstance()->GetEnablePerfdata() || !service->GetEnablePerfdata()) if (!IcingaApplication::GetInstance()->GetEnablePerfdata() || !service->GetEnablePerfdata())
return; return;
/* TODO: sanitize host and service names */ Host::Ptr host = service->GetHost();
String hostName = service->GetHost()->GetName();
String hostName = host->GetName();
String serviceName = service->GetShortName(); String serviceName = service->GetShortName();
SanitizeMetric(hostName); SanitizeMetric(hostName);
@ -108,7 +109,7 @@ void GraphiteWriter::CheckResultHandler(const Service::Ptr& service, const Check
String prefix = "icinga." + hostName + "." + serviceName; String prefix = "icinga." + hostName + "." + serviceName;
/* basic metrics */ /* service metrics */
SendMetric(prefix, "current_attempt", service->GetCheckAttempt()); SendMetric(prefix, "current_attempt", service->GetCheckAttempt());
SendMetric(prefix, "max_check_attempts", service->GetMaxCheckAttempts()); SendMetric(prefix, "max_check_attempts", service->GetMaxCheckAttempts());
SendMetric(prefix, "state_type", service->GetStateType()); SendMetric(prefix, "state_type", service->GetStateType());
@ -116,6 +117,25 @@ void GraphiteWriter::CheckResultHandler(const Service::Ptr& service, const Check
SendMetric(prefix, "latency", Service::CalculateLatency(cr)); SendMetric(prefix, "latency", Service::CalculateLatency(cr));
SendMetric(prefix, "execution_time", Service::CalculateExecutionTime(cr)); SendMetric(prefix, "execution_time", Service::CalculateExecutionTime(cr));
SendPerfdata(prefix, cr);
if (service == host->GetCheckService()) {
prefix = "icinga." + hostName; // TODO works?
/* host metrics */
SendMetric(prefix, "current_attempt", service->GetCheckAttempt());
SendMetric(prefix, "max_check_attempts", service->GetMaxCheckAttempts());
SendMetric(prefix, "state_type", host->GetStateType());
SendMetric(prefix, "state", host->GetState());
SendMetric(prefix, "latency", Service::CalculateLatency(cr));
SendMetric(prefix, "execution_time", Service::CalculateExecutionTime(cr));
SendPerfdata(prefix, cr);
}
}
void GraphiteWriter::SendPerfdata(const String& prefix, const CheckResult::Ptr& cr)
{
Value pdv = cr->GetPerformanceData(); Value pdv = cr->GetPerformanceData();
if (!pdv.IsObjectType<Dictionary>()) if (!pdv.IsObjectType<Dictionary>())

View File

@ -53,6 +53,7 @@ private:
void CheckResultHandler(const Service::Ptr& service, const CheckResult::Ptr& cr); void CheckResultHandler(const Service::Ptr& service, const CheckResult::Ptr& cr);
void SendMetric(const String& prefix, const String& name, double value); void SendMetric(const String& prefix, const String& name, double value);
void SendPerfdata(const String& prefix, const CheckResult::Ptr& cr);
static void SanitizeMetric(String& str); static void SanitizeMetric(String& str);
void ReconnectTimerHandler(void); void ReconnectTimerHandler(void);

View File

@ -60,7 +60,8 @@ void PerfdataWriter::Start(void)
m_RotationTimer->SetInterval(GetRotationInterval()); m_RotationTimer->SetInterval(GetRotationInterval());
m_RotationTimer->Start(); m_RotationTimer->Start();
RotateFile(); RotateFile(m_ServiceOutputFile, GetServiceTempPath(), GetServicePerfdataPath());
RotateFile(m_HostOutputFile, GetHostTempPath(), GetHostPerfdataPath());
} }
void PerfdataWriter::CheckResultHandler(const Service::Ptr& service, const CheckResult::Ptr& cr) void PerfdataWriter::CheckResultHandler(const Service::Ptr& service, const CheckResult::Ptr& cr)
@ -77,36 +78,52 @@ void PerfdataWriter::CheckResultHandler(const Service::Ptr& service, const Check
resolvers.push_back(host); resolvers.push_back(host);
resolvers.push_back(IcingaApplication::GetInstance()); resolvers.push_back(IcingaApplication::GetInstance());
String line = MacroProcessor::ResolveMacros(GetFormatTemplate(), resolvers, cr); String line = MacroProcessor::ResolveMacros(GetServiceFormatTemplate(), resolvers, cr);
{
ObjectLock olock(this); ObjectLock olock(this);
if (!m_OutputFile.good()) if (!m_ServiceOutputFile.good())
return; return;
m_OutputFile << line << "\n"; m_ServiceOutputFile << line << "\n";
}
if (service == host->GetCheckService()) {
resolvers.clear();
resolvers.push_back(host);
resolvers.push_back(IcingaApplication::GetInstance());
line = MacroProcessor::ResolveMacros(GetHostFormatTemplate(), resolvers, cr);
{
ObjectLock olock(this);
if (!m_HostOutputFile.good())
return;
m_HostOutputFile << line << "\n";
}
}
} }
void PerfdataWriter::RotateFile(void) void PerfdataWriter::RotateFile(std::ofstream& output, const String& temp_path, const String& perfdata_path)
{ {
ObjectLock olock(this); ObjectLock olock(this);
String tempFile = GetTempPath(); if (output.good()) {
output.close();
if (m_OutputFile.good()) { String finalFile = perfdata_path + "." + Convert::ToString((long)Utility::GetTime());
m_OutputFile.close(); (void) rename(temp_path.CStr(), finalFile.CStr());
String finalFile = GetPerfdataPath() + "." + Convert::ToString((long)Utility::GetTime());
(void) rename(tempFile.CStr(), finalFile.CStr());
} }
m_OutputFile.open(tempFile.CStr()); output.open(temp_path.CStr());
if (!m_OutputFile.good()) if (!output.good())
Log(LogWarning, "icinga", "Could not open perfdata file '" + tempFile + "' for writing. Perfdata will be lost."); Log(LogWarning, "icinga", "Could not open perfdata file '" + temp_path + "' for writing. Perfdata will be lost.");
} }
void PerfdataWriter::RotationTimerHandler(void) void PerfdataWriter::RotationTimerHandler(void)
{ {
RotateFile(); RotateFile(m_ServiceOutputFile, GetServiceTempPath(), GetServicePerfdataPath());
RotateFile(m_HostOutputFile, GetHostTempPath(), GetHostPerfdataPath());
} }

View File

@ -51,8 +51,9 @@ private:
Timer::Ptr m_RotationTimer; Timer::Ptr m_RotationTimer;
void RotationTimerHandler(void); void RotationTimerHandler(void);
std::ofstream m_OutputFile; std::ofstream m_ServiceOutputFile;
void RotateFile(void); std::ofstream m_HostOutputFile;
void RotateFile(std::ofstream& output, const String& temp_path, const String& perfdata_path);
}; };
} }

View File

@ -6,13 +6,30 @@ namespace icinga
class PerfdataWriter : DynamicObject class PerfdataWriter : DynamicObject
{ {
[config] String perfdata_path { [config] String host_perfdata_path {
default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/perfdata/perfdata"; }}} default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/perfdata/host-perfdata"; }}}
}; };
[config] String temp_path { [config] String service_perfdata_path {
default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/tmp/perfdata"; }}} default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/perfdata/service-perfdata"; }}}
}; };
[config] String format_template { [config] String host_temp_path {
default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/tmp/host-perfdata"; }}}
};
[config] String service_temp_path {
default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/tmp/service-perfdata"; }}}
};
[config] String host_format_template {
default {{{
return "DATATYPE::HOSTPERFDATA\t"
"TIMET::$TIMET$\t"
"HOSTNAME::$HOSTNAME$\t"
"HOSTPERFDATA::$HOSTPERFDATA$\t"
"HOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\t"
"HOSTSTATE::$HOSTSTATE$\t"
"HOSTSTATETYPE::$HOSTSTATETYPE$";
}}}
};
[config] String service_format_template {
default {{{ default {{{
return "DATATYPE::SERVICEPERFDATA\t" return "DATATYPE::SERVICEPERFDATA\t"
"TIMET::$TIMET$\t" "TIMET::$TIMET$\t"

View File

@ -57,7 +57,7 @@ By default Icinga 2 uses the following files and directories:
/usr/share/icinga2/itl | The Icinga Template Library. /usr/share/icinga2/itl | The Icinga Template Library.
/var/run/icinga2 | PID file. /var/run/icinga2 | PID file.
/var/run/icinga2/cmd | Command pipe and Livestatus socket. /var/run/icinga2/cmd | Command pipe and Livestatus socket.
/var/cache/icinga2 | Performance data files and status.dat/objects.cache. /var/cache/icinga2 | status.dat/objects.cache.
/var/spool/icinga2 | Used for performance data spool files. /var/spool/icinga2 | Used for performance data spool files.
/var/lib/icinga2 | Icinga 2 state file, cluster feature replay log and configuration files. /var/lib/icinga2 | Icinga 2 state file, cluster feature replay log and configuration files.
/var/log/icinga2 | Log file location and compat/ directory for the CompatLogger feature. /var/log/icinga2 | Log file location and compat/ directory for the CompatLogger feature.

View File

@ -13,26 +13,29 @@ inGraph and Graphite.
> **Note** > **Note**
> >
> As there are no real host checks in Icinga 2, there is no performance > As there are no real host checks in Icinga 2, the performance data is
> data generated for hosts. > generated from the host check service, if existing.
### <a id="writing-performance-data-files"></a> Writing Performance Data Files ### <a id="writing-performance-data-files"></a> Writing Performance Data Files
PNP4Nagios and inGraph use performance data collector daemons to fetch PNP4Nagios, inGraph and Graphios use performance data collector daemons to fetch
the current performance files for their backend updates. the current performance files for their backend updates.
Therefore the Icinga 2 `PerfdataWriter` object allows you to define Therefore the Icinga 2 `PerfdataWriter` object allows you to define
the output template format backed with Icinga 2 runtime macros. the output template format for host and services backed with Icinga 2
runtime macros.
format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$" host_format_template = "DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$"
service_format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$"
The default template is already provided with the Icinga 2 feature configuration The default templates are already provided with the Icinga 2 feature configuration
which can be enabled using which can be enabled using
# icinga2-enable-feature perfdata # icinga2-enable-feature perfdata
By default all performance data files are rotated in a 15 seconds interval into By default all performance data files are rotated in a 15 seconds interval into
the `/var/spool/icinga2/perfdata/` directory as `service-perfdata.<timestamp>`. the `/var/spool/icinga2/perfdata/` directory as `host-perfdata.<timestamp>` and
`service-perfdata.<timestamp>`.
External collectors need to parse the rotated performance data files and then External collectors need to parse the rotated performance data files and then
remove the processed files. remove the processed files.
@ -46,9 +49,9 @@ remove the processed files.
### <a id="graphite-carbon-cache-writer"></a> Graphite Carbon Cache Writer ### <a id="graphite-carbon-cache-writer"></a> Graphite Carbon Cache Writer
While there are some Graphite collector scripts for Icinga 1.x available it's While there are some Graphite collector scripts and daemons like Graphios available for
more reasonable to directly process the check and plugin performance in memory Icinga 1.x it's more reasonable to directly process the check and plugin performance
in Icinga 2. Once there are new metrics available, Icinga 2 will directly in memory in Icinga 2. Once there are new metrics available, Icinga 2 will directly
write them to the defined Graphite Carbon daemon tcp socket. write them to the defined Graphite Carbon daemon tcp socket.
You can enable the feature using You can enable the feature using
@ -60,4 +63,5 @@ at `127.0.0.1` on port `2003` by default.
The current naming schema is The current naming schema is
icinga.<hostname>.<metricname>
icinga.<hostname>.<servicename>.<metricname> icinga.<hostname>.<servicename>.<metricname>

View File

@ -523,9 +523,13 @@ Example:
library "perfdata" library "perfdata"
object PerfdataWriter "pnp" { object PerfdataWriter "pnp" {
perfdata_path = "/var/spool/icinga2/perfdata/service-perfdata" host_perfdata_path = "/var/spool/icinga2/perfdata/host-perfdata"
format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$" service_perfdata_path = "/var/spool/icinga2/perfdata/service-perfdata"
host_format_template = "DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$"
service_format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$"
rotation_interval = 15s rotation_interval = 15s
} }
@ -533,16 +537,19 @@ Example:
Attributes: Attributes:
Name |Description Name |Description
----------------|---------------- ------------------------|----------------
perfdata\_path |**Optional.** Path to the service performance data file. Defaults to IcingaLocalStateDir + "/spool/icinga2/perfdata/perfdata". host_perfdata\_path |**Optional.** Path to the host performance data file. Defaults to IcingaLocalStateDir + "/spool/icinga2/perfdata/host-perfdata".
temp\_path |**Optional.** Path to the temporary file. Defaults to IcingaLocalStateDir + "/spool/icinga2/tmp/perfdata". service_perfdata\_path |**Optional.** Path to the service performance data file. Defaults to IcingaLocalStateDir + "/spool/icinga2/perfdata/service-perfdata".
format\_template|**Optional.** Format template for the performance data file. Defaults to a template that's suitable for use with PNP4Nagios. host_temp\_path |**Optional.** Path to the temporary host file. Defaults to IcingaLocalStateDir + "/spool/icinga2/tmp/host-perfdata".
rotation\_interval|**Optional.** Rotation interval for the file specified in `perfdata\_path`. Defaults to 30 seconds. service_temp\_path |**Optional.** Path to the temporary service file. Defaults to IcingaLocalStateDir + "/spool/icinga2/tmp/service-perfdata".
host_format\_template |**Optional.** Host Format template for the performance data file. Defaults to a template that's suitable for use with PNP4Nagios.
service_format\_template|**Optional.** Service Format template for the performance data file. Defaults to a template that's suitable for use with PNP4Nagios.
rotation\_interval |**Optional.** Rotation interval for the files specified in `{host,service}\_perfdata\_path`. Defaults to 30 seconds.
> **Note** > **Note**
> >
> When rotating the performance data file the current UNIX timestamp is appended to the path specified > When rotating the performance data file the current UNIX timestamp is appended to the path specified
> in `perfdata\_path` to generate a unique filename. > in `host_perfdata\_path` and `service_perfdata\_path` to generate a unique filename.
### <a id="objecttype-graphitewriter"></a> GraphiteWriter ### <a id="objecttype-graphitewriter"></a> GraphiteWriter

View File

@ -330,12 +330,6 @@ where the initial state checks must have happened. Icinga 2 will use the
`retry_interval` setting instead and `check_interval` divided by 5 if `retry_interval` setting instead and `check_interval` divided by 5 if
`retry_interval` is not defined. `retry_interval` is not defined.
### <a id="differences-1x-2-performance-data"></a> Performance Data
There is no host performance data generated in Icinga 2 because there are no
real host checks. Therefore the PerfDataWriter will only write service
performance data files.
## <a id="differences-1x-2-commands"></a> Commands ## <a id="differences-1x-2-commands"></a> Commands
Unlike in Icinga 1.x there are 3 different command types in Icinga 2: Unlike in Icinga 1.x there are 3 different command types in Icinga 2:

View File

@ -486,6 +486,15 @@ bool Host::ResolveMacro(const String& macro, const CheckResult::Ptr&, String *re
return true; return true;
} else if (macro == "HOSTPERFDATA") { } else if (macro == "HOSTPERFDATA") {
*result = PluginUtility::FormatPerfdata(hccr->GetPerformanceData()); *result = PluginUtility::FormatPerfdata(hccr->GetPerformanceData());
return true;
} else if (macro == "HOSTCHECKCOMMAND") {
CheckCommand::Ptr commandObj = hc->GetCheckCommand();
if (commandObj)
*result = commandObj->GetName();
else
*result = "";
return true; return true;
} else if (macro == "LASTHOSTCHECK") { } else if (macro == "LASTHOSTCHECK") {
*result = Convert::ToString((long)hccr->GetScheduleStart()); *result = Convert::ToString((long)hccr->GetScheduleStart());