1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
3 #include "icinga/apievents.hpp"
4 #include "icinga/service.hpp"
5 #include "icinga/notificationcommand.hpp"
6 #include "remote/eventqueue.hpp"
7 #include "base/initialize.hpp"
8 #include "base/serializer.hpp"
9 #include "base/logger.hpp"
11 using namespace icinga;
13 INITIALIZE_ONCE(&ApiEvents::StaticInitialize);
15 void ApiEvents::StaticInitialize()
17 Checkable::OnNewCheckResult.connect(&ApiEvents::CheckResultHandler);
18 Checkable::OnStateChange.connect(&ApiEvents::StateChangeHandler);
19 Checkable::OnNotificationSentToAllUsers.connect(&ApiEvents::NotificationSentToAllUsersHandler);
21 Checkable::OnFlappingChanged.connect(&ApiEvents::FlappingChangedHandler);
23 Checkable::OnAcknowledgementSet.connect(&ApiEvents::AcknowledgementSetHandler);
24 Checkable::OnAcknowledgementCleared.connect(&ApiEvents::AcknowledgementClearedHandler);
26 Comment::OnCommentAdded.connect(&ApiEvents::CommentAddedHandler);
27 Comment::OnCommentRemoved.connect(&ApiEvents::CommentRemovedHandler);
29 Downtime::OnDowntimeAdded.connect(&ApiEvents::DowntimeAddedHandler);
30 Downtime::OnDowntimeRemoved.connect(&ApiEvents::DowntimeRemovedHandler);
31 Downtime::OnDowntimeStarted.connect(&ApiEvents::DowntimeStartedHandler);
32 Downtime::OnDowntimeTriggered.connect(&ApiEvents::DowntimeTriggeredHandler);
35 void ApiEvents::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin)
37 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("CheckResult");
38 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::CheckResult));
40 if (queues.empty() && !inboxes)
43 Log(LogDebug, "ApiEvents", "Processing event type 'CheckResult'.");
45 Dictionary::Ptr result = new Dictionary();
46 result->Set("type", "CheckResult");
47 result->Set("timestamp", Utility::GetTime());
51 tie(host, service) = GetHostService(checkable);
53 result->Set("host", host->GetName());
55 result->Set("service", service->GetShortName());
57 result->Set("check_result", Serialize(cr));
59 for (const EventQueue::Ptr& queue : queues) {
60 queue->ProcessEvent(result);
63 inboxes.Push(std::move(result));
66 void ApiEvents::StateChangeHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, StateType type, const MessageOrigin::Ptr& origin)
68 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("StateChange");
69 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::StateChange));
71 if (queues.empty() && !inboxes)
74 Log(LogDebug, "ApiEvents", "Processing event type 'StateChange'.");
76 Dictionary::Ptr result = new Dictionary();
77 result->Set("type", "StateChange");
78 result->Set("timestamp", Utility::GetTime());
82 tie(host, service) = GetHostService(checkable);
84 result->Set("host", host->GetName());
86 result->Set("service", service->GetShortName());
88 result->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
89 result->Set("state_type", checkable->GetStateType());
90 result->Set("check_result", Serialize(cr));
92 for (const EventQueue::Ptr& queue : queues) {
93 queue->ProcessEvent(result);
96 inboxes.Push(std::move(result));
99 void ApiEvents::NotificationSentToAllUsersHandler(const Notification::Ptr& notification,
100 const Checkable::Ptr& checkable, const std::set<User::Ptr>& users, NotificationType type,
101 const CheckResult::Ptr& cr, const String& author, const String& text, const MessageOrigin::Ptr& origin)
103 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("Notification");
104 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::Notification));
106 if (queues.empty() && !inboxes)
109 Log(LogDebug, "ApiEvents", "Processing event type 'Notification'.");
111 Dictionary::Ptr result = new Dictionary();
112 result->Set("type", "Notification");
113 result->Set("timestamp", Utility::GetTime());
116 Service::Ptr service;
117 tie(host, service) = GetHostService(checkable);
119 result->Set("host", host->GetName());
121 result->Set("service", service->GetShortName());
123 NotificationCommand::Ptr command = notification->GetCommand();
126 result->Set("command", command->GetName());
130 for (const User::Ptr& user : users) {
131 userNames.push_back(user->GetName());
134 result->Set("users", new Array(std::move(userNames)));
135 result->Set("notification_type", Notification::NotificationTypeToString(type));
136 result->Set("author", author);
137 result->Set("text", text);
138 result->Set("check_result", Serialize(cr));
140 for (const EventQueue::Ptr& queue : queues) {
141 queue->ProcessEvent(result);
144 inboxes.Push(std::move(result));
147 void ApiEvents::FlappingChangedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin)
149 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("Flapping");
150 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::Flapping));
152 if (queues.empty() && !inboxes)
155 Log(LogDebug, "ApiEvents", "Processing event type 'Flapping'.");
157 Dictionary::Ptr result = new Dictionary();
158 result->Set("type", "Flapping");
159 result->Set("timestamp", Utility::GetTime());
162 Service::Ptr service;
163 tie(host, service) = GetHostService(checkable);
165 result->Set("host", host->GetName());
167 result->Set("service", service->GetShortName());
169 result->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
170 result->Set("state_type", checkable->GetStateType());
171 result->Set("is_flapping", checkable->IsFlapping());
172 result->Set("flapping_current", checkable->GetFlappingCurrent());
173 result->Set("threshold_low", checkable->GetFlappingThresholdLow());
174 result->Set("threshold_high", checkable->GetFlappingThresholdHigh());
176 for (const EventQueue::Ptr& queue : queues) {
177 queue->ProcessEvent(result);
180 inboxes.Push(std::move(result));
183 void ApiEvents::AcknowledgementSetHandler(const Checkable::Ptr& checkable,
184 const String& author, const String& comment, AcknowledgementType type,
185 bool notify, bool persistent, double expiry, const MessageOrigin::Ptr& origin)
187 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("AcknowledgementSet");
188 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::AcknowledgementSet));
190 if (queues.empty() && !inboxes)
193 Log(LogDebug, "ApiEvents", "Processing event type 'AcknowledgementSet'.");
195 Dictionary::Ptr result = new Dictionary();
196 result->Set("type", "AcknowledgementSet");
197 result->Set("timestamp", Utility::GetTime());
200 Service::Ptr service;
201 tie(host, service) = GetHostService(checkable);
203 result->Set("host", host->GetName());
205 result->Set("service", service->GetShortName());
207 result->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
208 result->Set("state_type", checkable->GetStateType());
210 result->Set("author", author);
211 result->Set("comment", comment);
212 result->Set("acknowledgement_type", type);
213 result->Set("notify", notify);
214 result->Set("persistent", persistent);
215 result->Set("expiry", expiry);
217 for (const EventQueue::Ptr& queue : queues) {
218 queue->ProcessEvent(result);
221 inboxes.Push(std::move(result));
224 void ApiEvents::AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin)
226 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("AcknowledgementCleared");
227 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::AcknowledgementCleared));
229 if (queues.empty() && !inboxes)
232 Log(LogDebug, "ApiEvents", "Processing event type 'AcknowledgementCleared'.");
234 Dictionary::Ptr result = new Dictionary();
235 result->Set("type", "AcknowledgementCleared");
236 result->Set("timestamp", Utility::GetTime());
239 Service::Ptr service;
240 tie(host, service) = GetHostService(checkable);
242 result->Set("host", host->GetName());
244 result->Set("service", service->GetShortName());
246 result->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
247 result->Set("state_type", checkable->GetStateType());
249 for (const EventQueue::Ptr& queue : queues) {
250 queue->ProcessEvent(result);
253 result->Set("acknowledgement_type", AcknowledgementNone);
255 inboxes.Push(std::move(result));
258 void ApiEvents::CommentAddedHandler(const Comment::Ptr& comment)
260 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("CommentAdded");
261 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::CommentAdded));
263 if (queues.empty() && !inboxes)
266 Log(LogDebug, "ApiEvents", "Processing event type 'CommentAdded'.");
268 Dictionary::Ptr result = new Dictionary({
269 { "type", "CommentAdded" },
270 { "timestamp", Utility::GetTime() },
271 { "comment", Serialize(comment, FAConfig | FAState) }
274 for (const EventQueue::Ptr& queue : queues) {
275 queue->ProcessEvent(result);
278 inboxes.Push(std::move(result));
281 void ApiEvents::CommentRemovedHandler(const Comment::Ptr& comment)
283 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("CommentRemoved");
284 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::CommentRemoved));
286 if (queues.empty() && !inboxes)
289 Log(LogDebug, "ApiEvents", "Processing event type 'CommentRemoved'.");
291 Dictionary::Ptr result = new Dictionary({
292 { "type", "CommentRemoved" },
293 { "timestamp", Utility::GetTime() },
294 { "comment", Serialize(comment, FAConfig | FAState) }
297 for (const EventQueue::Ptr& queue : queues) {
298 queue->ProcessEvent(result);
301 inboxes.Push(std::move(result));
304 void ApiEvents::DowntimeAddedHandler(const Downtime::Ptr& downtime)
306 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeAdded");
307 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::DowntimeAdded));
309 if (queues.empty() && !inboxes)
312 Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeAdded'.");
314 Dictionary::Ptr result = new Dictionary({
315 { "type", "DowntimeAdded" },
316 { "timestamp", Utility::GetTime() },
317 { "downtime", Serialize(downtime, FAConfig | FAState) }
320 for (const EventQueue::Ptr& queue : queues) {
321 queue->ProcessEvent(result);
324 inboxes.Push(std::move(result));
327 void ApiEvents::DowntimeRemovedHandler(const Downtime::Ptr& downtime)
329 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeRemoved");
330 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::DowntimeRemoved));
332 if (queues.empty() && !inboxes)
335 Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeRemoved'.");
337 Dictionary::Ptr result = new Dictionary({
338 { "type", "DowntimeRemoved" },
339 { "timestamp", Utility::GetTime() },
340 { "downtime", Serialize(downtime, FAConfig | FAState) }
343 for (const EventQueue::Ptr& queue : queues) {
344 queue->ProcessEvent(result);
347 inboxes.Push(std::move(result));
350 void ApiEvents::DowntimeStartedHandler(const Downtime::Ptr& downtime)
352 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeStarted");
353 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::DowntimeStarted));
355 if (queues.empty() && !inboxes)
358 Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeStarted'.");
360 Dictionary::Ptr result = new Dictionary({
361 { "type", "DowntimeStarted" },
362 { "timestamp", Utility::GetTime() },
363 { "downtime", Serialize(downtime, FAConfig | FAState) }
366 for (const EventQueue::Ptr& queue : queues) {
367 queue->ProcessEvent(result);
370 inboxes.Push(std::move(result));
373 void ApiEvents::DowntimeTriggeredHandler(const Downtime::Ptr& downtime)
375 std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeTriggered");
376 auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::DowntimeTriggered));
378 if (queues.empty() && !inboxes)
381 Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeTriggered'.");
383 Dictionary::Ptr result = new Dictionary({
384 { "type", "DowntimeTriggered" },
385 { "timestamp", Utility::GetTime() },
386 { "downtime", Serialize(downtime, FAConfig | FAState) }
389 for (const EventQueue::Ptr& queue : queues) {
390 queue->ProcessEvent(result);
393 inboxes.Push(std::move(result));