1 /******************************************************************************
3 * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
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. *
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. *
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 ******************************************************************************/
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>
30 using namespace icinga;
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);
37 void CIB::UpdateActiveHostChecksStatistics(long tv, int num)
39 m_ActiveHostChecksStatistics.InsertValue(tv, num);
42 void CIB::UpdateActiveServiceChecksStatistics(long tv, int num)
44 m_ActiveServiceChecksStatistics.InsertValue(tv, num);
47 int CIB::GetActiveHostChecksStatistics(long timespan)
49 return m_ActiveHostChecksStatistics.GetValues(timespan);
52 int CIB::GetActiveServiceChecksStatistics(long timespan)
54 return m_ActiveServiceChecksStatistics.GetValues(timespan);
57 void CIB::UpdatePassiveHostChecksStatistics(long tv, int num)
59 m_PassiveServiceChecksStatistics.InsertValue(tv, num);
62 void CIB::UpdatePassiveServiceChecksStatistics(long tv, int num)
64 m_PassiveServiceChecksStatistics.InsertValue(tv, num);
67 int CIB::GetPassiveHostChecksStatistics(long timespan)
69 return m_PassiveHostChecksStatistics.GetValues(timespan);
72 int CIB::GetPassiveServiceChecksStatistics(long timespan)
74 return m_PassiveServiceChecksStatistics.GetValues(timespan);
77 CheckableCheckStatistics CIB::CalculateHostCheckStats(void)
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;
84 BOOST_FOREACH(const Host::Ptr& host, ConfigType::GetObjectsByType<Host>()) {
85 ObjectLock olock(host);
87 CheckResult::Ptr cr = host->GetLastCheckResult();
90 double latency = Host::CalculateLatency(cr);
92 if (min_latency == -1 || latency < min_latency)
93 min_latency = latency;
95 if (latency > max_latency)
96 max_latency = latency;
98 sum_latency += latency;
102 double execution_time = Host::CalculateExecutionTime(cr);
104 if (min_execution_time == -1 || execution_time < min_execution_time)
105 min_execution_time = execution_time;
107 if (execution_time > max_execution_time)
108 max_execution_time = execution_time;
110 sum_execution_time += execution_time;
111 count_execution_time++;
114 CheckableCheckStatistics ccs;
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;
126 CheckableCheckStatistics CIB::CalculateServiceCheckStats(void)
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;
133 BOOST_FOREACH(const Service::Ptr& service, ConfigType::GetObjectsByType<Service>()) {
134 ObjectLock olock(service);
136 CheckResult::Ptr cr = service->GetLastCheckResult();
139 double latency = Service::CalculateLatency(cr);
141 if (min_latency == -1 || latency < min_latency)
142 min_latency = latency;
144 if (latency > max_latency)
145 max_latency = latency;
147 sum_latency += latency;
151 double execution_time = Service::CalculateExecutionTime(cr);
153 if (min_execution_time == -1 || execution_time < min_execution_time)
154 min_execution_time = execution_time;
156 if (execution_time > max_execution_time)
157 max_execution_time = execution_time;
159 sum_execution_time += execution_time;
160 count_execution_time++;
163 CheckableCheckStatistics ccs;
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;
175 ServiceStatistics CIB::CalculateServiceStats(void)
177 ServiceStatistics ss = {0};
179 BOOST_FOREACH(const Service::Ptr& service, ConfigType::GetObjectsByType<Service>()) {
180 ObjectLock olock(service);
182 CheckResult::Ptr cr = service->GetLastCheckResult();
184 if (service->GetState() == ServiceOK)
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++;
194 ss.services_pending++;
195 if (!service->IsReachable())
196 ss.services_unreachable++;
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++;
209 HostStatistics CIB::CalculateHostStats(void)
211 HostStatistics hs = {0};
213 BOOST_FOREACH(const Host::Ptr& host, ConfigType::GetObjectsByType<Host>()) {
214 ObjectLock olock(host);
216 if (host->IsReachable()) {
217 if (host->GetState() == HostUp)
219 if (host->GetState() == HostDown)
222 hs.hosts_unreachable++;
224 if (!host->GetLastCheckResult())
227 if (host->IsFlapping())
229 if (host->IsInDowntime())
230 hs.hosts_in_downtime++;
231 if (host->IsAcknowledged())
232 hs.hosts_acknowledged++;
239 * 'perfdata' must be a flat dictionary with double values
240 * 'status' dictionary can contain multiple levels of dictionaries
242 std::pair<Dictionary::Ptr, Array::Ptr> CIB::GetFeatureStats(void)
244 Dictionary::Ptr status = new Dictionary();
245 Array::Ptr perfdata = new Array();
248 BOOST_FOREACH(tie(name, boost::tuples::ignore), StatsFunctionRegistry::GetInstance()->GetItems()) {
249 StatsFunction::Ptr func = StatsFunctionRegistry::GetInstance()->GetItem(name);
252 BOOST_THROW_EXCEPTION(std::invalid_argument("Function '" + name + "' does not exist."));
254 func->Invoke(status, perfdata);
257 return std::make_pair(status, perfdata);
260 REGISTER_STATSFUNCTION(CIB, &CIB::StatsFunc);
262 void CIB::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) {
263 double interval = Utility::GetTime() - Application::GetStartTime();
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));
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));
286 CheckableCheckStatistics scs = CalculateServiceCheckStats();
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);
295 ServiceStatistics ss = CalculateServiceStats();
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);
307 double uptime = Utility::GetTime() - Application::GetStartTime();
308 status->Set("uptime", uptime);
310 HostStatistics hs = CalculateHostStats();
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);