mirror of https://github.com/Icinga/icinga2.git
parent
22c9caa6ec
commit
3fe169cd7a
|
@ -82,7 +82,7 @@ void GraphiteWriter::ReconnectTimerHandler(void)
|
|||
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>();
|
||||
|
@ -99,16 +99,17 @@ void GraphiteWriter::CheckResultHandler(const Service::Ptr& service, const Check
|
|||
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());
|
||||
|
@ -116,6 +117,25 @@ void GraphiteWriter::CheckResultHandler(const Service::Ptr& service, const Check
|
|||
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>())
|
||||
|
|
|
@ -53,6 +53,7 @@ private:
|
|||
|
||||
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);
|
||||
|
|
|
@ -60,7 +60,8 @@ void PerfdataWriter::Start(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)
|
||||
|
@ -77,36 +78,52 @@ void PerfdataWriter::CheckResultHandler(const Service::Ptr& service, const Check
|
|||
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_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);
|
||||
|
||||
String tempFile = GetTempPath();
|
||||
if (output.good()) {
|
||||
output.close();
|
||||
|
||||
if (m_OutputFile.good()) {
|
||||
m_OutputFile.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());
|
||||
}
|
||||
|
||||
|
|
|
@ -51,8 +51,9 @@ private:
|
|||
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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -6,13 +6,30 @@ namespace icinga
|
|||
|
||||
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"
|
||||
|
|
|
@ -57,7 +57,7 @@ By default Icinga 2 uses the following files and directories:
|
|||
/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.
|
||||
|
|
|
@ -13,26 +13,29 @@ inGraph and Graphite.
|
|||
|
||||
> **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.
|
||||
|
||||
|
@ -46,18 +49,19 @@ 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>
|
||||
|
|
|
@ -523,26 +523,33 @@ Example:
|
|||
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
|
||||
|
||||
|
|
|
@ -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` 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:
|
||||
|
|
|
@ -486,6 +486,15 @@ bool Host::ResolveMacro(const String& macro, const CheckResult::Ptr&, String *re
|
|||
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());
|
||||
|
|
Loading…
Reference in New Issue