return;
}
} catch (const std::exception& ex) {
- Log(LogWarning, "perfdata", "GraphiteWriter socket on host '" + GetHost() + "' port '" + GetPort() + "' gone. Attempting to reconnect.");
+ Log(LogWarning, "perfdata", "GraphiteWriter socket on host '" + GetHost() + "' port '" + GetPort() + "' gone. Attempting to reconnect.");
}
TcpSocket::Ptr socket = make_shared<TcpSocket>();
if (!IcingaApplication::GetInstance()->GetEnablePerfdata() || !service->GetEnablePerfdata())
return;
- /* TODO: sanitize host and service names */
- String hostName = service->GetHost()->GetName();
- String serviceName = service->GetShortName();
+ Host::Ptr host = service->GetHost();
+
+ String hostName = host->GetName();
+ String serviceName = service->GetShortName();
SanitizeMetric(hostName);
SanitizeMetric(serviceName);
String prefix = "icinga." + hostName + "." + serviceName;
- /* basic metrics */
+ /* service metrics */
SendMetric(prefix, "current_attempt", service->GetCheckAttempt());
SendMetric(prefix, "max_check_attempts", service->GetMaxCheckAttempts());
SendMetric(prefix, "state_type", service->GetStateType());
SendMetric(prefix, "latency", Service::CalculateLatency(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();
if (!pdv.IsObjectType<Dictionary>())
void CheckResultHandler(const Service::Ptr& service, const CheckResult::Ptr& cr);
void SendMetric(const String& prefix, const String& name, double value);
+ void SendPerfdata(const String& prefix, const CheckResult::Ptr& cr);
static void SanitizeMetric(String& str);
void ReconnectTimerHandler(void);
m_RotationTimer->SetInterval(GetRotationInterval());
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)
resolvers.push_back(host);
resolvers.push_back(IcingaApplication::GetInstance());
- String line = MacroProcessor::ResolveMacros(GetFormatTemplate(), resolvers, cr);
+ String line = MacroProcessor::ResolveMacros(GetServiceFormatTemplate(), resolvers, cr);
- ObjectLock olock(this);
- if (!m_OutputFile.good())
- return;
+ {
+ ObjectLock olock(this);
+ if (!m_ServiceOutputFile.good())
+ return;
+
+ m_ServiceOutputFile << line << "\n";
+ }
- m_OutputFile << 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);
- String tempFile = GetTempPath();
-
- if (m_OutputFile.good()) {
- m_OutputFile.close();
+ if (output.good()) {
+ output.close();
- String finalFile = GetPerfdataPath() + "." + Convert::ToString((long)Utility::GetTime());
- (void) rename(tempFile.CStr(), finalFile.CStr());
+ String finalFile = perfdata_path + "." + Convert::ToString((long)Utility::GetTime());
+ (void) rename(temp_path.CStr(), finalFile.CStr());
}
- m_OutputFile.open(tempFile.CStr());
+ output.open(temp_path.CStr());
- if (!m_OutputFile.good())
- Log(LogWarning, "icinga", "Could not open perfdata file '" + tempFile + "' for writing. Perfdata will be lost.");
+ if (!output.good())
+ Log(LogWarning, "icinga", "Could not open perfdata file '" + temp_path + "' for writing. Perfdata will be lost.");
}
void PerfdataWriter::RotationTimerHandler(void)
{
- RotateFile();
+ RotateFile(m_ServiceOutputFile, GetServiceTempPath(), GetServicePerfdataPath());
+ RotateFile(m_HostOutputFile, GetHostTempPath(), GetHostPerfdataPath());
}
Timer::Ptr m_RotationTimer;
void RotationTimerHandler(void);
- std::ofstream m_OutputFile;
- void RotateFile(void);
+ std::ofstream m_ServiceOutputFile;
+ std::ofstream m_HostOutputFile;
+ void RotateFile(std::ofstream& output, const String& temp_path, const String& perfdata_path);
};
}
class PerfdataWriter : DynamicObject
{
- [config] String perfdata_path {
- default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/perfdata/perfdata"; }}}
+ [config] String host_perfdata_path {
+ default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/perfdata/host-perfdata"; }}}
};
- [config] String temp_path {
- default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/tmp/perfdata"; }}}
+ [config] String service_perfdata_path {
+ 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 {{{
return "DATATYPE::SERVICEPERFDATA\t"
"TIMET::$TIMET$\t"
/usr/share/icinga2/itl | The Icinga Template Library.
/var/run/icinga2 | PID file.
/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/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.
> **Note**
>
-> As there are no real host checks in Icinga 2, there is no performance
-> data generated for hosts.
+> As there are no real host checks in Icinga 2, the performance data is
+> generated from the host check service, if existing.
### <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.
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$"
-
-The default template is already provided with the Icinga 2 feature configuration
+ 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 templates are already provided with the Icinga 2 feature configuration
which can be enabled using
# icinga2-enable-feature perfdata
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
remove the processed files.
### <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
-more reasonable to directly process the check and plugin performance in memory
-in Icinga 2. Once there are new metrics available, Icinga 2 will directly
+While there are some Graphite collector scripts and daemons like Graphios available for
+Icinga 1.x it's more reasonable to directly process the check and plugin performance
+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.
You can enable the feature using
# icinga2-enable-feature graphite
-
+
The `GraphiteWriter` object expects the Graphite Carbon Cache socket listening
at `127.0.0.1` on port `2003` by default.
The current naming schema is
+ icinga.<hostname>.<metricname>
icinga.<hostname>.<servicename>.<metricname>
library "perfdata"
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
}
Attributes:
- Name |Description
- ----------------|----------------
- perfdata\_path |**Optional.** Path to the service performance data file. Defaults to IcingaLocalStateDir + "/spool/icinga2/perfdata/perfdata".
- temp\_path |**Optional.** Path to the temporary file. Defaults to IcingaLocalStateDir + "/spool/icinga2/tmp/perfdata".
- format\_template|**Optional.** 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 file specified in `perfdata\_path`. Defaults to 30 seconds.
+ Name |Description
+ ------------------------|----------------
+ host_perfdata\_path |**Optional.** Path to the host performance data file. Defaults to IcingaLocalStateDir + "/spool/icinga2/perfdata/host-perfdata".
+ service_perfdata\_path |**Optional.** Path to the service performance data file. Defaults to IcingaLocalStateDir + "/spool/icinga2/perfdata/service-perfdata".
+ host_temp\_path |**Optional.** Path to the temporary host file. Defaults to IcingaLocalStateDir + "/spool/icinga2/tmp/host-perfdata".
+ 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**
>
> 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
`retry_interval` setting instead and `check_interval` divided by 5 if
`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
Unlike in Icinga 1.x there are 3 different command types in Icinga 2:
return true;
} else if (macro == "HOSTPERFDATA") {
*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;
} else if (macro == "LASTHOSTCHECK") {
*result = Convert::ToString((long)hccr->GetScheduleStart());