1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
3 #include "icinga/cib.hpp"
4 #include "icinga/host.hpp"
5 #include "icinga/service.hpp"
6 #include "icinga/clusterevents.hpp"
7 #include "base/objectlock.hpp"
8 #include "base/utility.hpp"
9 #include "base/perfdatavalue.hpp"
10 #include "base/configtype.hpp"
11 #include "base/statsfunction.hpp"
13 using namespace icinga;
15 RingBuffer CIB::m_ActiveHostChecksStatistics(15 * 60);
16 RingBuffer CIB::m_ActiveServiceChecksStatistics(15 * 60);
17 RingBuffer CIB::m_PassiveHostChecksStatistics(15 * 60);
18 RingBuffer CIB::m_PassiveServiceChecksStatistics(15 * 60);
20 void CIB::UpdateActiveHostChecksStatistics(long tv, int num)
22 m_ActiveHostChecksStatistics.InsertValue(tv, num);
25 void CIB::UpdateActiveServiceChecksStatistics(long tv, int num)
27 m_ActiveServiceChecksStatistics.InsertValue(tv, num);
30 int CIB::GetActiveHostChecksStatistics(long timespan)
32 return m_ActiveHostChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
35 int CIB::GetActiveServiceChecksStatistics(long timespan)
37 return m_ActiveServiceChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
40 void CIB::UpdatePassiveHostChecksStatistics(long tv, int num)
42 m_PassiveServiceChecksStatistics.InsertValue(tv, num);
45 void CIB::UpdatePassiveServiceChecksStatistics(long tv, int num)
47 m_PassiveServiceChecksStatistics.InsertValue(tv, num);
50 int CIB::GetPassiveHostChecksStatistics(long timespan)
52 return m_PassiveHostChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
55 int CIB::GetPassiveServiceChecksStatistics(long timespan)
57 return m_PassiveServiceChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
60 CheckableCheckStatistics CIB::CalculateHostCheckStats()
62 double min_latency = -1, max_latency = 0, sum_latency = 0;
63 int count_latency = 0;
64 double min_execution_time = -1, max_execution_time = 0, sum_execution_time = 0;
65 int count_execution_time = 0;
66 bool checkresult = false;
68 for (const Host::Ptr& host : ConfigType::GetObjectsByType<Host>()) {
69 ObjectLock olock(host);
71 CheckResult::Ptr cr = host->GetLastCheckResult();
76 /* set to true, we have a checkresult */
80 double latency = cr->CalculateLatency();
82 if (min_latency == -1 || latency < min_latency)
83 min_latency = latency;
85 if (latency > max_latency)
86 max_latency = latency;
88 sum_latency += latency;
92 double execution_time = cr->CalculateExecutionTime();
94 if (min_execution_time == -1 || execution_time < min_execution_time)
95 min_execution_time = execution_time;
97 if (execution_time > max_execution_time)
98 max_execution_time = execution_time;
100 sum_execution_time += execution_time;
101 count_execution_time++;
106 min_execution_time = 0;
109 CheckableCheckStatistics ccs;
111 ccs.min_latency = min_latency;
112 ccs.max_latency = max_latency;
113 ccs.avg_latency = sum_latency / count_latency;
114 ccs.min_execution_time = min_execution_time;
115 ccs.max_execution_time = max_execution_time;
116 ccs.avg_execution_time = sum_execution_time / count_execution_time;
121 CheckableCheckStatistics CIB::CalculateServiceCheckStats()
123 double min_latency = -1, max_latency = 0, sum_latency = 0;
124 int count_latency = 0;
125 double min_execution_time = -1, max_execution_time = 0, sum_execution_time = 0;
126 int count_execution_time = 0;
127 bool checkresult = false;
129 for (const Service::Ptr& service : ConfigType::GetObjectsByType<Service>()) {
130 ObjectLock olock(service);
132 CheckResult::Ptr cr = service->GetLastCheckResult();
137 /* set to true, we have a checkresult */
141 double latency = cr->CalculateLatency();
143 if (min_latency == -1 || latency < min_latency)
144 min_latency = latency;
146 if (latency > max_latency)
147 max_latency = latency;
149 sum_latency += latency;
153 double execution_time = cr->CalculateExecutionTime();
155 if (min_execution_time == -1 || execution_time < min_execution_time)
156 min_execution_time = execution_time;
158 if (execution_time > max_execution_time)
159 max_execution_time = execution_time;
161 sum_execution_time += execution_time;
162 count_execution_time++;
167 min_execution_time = 0;
170 CheckableCheckStatistics ccs;
172 ccs.min_latency = min_latency;
173 ccs.max_latency = max_latency;
174 ccs.avg_latency = sum_latency / count_latency;
175 ccs.min_execution_time = min_execution_time;
176 ccs.max_execution_time = max_execution_time;
177 ccs.avg_execution_time = sum_execution_time / count_execution_time;
182 ServiceStatistics CIB::CalculateServiceStats()
184 ServiceStatistics ss = {};
186 for (const Service::Ptr& service : ConfigType::GetObjectsByType<Service>()) {
187 ObjectLock olock(service);
189 CheckResult::Ptr cr = service->GetLastCheckResult();
191 if (service->GetState() == ServiceOK)
193 if (service->GetState() == ServiceWarning)
194 ss.services_warning++;
195 if (service->GetState() == ServiceCritical)
196 ss.services_critical++;
197 if (service->GetState() == ServiceUnknown)
198 ss.services_unknown++;
201 ss.services_pending++;
202 if (!service->IsReachable())
203 ss.services_unreachable++;
205 if (service->IsFlapping())
206 ss.services_flapping++;
207 if (service->IsInDowntime())
208 ss.services_in_downtime++;
209 if (service->IsAcknowledged())
210 ss.services_acknowledged++;
216 HostStatistics CIB::CalculateHostStats()
218 HostStatistics hs = {};
220 for (const Host::Ptr& host : ConfigType::GetObjectsByType<Host>()) {
221 ObjectLock olock(host);
223 if (host->IsReachable()) {
224 if (host->GetState() == HostUp)
226 if (host->GetState() == HostDown)
229 hs.hosts_unreachable++;
231 if (!host->GetLastCheckResult())
234 if (host->IsFlapping())
236 if (host->IsInDowntime())
237 hs.hosts_in_downtime++;
238 if (host->IsAcknowledged())
239 hs.hosts_acknowledged++;
246 * 'perfdata' must be a flat dictionary with double values
247 * 'status' dictionary can contain multiple levels of dictionaries
249 std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats()
251 Dictionary::Ptr status = new Dictionary();
252 Array::Ptr perfdata = new Array();
254 Namespace::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
256 if (statsFunctions) {
257 ObjectLock olock(statsFunctions);
259 for (const Namespace::Pair& kv : statsFunctions)
260 static_cast<Function::Ptr>(kv.second->Get())->Invoke({ status, perfdata });
263 return std::make_pair(status, perfdata);
266 REGISTER_STATSFUNCTION(CIB, &CIB::StatsFunc);
268 void CIB::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) {
269 double interval = Utility::GetTime() - Application::GetStartTime();
274 status->Set("active_host_checks", GetActiveHostChecksStatistics(interval) / interval);
275 status->Set("passive_host_checks", GetPassiveHostChecksStatistics(interval) / interval);
276 status->Set("active_host_checks_1min", GetActiveHostChecksStatistics(60));
277 status->Set("passive_host_checks_1min", GetPassiveHostChecksStatistics(60));
278 status->Set("active_host_checks_5min", GetActiveHostChecksStatistics(60 * 5));
279 status->Set("passive_host_checks_5min", GetPassiveHostChecksStatistics(60 * 5));
280 status->Set("active_host_checks_15min", GetActiveHostChecksStatistics(60 * 15));
281 status->Set("passive_host_checks_15min", GetPassiveHostChecksStatistics(60 * 15));
283 status->Set("active_service_checks", GetActiveServiceChecksStatistics(interval) / interval);
284 status->Set("passive_service_checks", GetPassiveServiceChecksStatistics(interval) / interval);
285 status->Set("active_service_checks_1min", GetActiveServiceChecksStatistics(60));
286 status->Set("passive_service_checks_1min", GetPassiveServiceChecksStatistics(60));
287 status->Set("active_service_checks_5min", GetActiveServiceChecksStatistics(60 * 5));
288 status->Set("passive_service_checks_5min", GetPassiveServiceChecksStatistics(60 * 5));
289 status->Set("active_service_checks_15min", GetActiveServiceChecksStatistics(60 * 15));
290 status->Set("passive_service_checks_15min", GetPassiveServiceChecksStatistics(60 * 15));
292 status->Set("remote_check_queue", ClusterEvents::GetCheckRequestQueueSize());
294 CheckableCheckStatistics scs = CalculateServiceCheckStats();
296 status->Set("min_latency", scs.min_latency);
297 status->Set("max_latency", scs.max_latency);
298 status->Set("avg_latency", scs.avg_latency);
299 status->Set("min_execution_time", scs.min_execution_time);
300 status->Set("max_execution_time", scs.max_execution_time);
301 status->Set("avg_execution_time", scs.avg_execution_time);
303 ServiceStatistics ss = CalculateServiceStats();
305 status->Set("num_services_ok", ss.services_ok);
306 status->Set("num_services_warning", ss.services_warning);
307 status->Set("num_services_critical", ss.services_critical);
308 status->Set("num_services_unknown", ss.services_unknown);
309 status->Set("num_services_pending", ss.services_pending);
310 status->Set("num_services_unreachable", ss.services_unreachable);
311 status->Set("num_services_flapping", ss.services_flapping);
312 status->Set("num_services_in_downtime", ss.services_in_downtime);
313 status->Set("num_services_acknowledged", ss.services_acknowledged);
315 double uptime = Utility::GetTime() - Application::GetStartTime();
316 status->Set("uptime", uptime);
318 HostStatistics hs = CalculateHostStats();
320 status->Set("num_hosts_up", hs.hosts_up);
321 status->Set("num_hosts_down", hs.hosts_down);
322 status->Set("num_hosts_pending", hs.hosts_pending);
323 status->Set("num_hosts_unreachable", hs.hosts_unreachable);
324 status->Set("num_hosts_flapping", hs.hosts_flapping);
325 status->Set("num_hosts_in_downtime", hs.hosts_in_downtime);
326 status->Set("num_hosts_acknowledged", hs.hosts_acknowledged);