]> granicus.if.org Git - icinga2/blob - lib/icinga/cib.cpp
Merge pull request #7164 from Icinga/bugfix/notification-times-validate
[icinga2] / lib / icinga / cib.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
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"
12
13 using namespace icinga;
14
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);
19
20 void CIB::UpdateActiveHostChecksStatistics(long tv, int num)
21 {
22         m_ActiveHostChecksStatistics.InsertValue(tv, num);
23 }
24
25 void CIB::UpdateActiveServiceChecksStatistics(long tv, int num)
26 {
27         m_ActiveServiceChecksStatistics.InsertValue(tv, num);
28 }
29
30 int CIB::GetActiveHostChecksStatistics(long timespan)
31 {
32         return m_ActiveHostChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
33 }
34
35 int CIB::GetActiveServiceChecksStatistics(long timespan)
36 {
37         return m_ActiveServiceChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
38 }
39
40 void CIB::UpdatePassiveHostChecksStatistics(long tv, int num)
41 {
42         m_PassiveServiceChecksStatistics.InsertValue(tv, num);
43 }
44
45 void CIB::UpdatePassiveServiceChecksStatistics(long tv, int num)
46 {
47         m_PassiveServiceChecksStatistics.InsertValue(tv, num);
48 }
49
50 int CIB::GetPassiveHostChecksStatistics(long timespan)
51 {
52         return m_PassiveHostChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
53 }
54
55 int CIB::GetPassiveServiceChecksStatistics(long timespan)
56 {
57         return m_PassiveServiceChecksStatistics.UpdateAndGetValues(Utility::GetTime(), timespan);
58 }
59
60 CheckableCheckStatistics CIB::CalculateHostCheckStats()
61 {
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;
67
68         for (const Host::Ptr& host : ConfigType::GetObjectsByType<Host>()) {
69                 ObjectLock olock(host);
70
71                 CheckResult::Ptr cr = host->GetLastCheckResult();
72
73                 if (!cr)
74                         continue;
75
76                 /* set to true, we have a checkresult */
77                 checkresult = true;
78
79                 /* latency */
80                 double latency = cr->CalculateLatency();
81
82                 if (min_latency == -1 || latency < min_latency)
83                         min_latency = latency;
84
85                 if (latency > max_latency)
86                         max_latency = latency;
87
88                 sum_latency += latency;
89                 count_latency++;
90
91                 /* execution_time */
92                 double execution_time = cr->CalculateExecutionTime();
93
94                 if (min_execution_time == -1 || execution_time < min_execution_time)
95                         min_execution_time = execution_time;
96
97                 if (execution_time > max_execution_time)
98                         max_execution_time = execution_time;
99
100                 sum_execution_time += execution_time;
101                 count_execution_time++;
102         }
103
104         if (!checkresult) {
105                 min_latency = 0;
106                 min_execution_time = 0;
107         }
108
109         CheckableCheckStatistics ccs;
110
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;
117
118         return ccs;
119 }
120
121 CheckableCheckStatistics CIB::CalculateServiceCheckStats()
122 {
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;
128
129         for (const Service::Ptr& service : ConfigType::GetObjectsByType<Service>()) {
130                 ObjectLock olock(service);
131
132                 CheckResult::Ptr cr = service->GetLastCheckResult();
133
134                 if (!cr)
135                         continue;
136
137                 /* set to true, we have a checkresult */
138                 checkresult = true;
139
140                 /* latency */
141                 double latency = cr->CalculateLatency();
142
143                 if (min_latency == -1 || latency < min_latency)
144                         min_latency = latency;
145
146                 if (latency > max_latency)
147                         max_latency = latency;
148
149                 sum_latency += latency;
150                 count_latency++;
151
152                 /* execution_time */
153                 double execution_time = cr->CalculateExecutionTime();
154
155                 if (min_execution_time == -1 || execution_time < min_execution_time)
156                         min_execution_time = execution_time;
157
158                 if (execution_time > max_execution_time)
159                         max_execution_time = execution_time;
160
161                 sum_execution_time += execution_time;
162                 count_execution_time++;
163         }
164
165         if (!checkresult) {
166                 min_latency = 0;
167                 min_execution_time = 0;
168         }
169
170         CheckableCheckStatistics ccs;
171
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;
178
179         return ccs;
180 }
181
182 ServiceStatistics CIB::CalculateServiceStats()
183 {
184         ServiceStatistics ss = {};
185
186         for (const Service::Ptr& service : ConfigType::GetObjectsByType<Service>()) {
187                 ObjectLock olock(service);
188
189                 CheckResult::Ptr cr = service->GetLastCheckResult();
190
191                 if (service->GetState() == ServiceOK)
192                         ss.services_ok++;
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++;
199
200                 if (!cr)
201                         ss.services_pending++;
202                 if (!service->IsReachable())
203                         ss.services_unreachable++;
204
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++;
211         }
212
213         return ss;
214 }
215
216 HostStatistics CIB::CalculateHostStats()
217 {
218         HostStatistics hs = {};
219
220         for (const Host::Ptr& host : ConfigType::GetObjectsByType<Host>()) {
221                 ObjectLock olock(host);
222
223                 if (host->IsReachable()) {
224                         if (host->GetState() == HostUp)
225                                 hs.hosts_up++;
226                         if (host->GetState() == HostDown)
227                                 hs.hosts_down++;
228                 } else
229                         hs.hosts_unreachable++;
230
231                 if (!host->GetLastCheckResult())
232                         hs.hosts_pending++;
233
234                 if (host->IsFlapping())
235                         hs.hosts_flapping++;
236                 if (host->IsInDowntime())
237                         hs.hosts_in_downtime++;
238                 if (host->IsAcknowledged())
239                         hs.hosts_acknowledged++;
240         }
241
242         return hs;
243 }
244
245 /*
246  * 'perfdata' must be a flat dictionary with double values
247  * 'status' dictionary can contain multiple levels of dictionaries
248  */
249 std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats()
250 {
251         Dictionary::Ptr status = new Dictionary();
252         Array::Ptr perfdata = new Array();
253
254         Namespace::Ptr statsFunctions = ScriptGlobal::Get("StatsFunctions", &Empty);
255
256         if (statsFunctions) {
257                 ObjectLock olock(statsFunctions);
258
259                 for (const Namespace::Pair& kv : statsFunctions)
260                         static_cast<Function::Ptr>(kv.second->Get())->Invoke({ status, perfdata });
261         }
262
263         return std::make_pair(status, perfdata);
264 }
265
266 REGISTER_STATSFUNCTION(CIB, &CIB::StatsFunc);
267
268 void CIB::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) {
269         double interval = Utility::GetTime() - Application::GetStartTime();
270
271         if (interval > 60)
272                 interval = 60;
273
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));
282
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));
291
292         status->Set("remote_check_queue", ClusterEvents::GetCheckRequestQueueSize());
293
294         CheckableCheckStatistics scs = CalculateServiceCheckStats();
295
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);
302
303         ServiceStatistics ss = CalculateServiceStats();
304
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);
314
315         double uptime = Utility::GetTime() - Application::GetStartTime();
316         status->Set("uptime", uptime);
317
318         HostStatistics hs = CalculateHostStats();
319
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);
327 }