2019-02-25 14:48:22 +01:00
|
|
|
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
2012-07-09 20:32:02 +02:00
|
|
|
|
2014-05-25 16:23:35 +02:00
|
|
|
#include "icinga/cib.hpp"
|
2014-05-26 20:56:34 +02:00
|
|
|
#include "icinga/host.hpp"
|
2014-05-25 16:23:35 +02:00
|
|
|
#include "icinga/service.hpp"
|
2018-01-18 15:22:16 +01:00
|
|
|
#include "icinga/clusterevents.hpp"
|
2019-08-14 17:22:27 +02:00
|
|
|
#include "base/application.hpp"
|
2014-05-25 16:23:35 +02:00
|
|
|
#include "base/objectlock.hpp"
|
|
|
|
#include "base/utility.hpp"
|
2017-05-15 15:51:39 +02:00
|
|
|
#include "base/perfdatavalue.hpp"
|
2015-08-15 20:28:05 +02:00
|
|
|
#include "base/configtype.hpp"
|
2014-05-25 16:23:35 +02:00
|
|
|
#include "base/statsfunction.hpp"
|
2012-07-02 12:34:54 +02:00
|
|
|
|
|
|
|
using namespace icinga;
|
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
RingBuffer CIB::m_ActiveHostChecksStatistics(15 * 60);
|
|
|
|
RingBuffer CIB::m_ActiveServiceChecksStatistics(15 * 60);
|
|
|
|
RingBuffer CIB::m_PassiveHostChecksStatistics(15 * 60);
|
|
|
|
RingBuffer CIB::m_PassiveServiceChecksStatistics(15 * 60);
|
2012-07-02 12:34:54 +02:00
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
void CIB::UpdateActiveHostChecksStatistics(long tv, int num)
|
2012-07-02 12:34:54 +02:00
|
|
|
{
|
2014-05-26 20:56:34 +02:00
|
|
|
m_ActiveHostChecksStatistics.InsertValue(tv, num);
|
2012-07-02 12:34:54 +02:00
|
|
|
}
|
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
void CIB::UpdateActiveServiceChecksStatistics(long tv, int num)
|
2012-07-02 12:34:54 +02:00
|
|
|
{
|
2014-05-26 20:56:34 +02:00
|
|
|
m_ActiveServiceChecksStatistics.InsertValue(tv, num);
|
2013-01-28 09:01:47 +01:00
|
|
|
}
|
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
int CIB::GetActiveHostChecksStatistics(long timespan)
|
2013-01-28 09:01:47 +01:00
|
|
|
{
|
2017-11-13 16:17:59 +01:00
|
|
|
return m_ActiveHostChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
|
2013-01-28 09:01:47 +01:00
|
|
|
}
|
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
int CIB::GetActiveServiceChecksStatistics(long timespan)
|
2013-01-28 09:01:47 +01:00
|
|
|
{
|
2017-11-13 16:17:59 +01:00
|
|
|
return m_ActiveServiceChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
|
2012-07-02 12:34:54 +02:00
|
|
|
}
|
2014-02-10 14:56:39 +01:00
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
void CIB::UpdatePassiveHostChecksStatistics(long tv, int num)
|
|
|
|
{
|
|
|
|
m_PassiveServiceChecksStatistics.InsertValue(tv, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CIB::UpdatePassiveServiceChecksStatistics(long tv, int num)
|
|
|
|
{
|
|
|
|
m_PassiveServiceChecksStatistics.InsertValue(tv, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
int CIB::GetPassiveHostChecksStatistics(long timespan)
|
|
|
|
{
|
2017-11-13 16:17:59 +01:00
|
|
|
return m_PassiveHostChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
|
2014-05-26 20:56:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int CIB::GetPassiveServiceChecksStatistics(long timespan)
|
|
|
|
{
|
2017-11-13 16:17:59 +01:00
|
|
|
return m_PassiveServiceChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
|
2014-05-26 20:56:34 +02:00
|
|
|
}
|
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
CheckableCheckStatistics CIB::CalculateHostCheckStats()
|
2014-05-26 20:56:34 +02:00
|
|
|
{
|
|
|
|
double min_latency = -1, max_latency = 0, sum_latency = 0;
|
|
|
|
int count_latency = 0;
|
|
|
|
double min_execution_time = -1, max_execution_time = 0, sum_execution_time = 0;
|
|
|
|
int count_execution_time = 0;
|
2016-07-25 16:01:44 +02:00
|
|
|
bool checkresult = false;
|
2014-05-26 20:56:34 +02:00
|
|
|
|
2016-08-25 06:19:44 +02:00
|
|
|
for (const Host::Ptr& host : ConfigType::GetObjectsByType<Host>()) {
|
2014-05-26 20:56:34 +02:00
|
|
|
ObjectLock olock(host);
|
|
|
|
|
|
|
|
CheckResult::Ptr cr = host->GetLastCheckResult();
|
|
|
|
|
2016-05-10 11:44:14 +02:00
|
|
|
if (!cr)
|
|
|
|
continue;
|
|
|
|
|
2016-07-25 16:01:44 +02:00
|
|
|
/* set to true, we have a checkresult */
|
|
|
|
checkresult = true;
|
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
/* latency */
|
2016-05-10 11:44:14 +02:00
|
|
|
double latency = cr->CalculateLatency();
|
2014-05-26 20:56:34 +02:00
|
|
|
|
|
|
|
if (min_latency == -1 || latency < min_latency)
|
|
|
|
min_latency = latency;
|
|
|
|
|
|
|
|
if (latency > max_latency)
|
|
|
|
max_latency = latency;
|
|
|
|
|
|
|
|
sum_latency += latency;
|
|
|
|
count_latency++;
|
|
|
|
|
|
|
|
/* execution_time */
|
2016-05-10 11:44:14 +02:00
|
|
|
double execution_time = cr->CalculateExecutionTime();
|
2014-05-26 20:56:34 +02:00
|
|
|
|
|
|
|
if (min_execution_time == -1 || execution_time < min_execution_time)
|
|
|
|
min_execution_time = execution_time;
|
|
|
|
|
|
|
|
if (execution_time > max_execution_time)
|
|
|
|
max_execution_time = execution_time;
|
|
|
|
|
|
|
|
sum_execution_time += execution_time;
|
|
|
|
count_execution_time++;
|
|
|
|
}
|
|
|
|
|
2016-07-25 16:01:44 +02:00
|
|
|
if (!checkresult) {
|
|
|
|
min_latency = 0;
|
|
|
|
min_execution_time = 0;
|
|
|
|
}
|
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
CheckableCheckStatistics ccs;
|
|
|
|
|
|
|
|
ccs.min_latency = min_latency;
|
|
|
|
ccs.max_latency = max_latency;
|
|
|
|
ccs.avg_latency = sum_latency / count_latency;
|
|
|
|
ccs.min_execution_time = min_execution_time;
|
|
|
|
ccs.max_execution_time = max_execution_time;
|
|
|
|
ccs.avg_execution_time = sum_execution_time / count_execution_time;
|
|
|
|
|
|
|
|
return ccs;
|
|
|
|
}
|
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
CheckableCheckStatistics CIB::CalculateServiceCheckStats()
|
2014-02-10 14:56:39 +01:00
|
|
|
{
|
|
|
|
double min_latency = -1, max_latency = 0, sum_latency = 0;
|
|
|
|
int count_latency = 0;
|
|
|
|
double min_execution_time = -1, max_execution_time = 0, sum_execution_time = 0;
|
|
|
|
int count_execution_time = 0;
|
2016-07-25 16:01:44 +02:00
|
|
|
bool checkresult = false;
|
2014-02-10 14:56:39 +01:00
|
|
|
|
2016-08-25 06:19:44 +02:00
|
|
|
for (const Service::Ptr& service : ConfigType::GetObjectsByType<Service>()) {
|
2014-02-10 14:56:39 +01:00
|
|
|
ObjectLock olock(service);
|
|
|
|
|
|
|
|
CheckResult::Ptr cr = service->GetLastCheckResult();
|
|
|
|
|
2016-05-10 11:44:14 +02:00
|
|
|
if (!cr)
|
|
|
|
continue;
|
|
|
|
|
2016-07-25 16:01:44 +02:00
|
|
|
/* set to true, we have a checkresult */
|
|
|
|
checkresult = true;
|
|
|
|
|
2014-02-10 14:56:39 +01:00
|
|
|
/* latency */
|
2016-05-10 11:44:14 +02:00
|
|
|
double latency = cr->CalculateLatency();
|
2014-02-10 14:56:39 +01:00
|
|
|
|
|
|
|
if (min_latency == -1 || latency < min_latency)
|
|
|
|
min_latency = latency;
|
|
|
|
|
|
|
|
if (latency > max_latency)
|
|
|
|
max_latency = latency;
|
|
|
|
|
|
|
|
sum_latency += latency;
|
|
|
|
count_latency++;
|
|
|
|
|
|
|
|
/* execution_time */
|
2016-05-10 11:44:14 +02:00
|
|
|
double execution_time = cr->CalculateExecutionTime();
|
2014-02-10 14:56:39 +01:00
|
|
|
|
|
|
|
if (min_execution_time == -1 || execution_time < min_execution_time)
|
|
|
|
min_execution_time = execution_time;
|
|
|
|
|
|
|
|
if (execution_time > max_execution_time)
|
|
|
|
max_execution_time = execution_time;
|
|
|
|
|
|
|
|
sum_execution_time += execution_time;
|
|
|
|
count_execution_time++;
|
|
|
|
}
|
|
|
|
|
2016-07-25 16:01:44 +02:00
|
|
|
if (!checkresult) {
|
|
|
|
min_latency = 0;
|
|
|
|
min_execution_time = 0;
|
|
|
|
}
|
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
CheckableCheckStatistics ccs;
|
2014-02-10 14:56:39 +01:00
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
ccs.min_latency = min_latency;
|
|
|
|
ccs.max_latency = max_latency;
|
|
|
|
ccs.avg_latency = sum_latency / count_latency;
|
|
|
|
ccs.min_execution_time = min_execution_time;
|
|
|
|
ccs.max_execution_time = max_execution_time;
|
|
|
|
ccs.avg_execution_time = sum_execution_time / count_execution_time;
|
2014-02-10 14:56:39 +01:00
|
|
|
|
2014-05-26 20:56:34 +02:00
|
|
|
return ccs;
|
2014-02-10 14:56:39 +01:00
|
|
|
}
|
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
ServiceStatistics CIB::CalculateServiceStats()
|
2014-02-10 14:56:39 +01:00
|
|
|
{
|
2016-08-24 19:59:13 +02:00
|
|
|
ServiceStatistics ss = {};
|
2014-02-10 14:56:39 +01:00
|
|
|
|
2016-08-25 06:19:44 +02:00
|
|
|
for (const Service::Ptr& service : ConfigType::GetObjectsByType<Service>()) {
|
2014-02-10 14:56:39 +01:00
|
|
|
ObjectLock olock(service);
|
|
|
|
|
2014-04-08 09:11:54 +02:00
|
|
|
if (service->GetState() == ServiceOK)
|
2014-02-10 14:56:39 +01:00
|
|
|
ss.services_ok++;
|
2014-04-08 09:11:54 +02:00
|
|
|
if (service->GetState() == ServiceWarning)
|
2014-02-10 14:56:39 +01:00
|
|
|
ss.services_warning++;
|
2014-04-08 09:11:54 +02:00
|
|
|
if (service->GetState() == ServiceCritical)
|
2014-02-10 14:56:39 +01:00
|
|
|
ss.services_critical++;
|
2014-04-08 09:11:54 +02:00
|
|
|
if (service->GetState() == ServiceUnknown)
|
2014-02-10 14:56:39 +01:00
|
|
|
ss.services_unknown++;
|
|
|
|
|
2019-08-29 17:04:23 +02:00
|
|
|
CheckResult::Ptr cr = service->GetLastCheckResult();
|
|
|
|
|
2014-02-10 14:56:39 +01:00
|
|
|
if (!cr)
|
|
|
|
ss.services_pending++;
|
2019-08-29 17:04:23 +02:00
|
|
|
|
2014-02-10 14:56:39 +01:00
|
|
|
if (!service->IsReachable())
|
|
|
|
ss.services_unreachable++;
|
|
|
|
|
|
|
|
if (service->IsFlapping())
|
|
|
|
ss.services_flapping++;
|
|
|
|
if (service->IsInDowntime())
|
|
|
|
ss.services_in_downtime++;
|
|
|
|
if (service->IsAcknowledged())
|
|
|
|
ss.services_acknowledged++;
|
2019-08-29 17:04:23 +02:00
|
|
|
|
|
|
|
if (service->GetHandled())
|
|
|
|
ss.services_handled++;
|
|
|
|
if (service->GetProblem())
|
|
|
|
ss.services_problem++;
|
2014-02-10 14:56:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return ss;
|
|
|
|
}
|
|
|
|
|
2018-01-04 04:25:35 +01:00
|
|
|
HostStatistics CIB::CalculateHostStats()
|
2014-02-10 14:56:39 +01:00
|
|
|
{
|
2016-08-24 19:59:13 +02:00
|
|
|
HostStatistics hs = {};
|
2014-02-10 14:56:39 +01:00
|
|
|
|
2016-08-25 06:19:44 +02:00
|
|
|
for (const Host::Ptr& host : ConfigType::GetObjectsByType<Host>()) {
|
2014-02-10 14:56:39 +01:00
|
|
|
ObjectLock olock(host);
|
|
|
|
|
2014-04-08 08:54:49 +02:00
|
|
|
if (host->IsReachable()) {
|
|
|
|
if (host->GetState() == HostUp)
|
|
|
|
hs.hosts_up++;
|
|
|
|
if (host->GetState() == HostDown)
|
|
|
|
hs.hosts_down++;
|
|
|
|
} else
|
2014-02-10 14:56:39 +01:00
|
|
|
hs.hosts_unreachable++;
|
|
|
|
|
2014-04-03 15:36:13 +02:00
|
|
|
if (!host->GetLastCheckResult())
|
2014-02-10 14:56:39 +01:00
|
|
|
hs.hosts_pending++;
|
|
|
|
|
2014-04-03 15:36:13 +02:00
|
|
|
if (host->IsFlapping())
|
2014-02-10 14:56:39 +01:00
|
|
|
hs.hosts_flapping++;
|
2014-04-03 15:36:13 +02:00
|
|
|
if (host->IsInDowntime())
|
2014-02-10 14:56:39 +01:00
|
|
|
hs.hosts_in_downtime++;
|
2014-04-03 15:36:13 +02:00
|
|
|
if (host->IsAcknowledged())
|
2014-02-10 14:56:39 +01:00
|
|
|
hs.hosts_acknowledged++;
|
2019-08-29 17:04:23 +02:00
|
|
|
|
|
|
|
if (host->GetHandled())
|
|
|
|
hs.hosts_handled++;
|
|
|
|
if (host->GetProblem())
|
|
|
|
hs.hosts_problem++;
|
2014-02-10 14:56:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return hs;
|
|
|
|
}
|
2014-02-17 16:34:18 +01:00
|
|
|
|
2014-02-18 10:53:44 +01:00
|
|
|
/*
|
|
|
|
* 'perfdata' must be a flat dictionary with double values
|
|
|
|
* 'status' dictionary can contain multiple levels of dictionaries
|
|
|
|
*/
|
2018-01-04 04:25:35 +01:00
|
|
|
std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats()
|
2014-02-17 16:34:18 +01:00
|
|
|
{
|
2014-11-08 21:17:16 +01:00
|
|
|
Dictionary::Ptr status = new Dictionary();
|
|
|
|
Array::Ptr perfdata = new Array();
|
2014-02-17 16:34:18 +01:00
|
|
|
|
2018-08-07 13:55:41 +02:00
|
|
|
Namespace::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
|
2017-11-30 10:46:44 +01:00
|
|
|
|
|
|
|
if (statsFunctions) {
|
|
|
|
ObjectLock olock(statsFunctions);
|
|
|
|
|
2018-08-07 13:55:41 +02:00
|
|
|
for (const Namespace::Pair& kv : statsFunctions)
|
|
|
|
static_cast<Function::Ptr>(kv.second->Get())->Invoke({ status, perfdata });
|
2014-02-17 16:34:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_pair(status, perfdata);
|
|
|
|
}
|
|
|
|
|
2015-09-21 11:44:58 +02:00
|
|
|
REGISTER_STATSFUNCTION(CIB, &CIB::StatsFunc);
|
|
|
|
|
|
|
|
void CIB::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) {
|
|
|
|
double interval = Utility::GetTime() - Application::GetStartTime();
|
|
|
|
|
|
|
|
if (interval > 60)
|
|
|
|
interval = 60;
|
|
|
|
|
|
|
|
status->Set("active_host_checks", GetActiveHostChecksStatistics(interval) / interval);
|
|
|
|
status->Set("passive_host_checks", GetPassiveHostChecksStatistics(interval) / interval);
|
|
|
|
status->Set("active_host_checks_1min", GetActiveHostChecksStatistics(60));
|
|
|
|
status->Set("passive_host_checks_1min", GetPassiveHostChecksStatistics(60));
|
|
|
|
status->Set("active_host_checks_5min", GetActiveHostChecksStatistics(60 * 5));
|
|
|
|
status->Set("passive_host_checks_5min", GetPassiveHostChecksStatistics(60 * 5));
|
|
|
|
status->Set("active_host_checks_15min", GetActiveHostChecksStatistics(60 * 15));
|
|
|
|
status->Set("passive_host_checks_15min", GetPassiveHostChecksStatistics(60 * 15));
|
|
|
|
|
|
|
|
status->Set("active_service_checks", GetActiveServiceChecksStatistics(interval) / interval);
|
|
|
|
status->Set("passive_service_checks", GetPassiveServiceChecksStatistics(interval) / interval);
|
|
|
|
status->Set("active_service_checks_1min", GetActiveServiceChecksStatistics(60));
|
|
|
|
status->Set("passive_service_checks_1min", GetPassiveServiceChecksStatistics(60));
|
|
|
|
status->Set("active_service_checks_5min", GetActiveServiceChecksStatistics(60 * 5));
|
|
|
|
status->Set("passive_service_checks_5min", GetPassiveServiceChecksStatistics(60 * 5));
|
|
|
|
status->Set("active_service_checks_15min", GetActiveServiceChecksStatistics(60 * 15));
|
|
|
|
status->Set("passive_service_checks_15min", GetPassiveServiceChecksStatistics(60 * 15));
|
|
|
|
|
2019-08-06 14:51:10 +02:00
|
|
|
// Checker related stats
|
2018-01-18 15:22:16 +01:00
|
|
|
status->Set("remote_check_queue", ClusterEvents::GetCheckRequestQueueSize());
|
2019-08-14 17:22:27 +02:00
|
|
|
status->Set("current_pending_callbacks", Application::GetTP().GetPending());
|
2019-08-14 17:43:06 +02:00
|
|
|
status->Set("current_concurrent_checks", Checkable::CurrentConcurrentChecks.load());
|
2018-01-18 15:22:16 +01:00
|
|
|
|
2015-09-21 11:44:58 +02:00
|
|
|
CheckableCheckStatistics scs = CalculateServiceCheckStats();
|
|
|
|
|
|
|
|
status->Set("min_latency", scs.min_latency);
|
|
|
|
status->Set("max_latency", scs.max_latency);
|
|
|
|
status->Set("avg_latency", scs.avg_latency);
|
2016-07-25 17:28:24 +02:00
|
|
|
status->Set("min_execution_time", scs.min_execution_time);
|
|
|
|
status->Set("max_execution_time", scs.max_execution_time);
|
2015-09-21 11:44:58 +02:00
|
|
|
status->Set("avg_execution_time", scs.avg_execution_time);
|
|
|
|
|
|
|
|
ServiceStatistics ss = CalculateServiceStats();
|
|
|
|
|
|
|
|
status->Set("num_services_ok", ss.services_ok);
|
|
|
|
status->Set("num_services_warning", ss.services_warning);
|
|
|
|
status->Set("num_services_critical", ss.services_critical);
|
|
|
|
status->Set("num_services_unknown", ss.services_unknown);
|
|
|
|
status->Set("num_services_pending", ss.services_pending);
|
|
|
|
status->Set("num_services_unreachable", ss.services_unreachable);
|
|
|
|
status->Set("num_services_flapping", ss.services_flapping);
|
|
|
|
status->Set("num_services_in_downtime", ss.services_in_downtime);
|
|
|
|
status->Set("num_services_acknowledged", ss.services_acknowledged);
|
2019-08-29 17:04:23 +02:00
|
|
|
status->Set("num_services_handled", ss.services_handled);
|
|
|
|
status->Set("num_services_problem", ss.services_problem);
|
2015-09-21 11:44:58 +02:00
|
|
|
|
|
|
|
double uptime = Utility::GetTime() - Application::GetStartTime();
|
|
|
|
status->Set("uptime", uptime);
|
|
|
|
|
|
|
|
HostStatistics hs = CalculateHostStats();
|
|
|
|
|
|
|
|
status->Set("num_hosts_up", hs.hosts_up);
|
|
|
|
status->Set("num_hosts_down", hs.hosts_down);
|
2015-11-26 20:03:46 +01:00
|
|
|
status->Set("num_hosts_pending", hs.hosts_pending);
|
2015-09-21 11:44:58 +02:00
|
|
|
status->Set("num_hosts_unreachable", hs.hosts_unreachable);
|
|
|
|
status->Set("num_hosts_flapping", hs.hosts_flapping);
|
|
|
|
status->Set("num_hosts_in_downtime", hs.hosts_in_downtime);
|
|
|
|
status->Set("num_hosts_acknowledged", hs.hosts_acknowledged);
|
2019-08-29 17:04:23 +02:00
|
|
|
status->Set("num_hosts_handled", hs.hosts_handled);
|
|
|
|
status->Set("num_hosts_problem", hs.hosts_problem);
|
2015-09-21 11:44:58 +02:00
|
|
|
}
|