]> granicus.if.org Git - icinga2/blob - lib/icinga/cib.cpp
Fix missing num_hosts_pending in /v1/status/CIB
[icinga2] / lib / icinga / cib.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org)    *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "icinga/cib.hpp"
21 #include "icinga/host.hpp"
22 #include "icinga/service.hpp"
23 #include "icinga/perfdatavalue.hpp"
24 #include "base/objectlock.hpp"
25 #include "base/utility.hpp"
26 #include "base/configtype.hpp"
27 #include "base/statsfunction.hpp"
28 #include <boost/foreach.hpp>
29
30 using namespace icinga;
31
32 RingBuffer CIB::m_ActiveHostChecksStatistics(15 * 60);
33 RingBuffer CIB::m_ActiveServiceChecksStatistics(15 * 60);
34 RingBuffer CIB::m_PassiveHostChecksStatistics(15 * 60);
35 RingBuffer CIB::m_PassiveServiceChecksStatistics(15 * 60);
36
37 void CIB::UpdateActiveHostChecksStatistics(long tv, int num)
38 {
39         m_ActiveHostChecksStatistics.InsertValue(tv, num);
40 }
41
42 void CIB::UpdateActiveServiceChecksStatistics(long tv, int num)
43 {
44         m_ActiveServiceChecksStatistics.InsertValue(tv, num);
45 }
46
47 int CIB::GetActiveHostChecksStatistics(long timespan)
48 {
49         return m_ActiveHostChecksStatistics.GetValues(timespan);
50 }
51
52 int CIB::GetActiveServiceChecksStatistics(long timespan)
53 {
54         return m_ActiveServiceChecksStatistics.GetValues(timespan);
55 }
56
57 void CIB::UpdatePassiveHostChecksStatistics(long tv, int num)
58 {
59         m_PassiveServiceChecksStatistics.InsertValue(tv, num);
60 }
61
62 void CIB::UpdatePassiveServiceChecksStatistics(long tv, int num)
63 {
64         m_PassiveServiceChecksStatistics.InsertValue(tv, num);
65 }
66
67 int CIB::GetPassiveHostChecksStatistics(long timespan)
68 {
69         return m_PassiveHostChecksStatistics.GetValues(timespan);
70 }
71
72 int CIB::GetPassiveServiceChecksStatistics(long timespan)
73 {
74         return m_PassiveServiceChecksStatistics.GetValues(timespan);
75 }
76
77 CheckableCheckStatistics CIB::CalculateHostCheckStats(void)
78 {
79         double min_latency = -1, max_latency = 0, sum_latency = 0;
80         int count_latency = 0;
81         double min_execution_time = -1, max_execution_time = 0, sum_execution_time = 0;
82         int count_execution_time = 0;
83
84         BOOST_FOREACH(const Host::Ptr& host, ConfigType::GetObjectsByType<Host>()) {
85                 ObjectLock olock(host);
86
87                 CheckResult::Ptr cr = host->GetLastCheckResult();
88
89                 /* latency */
90                 double latency = Host::CalculateLatency(cr);
91
92                 if (min_latency == -1 || latency < min_latency)
93                         min_latency = latency;
94
95                 if (latency > max_latency)
96                         max_latency = latency;
97
98                 sum_latency += latency;
99                 count_latency++;
100
101                 /* execution_time */
102                 double execution_time = Host::CalculateExecutionTime(cr);
103
104                 if (min_execution_time == -1 || execution_time < min_execution_time)
105                         min_execution_time = execution_time;
106
107                 if (execution_time > max_execution_time)
108                         max_execution_time = execution_time;
109
110                 sum_execution_time += execution_time;
111                 count_execution_time++;
112         }
113
114         CheckableCheckStatistics ccs;
115
116         ccs.min_latency = min_latency;
117         ccs.max_latency = max_latency;
118         ccs.avg_latency = sum_latency / count_latency;
119         ccs.min_execution_time = min_execution_time;
120         ccs.max_execution_time = max_execution_time;
121         ccs.avg_execution_time = sum_execution_time / count_execution_time;
122
123         return ccs;
124 }
125
126 CheckableCheckStatistics CIB::CalculateServiceCheckStats(void)
127 {
128         double min_latency = -1, max_latency = 0, sum_latency = 0;
129         int count_latency = 0;
130         double min_execution_time = -1, max_execution_time = 0, sum_execution_time = 0;
131         int count_execution_time = 0;
132
133         BOOST_FOREACH(const Service::Ptr& service, ConfigType::GetObjectsByType<Service>()) {
134                 ObjectLock olock(service);
135
136                 CheckResult::Ptr cr = service->GetLastCheckResult();
137
138                 /* latency */
139                 double latency = Service::CalculateLatency(cr);
140
141                 if (min_latency == -1 || latency < min_latency)
142                         min_latency = latency;
143
144                 if (latency > max_latency)
145                         max_latency = latency;
146
147                 sum_latency += latency;
148                 count_latency++;
149
150                 /* execution_time */
151                 double execution_time = Service::CalculateExecutionTime(cr);
152
153                 if (min_execution_time == -1 || execution_time < min_execution_time)
154                         min_execution_time = execution_time;
155
156                 if (execution_time > max_execution_time)
157                         max_execution_time = execution_time;
158
159                 sum_execution_time += execution_time;
160                 count_execution_time++;
161         }
162
163         CheckableCheckStatistics ccs;
164
165         ccs.min_latency = min_latency;
166         ccs.max_latency = max_latency;
167         ccs.avg_latency = sum_latency / count_latency;
168         ccs.min_execution_time = min_execution_time;
169         ccs.max_execution_time = max_execution_time;
170         ccs.avg_execution_time = sum_execution_time / count_execution_time;
171
172         return ccs;
173 }
174
175 ServiceStatistics CIB::CalculateServiceStats(void)
176 {
177         ServiceStatistics ss = {0};
178
179         BOOST_FOREACH(const Service::Ptr& service, ConfigType::GetObjectsByType<Service>()) {
180                 ObjectLock olock(service);
181
182                 CheckResult::Ptr cr = service->GetLastCheckResult();
183
184                 if (service->GetState() == ServiceOK)
185                         ss.services_ok++;
186                 if (service->GetState() == ServiceWarning)
187                         ss.services_warning++;
188                 if (service->GetState() == ServiceCritical)
189                         ss.services_critical++;
190                 if (service->GetState() == ServiceUnknown)
191                         ss.services_unknown++;
192
193                 if (!cr)
194                         ss.services_pending++;
195                 if (!service->IsReachable())
196                         ss.services_unreachable++;
197
198                 if (service->IsFlapping())
199                         ss.services_flapping++;
200                 if (service->IsInDowntime())
201                         ss.services_in_downtime++;
202                 if (service->IsAcknowledged())
203                         ss.services_acknowledged++;
204         }
205
206         return ss;
207 }
208
209 HostStatistics CIB::CalculateHostStats(void)
210 {
211         HostStatistics hs = {0};
212
213         BOOST_FOREACH(const Host::Ptr& host, ConfigType::GetObjectsByType<Host>()) {
214                 ObjectLock olock(host);
215
216                 if (host->IsReachable()) {
217                         if (host->GetState() == HostUp)
218                                 hs.hosts_up++;
219                         if (host->GetState() == HostDown)
220                                 hs.hosts_down++;
221                 } else
222                         hs.hosts_unreachable++;
223
224                 if (!host->GetLastCheckResult())
225                         hs.hosts_pending++;
226
227                 if (host->IsFlapping())
228                         hs.hosts_flapping++;
229                 if (host->IsInDowntime())
230                         hs.hosts_in_downtime++;
231                 if (host->IsAcknowledged())
232                         hs.hosts_acknowledged++;
233         }
234
235         return hs;
236 }
237
238 /*
239  * 'perfdata' must be a flat dictionary with double values
240  * 'status' dictionary can contain multiple levels of dictionaries
241  */
242 std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats(void)
243 {
244         Dictionary::Ptr status = new Dictionary();
245         Array::Ptr perfdata = new Array();
246
247         String name;
248         BOOST_FOREACH(tie(name, boost::tuples::ignore), StatsFunctionRegistry::GetInstance()->GetItems()) {
249                 StatsFunction::Ptr func = StatsFunctionRegistry::GetInstance()->GetItem(name);
250
251                 if (!func)
252                         BOOST_THROW_EXCEPTION(std::invalid_argument("Function '" + name + "' does not exist."));
253
254                 func->Invoke(status, perfdata);
255         }
256
257         return std::make_pair(status, perfdata);
258 }
259
260 REGISTER_STATSFUNCTION(CIB, &CIB::StatsFunc);
261
262 void CIB::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) {
263         double interval = Utility::GetTime() - Application::GetStartTime();
264
265         if (interval > 60)
266                 interval = 60;
267
268         status->Set("active_host_checks", GetActiveHostChecksStatistics(interval) / interval);
269         status->Set("passive_host_checks", GetPassiveHostChecksStatistics(interval) / interval);
270         status->Set("active_host_checks_1min", GetActiveHostChecksStatistics(60));
271         status->Set("passive_host_checks_1min", GetPassiveHostChecksStatistics(60));
272         status->Set("active_host_checks_5min", GetActiveHostChecksStatistics(60 * 5));
273         status->Set("passive_host_checks_5min", GetPassiveHostChecksStatistics(60 * 5));
274         status->Set("active_host_checks_15min", GetActiveHostChecksStatistics(60 * 15));
275         status->Set("passive_host_checks_15min", GetPassiveHostChecksStatistics(60 * 15));
276
277         status->Set("active_service_checks", GetActiveServiceChecksStatistics(interval) / interval);
278         status->Set("passive_service_checks", GetPassiveServiceChecksStatistics(interval) / interval);
279         status->Set("active_service_checks_1min", GetActiveServiceChecksStatistics(60));
280         status->Set("passive_service_checks_1min", GetPassiveServiceChecksStatistics(60));
281         status->Set("active_service_checks_5min", GetActiveServiceChecksStatistics(60 * 5));
282         status->Set("passive_service_checks_5min", GetPassiveServiceChecksStatistics(60 * 5));
283         status->Set("active_service_checks_15min", GetActiveServiceChecksStatistics(60 * 15));
284         status->Set("passive_service_checks_15min", GetPassiveServiceChecksStatistics(60 * 15));
285
286         CheckableCheckStatistics scs = CalculateServiceCheckStats();
287
288         status->Set("min_latency", scs.min_latency);
289         status->Set("max_latency", scs.max_latency);
290         status->Set("avg_latency", scs.avg_latency);
291         status->Set("min_execution_time", scs.min_latency);
292         status->Set("max_execution_time", scs.max_latency);
293         status->Set("avg_execution_time", scs.avg_execution_time);
294
295         ServiceStatistics ss = CalculateServiceStats();
296
297         status->Set("num_services_ok", ss.services_ok);
298         status->Set("num_services_warning", ss.services_warning);
299         status->Set("num_services_critical", ss.services_critical);
300         status->Set("num_services_unknown", ss.services_unknown);
301         status->Set("num_services_pending", ss.services_pending);
302         status->Set("num_services_unreachable", ss.services_unreachable);
303         status->Set("num_services_flapping", ss.services_flapping);
304         status->Set("num_services_in_downtime", ss.services_in_downtime);
305         status->Set("num_services_acknowledged", ss.services_acknowledged);
306
307         double uptime = Utility::GetTime() - Application::GetStartTime();
308         status->Set("uptime", uptime);
309
310         HostStatistics hs = CalculateHostStats();
311
312         status->Set("num_hosts_up", hs.hosts_up);
313         status->Set("num_hosts_down", hs.hosts_down);
314         status->Set("num_hosts_pending", hs.hosts_pending);
315         status->Set("num_hosts_unreachable", hs.hosts_unreachable);
316         status->Set("num_hosts_flapping", hs.hosts_flapping);
317         status->Set("num_hosts_in_downtime", hs.hosts_in_downtime);
318         status->Set("num_hosts_acknowledged", hs.hosts_acknowledged);
319 }