1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2 
3 #include "livestatus/statustable.hpp"
4 #include "livestatus/livestatuslistener.hpp"
5 #include "icinga/icingaapplication.hpp"
6 #include "icinga/cib.hpp"
7 #include "icinga/host.hpp"
8 #include "icinga/service.hpp"
9 #include "base/configtype.hpp"
10 #include "base/utility.hpp"
11 #include "base/application.hpp"
12 
13 using namespace icinga;
14 
StatusTable()15 StatusTable::StatusTable()
16 {
17 	AddColumns(this);
18 }
19 
AddColumns(Table * table,const String & prefix,const Column::ObjectAccessor & objectAccessor)20 void StatusTable::AddColumns(Table *table, const String& prefix,
21 	const Column::ObjectAccessor& objectAccessor)
22 {
23 	table->AddColumn(prefix + "neb_callbacks", Column(&Table::ZeroAccessor, objectAccessor));
24 	table->AddColumn(prefix + "neb_callbacks_rate", Column(&Table::ZeroAccessor, objectAccessor));
25 
26 	table->AddColumn(prefix + "requests", Column(&Table::ZeroAccessor, objectAccessor));
27 	table->AddColumn(prefix + "requests_rate", Column(&Table::ZeroAccessor, objectAccessor));
28 
29 	table->AddColumn(prefix + "connections", Column(&StatusTable::ConnectionsAccessor, objectAccessor));
30 	table->AddColumn(prefix + "connections_rate", Column(&StatusTable::ConnectionsRateAccessor, objectAccessor));
31 
32 	table->AddColumn(prefix + "service_checks", Column(&StatusTable::ServiceChecksAccessor, objectAccessor));
33 	table->AddColumn(prefix + "service_checks_rate", Column(&StatusTable::ServiceChecksRateAccessor, objectAccessor));
34 
35 	table->AddColumn(prefix + "host_checks", Column(&StatusTable::HostChecksAccessor, objectAccessor));
36 	table->AddColumn(prefix + "host_checks_rate", Column(&StatusTable::HostChecksRateAccessor, objectAccessor));
37 
38 	table->AddColumn(prefix + "forks", Column(&Table::ZeroAccessor, objectAccessor));
39 	table->AddColumn(prefix + "forks_rate", Column(&Table::ZeroAccessor, objectAccessor));
40 
41 	table->AddColumn(prefix + "log_messages", Column(&Table::ZeroAccessor, objectAccessor));
42 	table->AddColumn(prefix + "log_messages_rate", Column(&Table::ZeroAccessor, objectAccessor));
43 
44 	table->AddColumn(prefix + "external_commands", Column(&StatusTable::ExternalCommandsAccessor, objectAccessor));
45 	table->AddColumn(prefix + "external_commands_rate", Column(&StatusTable::ExternalCommandsRateAccessor, objectAccessor));
46 
47 	table->AddColumn(prefix + "livechecks", Column(&Table::ZeroAccessor, objectAccessor));
48 	table->AddColumn(prefix + "livechecks_rate", Column(&Table::ZeroAccessor, objectAccessor));
49 
50 	table->AddColumn(prefix + "livecheck_overflows", Column(&Table::ZeroAccessor, objectAccessor));
51 	table->AddColumn(prefix + "livecheck_overflows_rate", Column(&Table::ZeroAccessor, objectAccessor));
52 
53 	table->AddColumn(prefix + "nagios_pid", Column(&StatusTable::NagiosPidAccessor, objectAccessor));
54 	table->AddColumn(prefix + "enable_notifications", Column(&StatusTable::EnableNotificationsAccessor, objectAccessor));
55 	table->AddColumn(prefix + "execute_service_checks", Column(&StatusTable::ExecuteServiceChecksAccessor, objectAccessor));
56 	table->AddColumn(prefix + "accept_passive_service_checks", Column(&Table::OneAccessor, objectAccessor));
57 	table->AddColumn(prefix + "execute_host_checks", Column(&StatusTable::ExecuteHostChecksAccessor, objectAccessor));
58 	table->AddColumn(prefix + "accept_passive_host_checks", Column(&Table::OneAccessor, objectAccessor));
59 	table->AddColumn(prefix + "enable_event_handlers", Column(&StatusTable::EnableEventHandlersAccessor, objectAccessor));
60 	table->AddColumn(prefix + "obsess_over_services", Column(&Table::ZeroAccessor, objectAccessor));
61 	table->AddColumn(prefix + "obsess_over_hosts", Column(&Table::ZeroAccessor, objectAccessor));
62 	table->AddColumn(prefix + "check_service_freshness", Column(&Table::OneAccessor, objectAccessor));
63 	table->AddColumn(prefix + "check_host_freshness", Column(&Table::OneAccessor, objectAccessor));
64 	table->AddColumn(prefix + "enable_flap_detection", Column(&StatusTable::EnableFlapDetectionAccessor, objectAccessor));
65 	table->AddColumn(prefix + "process_performance_data", Column(&StatusTable::ProcessPerformanceDataAccessor, objectAccessor));
66 	table->AddColumn(prefix + "check_external_commands", Column(&Table::OneAccessor, objectAccessor));
67 	table->AddColumn(prefix + "program_start", Column(&StatusTable::ProgramStartAccessor, objectAccessor));
68 	table->AddColumn(prefix + "last_command_check", Column(&Table::ZeroAccessor, objectAccessor));
69 	table->AddColumn(prefix + "last_log_rotation", Column(&Table::ZeroAccessor, objectAccessor));
70 	table->AddColumn(prefix + "interval_length", Column(&StatusTable::IntervalLengthAccessor, objectAccessor));
71 	table->AddColumn(prefix + "num_hosts", Column(&StatusTable::NumHostsAccessor, objectAccessor));
72 	table->AddColumn(prefix + "num_services", Column(&StatusTable::NumServicesAccessor, objectAccessor));
73 	table->AddColumn(prefix + "program_version", Column(&StatusTable::ProgramVersionAccessor, objectAccessor));
74 	table->AddColumn(prefix + "external_command_buffer_slots", Column(&Table::ZeroAccessor, objectAccessor));
75 	table->AddColumn(prefix + "external_command_buffer_usage", Column(&Table::ZeroAccessor, objectAccessor));
76 	table->AddColumn(prefix + "external_command_buffer_max", Column(&Table::ZeroAccessor, objectAccessor));
77 	table->AddColumn(prefix + "cached_log_messages", Column(&Table::ZeroAccessor, objectAccessor));
78 	table->AddColumn(prefix + "livestatus_version", Column(&StatusTable::LivestatusVersionAccessor, objectAccessor));
79 	table->AddColumn(prefix + "livestatus_active_connections", Column(&Table::ZeroAccessor, objectAccessor));
80 	table->AddColumn(prefix + "livestatus_queued_connections", Column(&Table::ZeroAccessor, objectAccessor));
81 	table->AddColumn(prefix + "livestatus_threads", Column(&Table::ZeroAccessor, objectAccessor));
82 
83 	table->AddColumn(prefix + "custom_variable_names", Column(&StatusTable::CustomVariableNamesAccessor, objectAccessor));
84 	table->AddColumn(prefix + "custom_variable_values", Column(&StatusTable::CustomVariableValuesAccessor, objectAccessor));
85 	table->AddColumn(prefix + "custom_variables", Column(&StatusTable::CustomVariablesAccessor, objectAccessor));
86 }
87 
GetName() const88 String StatusTable::GetName() const
89 {
90 	return "status";
91 }
92 
GetPrefix() const93 String StatusTable::GetPrefix() const
94 {
95 	return "status";
96 }
97 
FetchRows(const AddRowFunction & addRowFn)98 void StatusTable::FetchRows(const AddRowFunction& addRowFn)
99 {
100 	Object::Ptr obj = new Object();
101 
102 	/* Return a fake row. */
103 	addRowFn(obj, LivestatusGroupByNone, Empty);
104 }
105 
ConnectionsAccessor(const Value &)106 Value StatusTable::ConnectionsAccessor(const Value&)
107 {
108 	return LivestatusListener::GetConnections();
109 }
110 
ConnectionsRateAccessor(const Value &)111 Value StatusTable::ConnectionsRateAccessor(const Value&)
112 {
113 	return (LivestatusListener::GetConnections() / (Utility::GetTime() - Application::GetStartTime()));
114 }
115 
HostChecksAccessor(const Value &)116 Value StatusTable::HostChecksAccessor(const Value&)
117 {
118 	auto timespan = static_cast<long>(Utility::GetTime() - Application::GetStartTime());
119 	return CIB::GetActiveHostChecksStatistics(timespan);
120 }
121 
HostChecksRateAccessor(const Value &)122 Value StatusTable::HostChecksRateAccessor(const Value&)
123 {
124 	auto timespan = static_cast<long>(Utility::GetTime() - Application::GetStartTime());
125 	return (CIB::GetActiveHostChecksStatistics(timespan) / (Utility::GetTime() - Application::GetStartTime()));
126 }
127 
ServiceChecksAccessor(const Value &)128 Value StatusTable::ServiceChecksAccessor(const Value&)
129 {
130 	auto timespan = static_cast<long>(Utility::GetTime() - Application::GetStartTime());
131 	return CIB::GetActiveServiceChecksStatistics(timespan);
132 }
133 
ServiceChecksRateAccessor(const Value &)134 Value StatusTable::ServiceChecksRateAccessor(const Value&)
135 {
136 	auto timespan = static_cast<long>(Utility::GetTime() - Application::GetStartTime());
137 	return (CIB::GetActiveServiceChecksStatistics(timespan) / (Utility::GetTime() - Application::GetStartTime()));
138 }
139 
ExternalCommandsAccessor(const Value &)140 Value StatusTable::ExternalCommandsAccessor(const Value&)
141 {
142 	return LivestatusQuery::GetExternalCommands();
143 }
144 
ExternalCommandsRateAccessor(const Value &)145 Value StatusTable::ExternalCommandsRateAccessor(const Value&)
146 {
147 	return (LivestatusQuery::GetExternalCommands() / (Utility::GetTime() - Application::GetStartTime()));
148 }
149 
NagiosPidAccessor(const Value &)150 Value StatusTable::NagiosPidAccessor(const Value&)
151 {
152 	return Utility::GetPid();
153 }
154 
EnableNotificationsAccessor(const Value &)155 Value StatusTable::EnableNotificationsAccessor(const Value&)
156 {
157 	return (IcingaApplication::GetInstance()->GetEnableNotifications() ? 1 : 0);
158 }
159 
ExecuteServiceChecksAccessor(const Value &)160 Value StatusTable::ExecuteServiceChecksAccessor(const Value&)
161 {
162 	return (IcingaApplication::GetInstance()->GetEnableServiceChecks() ? 1 : 0);
163 }
164 
ExecuteHostChecksAccessor(const Value &)165 Value StatusTable::ExecuteHostChecksAccessor(const Value&)
166 {
167 	return (IcingaApplication::GetInstance()->GetEnableHostChecks() ? 1 : 0);
168 }
169 
EnableEventHandlersAccessor(const Value &)170 Value StatusTable::EnableEventHandlersAccessor(const Value&)
171 {
172 	return (IcingaApplication::GetInstance()->GetEnableEventHandlers() ? 1 : 0);
173 }
174 
EnableFlapDetectionAccessor(const Value &)175 Value StatusTable::EnableFlapDetectionAccessor(const Value&)
176 {
177 	return (IcingaApplication::GetInstance()->GetEnableFlapping() ? 1 : 0);
178 }
179 
ProcessPerformanceDataAccessor(const Value &)180 Value StatusTable::ProcessPerformanceDataAccessor(const Value&)
181 {
182 	return (IcingaApplication::GetInstance()->GetEnablePerfdata() ? 1 : 0);
183 }
184 
ProgramStartAccessor(const Value &)185 Value StatusTable::ProgramStartAccessor(const Value&)
186 {
187 	return static_cast<long>(Application::GetStartTime());
188 }
189 
IntervalLengthAccessor(const Value &)190 Value StatusTable::IntervalLengthAccessor(const Value&)
191 {
192 	return LIVESTATUS_INTERVAL_LENGTH;
193 }
194 
NumHostsAccessor(const Value &)195 Value StatusTable::NumHostsAccessor(const Value&)
196 {
197 	return ConfigType::Get<Host>()->GetObjectCount();
198 }
199 
NumServicesAccessor(const Value &)200 Value StatusTable::NumServicesAccessor(const Value&)
201 {
202 	return ConfigType::Get<Service>()->GetObjectCount();
203 }
204 
ProgramVersionAccessor(const Value &)205 Value StatusTable::ProgramVersionAccessor(const Value&)
206 {
207 	return Application::GetAppVersion() + "-icinga2";
208 }
209 
LivestatusVersionAccessor(const Value &)210 Value StatusTable::LivestatusVersionAccessor(const Value&)
211 {
212 	return Application::GetAppVersion();
213 }
214 
LivestatusActiveConnectionsAccessor(const Value &)215 Value StatusTable::LivestatusActiveConnectionsAccessor(const Value&)
216 {
217 	return LivestatusListener::GetClientsConnected();
218 }
219 
CustomVariableNamesAccessor(const Value &)220 Value StatusTable::CustomVariableNamesAccessor(const Value&)
221 {
222 	Dictionary::Ptr vars = IcingaApplication::GetInstance()->GetVars();
223 
224 	ArrayData result;
225 
226 	if (vars) {
227 		ObjectLock olock(vars);
228 		for (const auto& kv : vars) {
229 			result.push_back(kv.first);
230 		}
231 	}
232 
233 	return new Array(std::move(result));
234 }
235 
CustomVariableValuesAccessor(const Value &)236 Value StatusTable::CustomVariableValuesAccessor(const Value&)
237 {
238 	Dictionary::Ptr vars = IcingaApplication::GetInstance()->GetVars();
239 
240 	ArrayData result;
241 
242 	if (vars) {
243 		ObjectLock olock(vars);
244 		for (const auto& kv : vars) {
245 			result.push_back(kv.second);
246 		}
247 	}
248 
249 	return new Array(std::move(result));
250 }
251 
CustomVariablesAccessor(const Value &)252 Value StatusTable::CustomVariablesAccessor(const Value&)
253 {
254 	Dictionary::Ptr vars = IcingaApplication::GetInstance()->GetVars();
255 
256 	ArrayData result;
257 
258 	if (vars) {
259 		ObjectLock olock(vars);
260 		for (const auto& kv : vars) {
261 			result.push_back(new Array({
262 				kv.first,
263 				kv.second
264 			}));
265 		}
266 	}
267 
268 	return new Array(std::move(result));
269 }
270