1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
3 #include "db_ido/dbevents.hpp"
4 #include "db_ido/dbtype.hpp"
5 #include "db_ido/dbvalue.hpp"
6 #include "base/convert.hpp"
7 #include "base/objectlock.hpp"
8 #include "base/initialize.hpp"
9 #include "base/configtype.hpp"
10 #include "base/utility.hpp"
11 #include "base/logger.hpp"
12 #include "remote/endpoint.hpp"
13 #include "icinga/notification.hpp"
14 #include "icinga/checkcommand.hpp"
15 #include "icinga/eventcommand.hpp"
16 #include "icinga/externalcommandprocessor.hpp"
17 #include "icinga/compatutility.hpp"
18 #include "icinga/pluginutility.hpp"
19 #include "icinga/icingaapplication.hpp"
20 #include <boost/algorithm/string/join.hpp>
22 using namespace icinga;
24 INITIALIZE_ONCE(&DbEvents::StaticInitialize);
26 void DbEvents::StaticInitialize()
29 Comment::OnCommentAdded.connect(std::bind(&DbEvents::AddComment, _1));
30 Comment::OnCommentRemoved.connect(std::bind(&DbEvents::RemoveComment, _1));
31 Downtime::OnDowntimeAdded.connect(std::bind(&DbEvents::AddDowntime, _1));
32 Downtime::OnDowntimeRemoved.connect(std::bind(&DbEvents::RemoveDowntime, _1));
33 Downtime::OnDowntimeTriggered.connect(std::bind(&DbEvents::TriggerDowntime, _1));
34 Checkable::OnAcknowledgementSet.connect(std::bind(&DbEvents::AddAcknowledgement, _1, _4));
35 Checkable::OnAcknowledgementCleared.connect(std::bind(&DbEvents::RemoveAcknowledgement, _1));
37 Checkable::OnNextCheckUpdated.connect(std::bind(&DbEvents::NextCheckUpdatedHandler, _1));
38 Checkable::OnFlappingChanged.connect(std::bind(&DbEvents::FlappingChangedHandler, _1));
39 Checkable::OnNotificationSentToAllUsers.connect(std::bind(&DbEvents::LastNotificationChangedHandler, _1, _2));
41 Checkable::OnEnableActiveChecksChanged.connect(std::bind(&DbEvents::EnableActiveChecksChangedHandler, _1));
42 Checkable::OnEnablePassiveChecksChanged.connect(std::bind(&DbEvents::EnablePassiveChecksChangedHandler, _1));
43 Checkable::OnEnableNotificationsChanged.connect(std::bind(&DbEvents::EnableNotificationsChangedHandler, _1));
44 Checkable::OnEnablePerfdataChanged.connect(std::bind(&DbEvents::EnablePerfdataChangedHandler, _1));
45 Checkable::OnEnableFlappingChanged.connect(std::bind(&DbEvents::EnableFlappingChangedHandler, _1));
47 Checkable::OnReachabilityChanged.connect(std::bind(&DbEvents::ReachabilityChangedHandler, _1, _2, _3));
50 Comment::OnCommentAdded.connect(std::bind(&DbEvents::AddCommentHistory, _1));
51 Downtime::OnDowntimeAdded.connect(std::bind(&DbEvents::AddDowntimeHistory, _1));
52 Checkable::OnAcknowledgementSet.connect(std::bind(&DbEvents::AddAcknowledgementHistory, _1, _2, _3, _4, _5, _6));
54 Checkable::OnNotificationSentToAllUsers.connect(std::bind(&DbEvents::AddNotificationHistory, _1, _2, _3, _4, _5, _6, _7));
56 Checkable::OnStateChange.connect(std::bind(&DbEvents::AddStateChangeHistory, _1, _2, _3));
58 Checkable::OnNewCheckResult.connect(std::bind(&DbEvents::AddCheckResultLogHistory, _1, _2));
59 Checkable::OnNotificationSentToUser.connect(std::bind(&DbEvents::AddNotificationSentLogHistory, _1, _2, _3, _4, _5, _6, _7, _8));
60 Checkable::OnFlappingChanged.connect(std::bind(&DbEvents::AddFlappingChangedLogHistory, _1));
61 Checkable::OnEnableFlappingChanged.connect(std::bind(&DbEvents::AddEnableFlappingChangedLogHistory, _1));
62 Downtime::OnDowntimeTriggered.connect(std::bind(&DbEvents::AddTriggerDowntimeLogHistory, _1));
63 Downtime::OnDowntimeRemoved.connect(std::bind(&DbEvents::AddRemoveDowntimeLogHistory, _1));
65 Checkable::OnFlappingChanged.connect(std::bind(&DbEvents::AddFlappingChangedHistory, _1));
66 Checkable::OnEnableFlappingChanged.connect(std::bind(&DbEvents::AddEnableFlappingChangedHistory, _1));
67 Checkable::OnNewCheckResult.connect(std::bind(&DbEvents::AddCheckableCheckHistory, _1, _2));
69 Checkable::OnEventCommandExecuted.connect(std::bind(&DbEvents::AddEventHandlerHistory, _1));
71 ExternalCommandProcessor::OnNewExternalCommand.connect(std::bind(&DbEvents::AddExternalCommandHistory, _1, _2, _3));
75 void DbEvents::NextCheckUpdatedHandler(const Checkable::Ptr& checkable)
79 tie(host, service) = GetHostService(checkable);
82 query1.WhereCriteria = new Dictionary();
85 query1.Table = "servicestatus";
86 query1.WhereCriteria->Set("service_object_id", service);
88 query1.Table = "hoststatus";
89 query1.WhereCriteria->Set("host_object_id", host);
92 query1.Type = DbQueryUpdate;
93 query1.Category = DbCatState;
94 query1.StatusUpdate = true;
95 query1.Object = DbObject::GetOrCreateByObject(checkable);
97 query1.Fields = new Dictionary({
98 { "next_check", DbValue::FromTimestamp(checkable->GetNextCheck()) }
101 DbObject::OnQuery(query1);
104 void DbEvents::FlappingChangedHandler(const Checkable::Ptr& checkable)
107 Service::Ptr service;
108 tie(host, service) = GetHostService(checkable);
111 query1.WhereCriteria = new Dictionary();
114 query1.Table = "servicestatus";
115 query1.WhereCriteria->Set("service_object_id", service);
117 query1.Table = "hoststatus";
118 query1.WhereCriteria->Set("host_object_id", host);
121 query1.Type = DbQueryUpdate;
122 query1.Category = DbCatState;
123 query1.StatusUpdate = true;
124 query1.Object = DbObject::GetOrCreateByObject(checkable);
126 Dictionary::Ptr fields1 = new Dictionary();
127 fields1->Set("is_flapping", checkable->IsFlapping());
128 fields1->Set("percent_state_change", checkable->GetFlappingCurrent());
130 query1.Fields = new Dictionary({
131 { "is_flapping", checkable->IsFlapping() },
132 { "percent_state_change", checkable->GetFlappingCurrent() }
135 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
137 DbObject::OnQuery(query1);
140 void DbEvents::LastNotificationChangedHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable)
142 std::pair<unsigned long, unsigned long> now_bag = ConvertTimestamp(Utility::GetTime());
143 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(notification->GetNextNotification());
146 Service::Ptr service;
147 tie(host, service) = GetHostService(checkable);
150 query1.WhereCriteria = new Dictionary();
153 query1.Table = "servicestatus";
154 query1.WhereCriteria->Set("service_object_id", service);
156 query1.Table = "hoststatus";
157 query1.WhereCriteria->Set("host_object_id", host);
160 query1.Type = DbQueryUpdate;
161 query1.Category = DbCatState;
162 query1.StatusUpdate = true;
163 query1.Object = DbObject::GetOrCreateByObject(checkable);
165 query1.Fields = new Dictionary({
166 { "last_notification", DbValue::FromTimestamp(now_bag.first) },
167 { "next_notification", DbValue::FromTimestamp(timeBag.first) },
168 { "current_notification_number", notification->GetNotificationNumber() }
171 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
173 DbObject::OnQuery(query1);
176 void DbEvents::ReachabilityChangedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, std::set<Checkable::Ptr> children)
178 int is_reachable = 0;
180 if (cr->GetState() == ServiceOK)
183 for (const Checkable::Ptr& child : children) {
185 Service::Ptr service;
186 tie(host, service) = GetHostService(child);
189 query1.WhereCriteria = new Dictionary();
192 query1.Table = "servicestatus";
193 query1.WhereCriteria->Set("service_object_id", service);
195 query1.Table = "hoststatus";
196 query1.WhereCriteria->Set("host_object_id", host);
199 query1.Type = DbQueryUpdate;
200 query1.Category = DbCatState;
201 query1.StatusUpdate = true;
202 query1.Object = DbObject::GetOrCreateByObject(child);
204 query1.Fields = new Dictionary({
205 { "is_reachable", is_reachable }
208 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
210 DbObject::OnQuery(query1);
214 /* enable changed events */
215 void DbEvents::EnableActiveChecksChangedHandler(const Checkable::Ptr& checkable)
217 EnableChangedHandlerInternal(checkable, "active_checks_enabled", checkable->GetEnableActiveChecks());
220 void DbEvents::EnablePassiveChecksChangedHandler(const Checkable::Ptr& checkable)
222 EnableChangedHandlerInternal(checkable, "passive_checks_enabled", checkable->GetEnablePassiveChecks());
225 void DbEvents::EnableNotificationsChangedHandler(const Checkable::Ptr& checkable)
227 EnableChangedHandlerInternal(checkable, "notifications_enabled", checkable->GetEnableNotifications());
230 void DbEvents::EnablePerfdataChangedHandler(const Checkable::Ptr& checkable)
232 EnableChangedHandlerInternal(checkable, "process_performance_data", checkable->GetEnablePerfdata());
235 void DbEvents::EnableFlappingChangedHandler(const Checkable::Ptr& checkable)
237 EnableChangedHandlerInternal(checkable, "flap_detection_enabled", checkable->GetEnableFlapping());
240 void DbEvents::EnableChangedHandlerInternal(const Checkable::Ptr& checkable, const String& fieldName, bool enabled)
243 Service::Ptr service;
244 tie(host, service) = GetHostService(checkable);
247 query1.WhereCriteria = new Dictionary();
250 query1.Table = "servicestatus";
251 query1.WhereCriteria->Set("service_object_id", service);
253 query1.Table = "hoststatus";
254 query1.WhereCriteria->Set("host_object_id", host);
257 query1.Type = DbQueryUpdate;
258 query1.Category = DbCatState;
259 query1.StatusUpdate = true;
260 query1.Object = DbObject::GetOrCreateByObject(checkable);
262 query1.Fields = new Dictionary({
263 { fieldName, enabled }
266 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
268 DbObject::OnQuery(query1);
273 void DbEvents::AddComments(const Checkable::Ptr& checkable)
275 std::set<Comment::Ptr> comments = checkable->GetComments();
277 std::vector<DbQuery> queries;
279 for (const Comment::Ptr& comment : comments) {
280 AddCommentInternal(queries, comment, false);
283 DbObject::OnMultipleQueries(queries);
286 void DbEvents::AddComment(const Comment::Ptr& comment)
288 std::vector<DbQuery> queries;
289 AddCommentInternal(queries, comment, false);
290 DbObject::OnMultipleQueries(queries);
293 void DbEvents::AddCommentHistory(const Comment::Ptr& comment)
295 std::vector<DbQuery> queries;
296 AddCommentInternal(queries, comment, true);
297 DbObject::OnMultipleQueries(queries);
300 void DbEvents::AddCommentInternal(std::vector<DbQuery>& queries, const Comment::Ptr& comment, bool historical)
302 Checkable::Ptr checkable = comment->GetCheckable();
304 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(comment->GetEntryTime());
306 Dictionary::Ptr fields1 = new Dictionary();
307 fields1->Set("entry_time", DbValue::FromTimestamp(timeBag.first));
308 fields1->Set("entry_time_usec", timeBag.second);
309 fields1->Set("entry_type", comment->GetEntryType());
310 fields1->Set("object_id", checkable);
314 if (checkable->GetReflectionType() == Host::TypeInstance)
316 else if (checkable->GetReflectionType() == Service::TypeInstance)
322 fields1->Set("comment_type", commentType);
323 fields1->Set("internal_comment_id", comment->GetLegacyId());
324 fields1->Set("name", comment->GetName());
325 fields1->Set("comment_time", DbValue::FromTimestamp(timeBag.first)); /* same as entry_time */
326 fields1->Set("author_name", comment->GetAuthor());
327 fields1->Set("comment_data", comment->GetText());
328 fields1->Set("is_persistent", comment->GetPersistent());
329 fields1->Set("comment_source", 1); /* external */
330 fields1->Set("expires", (comment->GetExpireTime() > 0));
331 fields1->Set("expiration_time", DbValue::FromTimestamp(comment->GetExpireTime()));
332 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
334 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
337 fields1->Set("endpoint_object_id", endpoint);
342 query1.Table = "comments";
343 query1.Type = DbQueryInsert | DbQueryUpdate;
345 fields1->Set("session_token", 0); /* DbConnection class fills in real ID */
347 query1.WhereCriteria = new Dictionary({
348 { "object_id", checkable },
349 { "name", comment->GetName() },
350 { "entry_time", DbValue::FromTimestamp(timeBag.first) }
353 query1.Table = "commenthistory";
354 query1.Type = DbQueryInsert;
357 query1.Category = DbCatComment;
358 query1.Fields = fields1;
359 queries.emplace_back(std::move(query1));
362 void DbEvents::RemoveComment(const Comment::Ptr& comment)
364 std::vector<DbQuery> queries;
365 RemoveCommentInternal(queries, comment);
366 DbObject::OnMultipleQueries(queries);
369 void DbEvents::RemoveCommentInternal(std::vector<DbQuery>& queries, const Comment::Ptr& comment)
371 Checkable::Ptr checkable = comment->GetCheckable();
373 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(comment->GetEntryTime());
377 query1.Table = "comments";
378 query1.Type = DbQueryDelete;
379 query1.Category = DbCatComment;
381 query1.WhereCriteria = new Dictionary({
382 { "object_id", checkable },
383 { "entry_time", DbValue::FromTimestamp(timeBag.first) },
384 { "name", comment->GetName() }
387 queries.emplace_back(std::move(query1));
389 /* History - update deletion time for service/host */
390 std::pair<unsigned long, unsigned long> timeBagNow = ConvertTimestamp(Utility::GetTime());
393 query2.Table = "commenthistory";
394 query2.Type = DbQueryUpdate;
395 query2.Category = DbCatComment;
397 query2.Fields = new Dictionary({
398 { "deletion_time", DbValue::FromTimestamp(timeBagNow.first) },
399 { "deletion_time_usec", timeBagNow.second }
402 query2.WhereCriteria = new Dictionary({
403 { "object_id", checkable },
404 { "entry_time", DbValue::FromTimestamp(timeBag.first) },
405 { "name", comment->GetName() }
408 queries.emplace_back(std::move(query2));
412 void DbEvents::AddDowntimes(const Checkable::Ptr& checkable)
414 std::set<Downtime::Ptr> downtimes = checkable->GetDowntimes();
416 std::vector<DbQuery> queries;
418 for (const Downtime::Ptr& downtime : downtimes) {
419 AddDowntimeInternal(queries, downtime, false);
422 DbObject::OnMultipleQueries(queries);
425 void DbEvents::AddDowntime(const Downtime::Ptr& downtime)
427 std::vector<DbQuery> queries;
428 AddDowntimeInternal(queries, downtime, false);
429 DbObject::OnMultipleQueries(queries);
432 void DbEvents::AddDowntimeHistory(const Downtime::Ptr& downtime)
434 std::vector<DbQuery> queries;
435 AddDowntimeInternal(queries, downtime, true);
436 DbObject::OnMultipleQueries(queries);
439 void DbEvents::AddDowntimeInternal(std::vector<DbQuery>& queries, const Downtime::Ptr& downtime, bool historical)
441 Checkable::Ptr checkable = downtime->GetCheckable();
443 Dictionary::Ptr fields1 = new Dictionary();
444 fields1->Set("entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()));
445 fields1->Set("object_id", checkable);
447 int downtimeType = 0;
449 if (checkable->GetReflectionType() == Host::TypeInstance)
451 else if (checkable->GetReflectionType() == Service::TypeInstance)
457 fields1->Set("downtime_type", downtimeType);
458 fields1->Set("internal_downtime_id", downtime->GetLegacyId());
459 fields1->Set("author_name", downtime->GetAuthor());
460 fields1->Set("comment_data", downtime->GetComment());
461 fields1->Set("triggered_by_id", Downtime::GetByName(downtime->GetTriggeredBy()));
462 fields1->Set("is_fixed", downtime->GetFixed());
463 fields1->Set("duration", downtime->GetDuration());
464 fields1->Set("scheduled_start_time", DbValue::FromTimestamp(downtime->GetStartTime()));
465 fields1->Set("scheduled_end_time", DbValue::FromTimestamp(downtime->GetEndTime()));
466 fields1->Set("name", downtime->GetName());
468 /* flexible downtimes are started at trigger time */
469 if (downtime->GetFixed()) {
470 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(downtime->GetStartTime());
472 fields1->Set("actual_start_time", DbValue::FromTimestamp(timeBag.first));
473 fields1->Set("actual_start_time_usec", timeBag.second);
474 fields1->Set("was_started", ((downtime->GetStartTime() <= Utility::GetTime()) ? 1 : 0));
477 fields1->Set("is_in_effect", downtime->IsInEffect());
478 fields1->Set("trigger_time", DbValue::FromTimestamp(downtime->GetTriggerTime()));
479 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
481 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
484 fields1->Set("endpoint_object_id", endpoint);
489 query1.Table = "scheduleddowntime";
490 query1.Type = DbQueryInsert | DbQueryUpdate;
492 fields1->Set("session_token", 0); /* DbConnection class fills in real ID */
494 query1.WhereCriteria = new Dictionary({
495 { "object_id", checkable },
496 { "name", downtime->GetName() },
497 { "entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()) }
500 query1.Table = "downtimehistory";
501 query1.Type = DbQueryInsert;
504 query1.Category = DbCatDowntime;
505 query1.Fields = fields1;
506 queries.emplace_back(std::move(query1));
508 /* host/service status */
511 Service::Ptr service;
512 tie(host, service) = GetHostService(checkable);
515 query2.WhereCriteria = new Dictionary();
518 query2.Table = "servicestatus";
519 query2.WhereCriteria->Set("service_object_id", service);
521 query2.Table = "hoststatus";
522 query2.WhereCriteria->Set("host_object_id", host);
525 query2.Type = DbQueryUpdate;
526 query2.Category = DbCatState;
527 query2.StatusUpdate = true;
528 query2.Object = DbObject::GetOrCreateByObject(checkable);
530 Dictionary::Ptr fields2 = new Dictionary();
531 fields2->Set("scheduled_downtime_depth", checkable->GetDowntimeDepth());
533 query2.Fields = fields2;
534 query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
536 queries.emplace_back(std::move(query2));
540 void DbEvents::RemoveDowntime(const Downtime::Ptr& downtime)
542 std::vector<DbQuery> queries;
543 RemoveDowntimeInternal(queries, downtime);
544 DbObject::OnMultipleQueries(queries);
547 void DbEvents::RemoveDowntimeInternal(std::vector<DbQuery>& queries, const Downtime::Ptr& downtime)
549 Checkable::Ptr checkable = downtime->GetCheckable();
553 query1.Table = "scheduleddowntime";
554 query1.Type = DbQueryDelete;
555 query1.Category = DbCatDowntime;
556 query1.WhereCriteria = new Dictionary();
558 query1.WhereCriteria->Set("object_id", checkable);
559 query1.WhereCriteria->Set("entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()));
560 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
561 query1.WhereCriteria->Set("scheduled_start_time", DbValue::FromTimestamp(downtime->GetStartTime()));
562 query1.WhereCriteria->Set("scheduled_end_time", DbValue::FromTimestamp(downtime->GetEndTime()));
563 query1.WhereCriteria->Set("name", downtime->GetName());
564 queries.emplace_back(std::move(query1));
566 /* History - update actual_end_time, was_cancelled for service (and host in case) */
567 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
570 query3.Table = "downtimehistory";
571 query3.Type = DbQueryUpdate;
572 query3.Category = DbCatDowntime;
574 Dictionary::Ptr fields3 = new Dictionary();
575 fields3->Set("was_cancelled", downtime->GetWasCancelled() ? 1 : 0);
577 if (downtime->GetFixed() || (!downtime->GetFixed() && downtime->GetTriggerTime() > 0)) {
578 fields3->Set("actual_end_time", DbValue::FromTimestamp(timeBag.first));
579 fields3->Set("actual_end_time_usec", timeBag.second);
582 fields3->Set("is_in_effect", 0);
583 query3.Fields = fields3;
585 query3.WhereCriteria = new Dictionary({
586 { "object_id", checkable },
587 { "entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()) },
588 { "instance_id", 0 }, /* DbConnection class fills in real ID */
589 { "scheduled_start_time", DbValue::FromTimestamp(downtime->GetStartTime()) },
590 { "scheduled_end_time", DbValue::FromTimestamp(downtime->GetEndTime()) },
591 { "name", downtime->GetName() }
594 queries.emplace_back(std::move(query3));
596 /* host/service status */
598 Service::Ptr service;
599 tie(host, service) = GetHostService(checkable);
602 query4.WhereCriteria = new Dictionary();
605 query4.Table = "servicestatus";
606 query4.WhereCriteria->Set("service_object_id", service);
608 query4.Table = "hoststatus";
609 query4.WhereCriteria->Set("host_object_id", host);
612 query4.Type = DbQueryUpdate;
613 query4.Category = DbCatState;
614 query4.StatusUpdate = true;
615 query4.Object = DbObject::GetOrCreateByObject(checkable);
617 Dictionary::Ptr fields4 = new Dictionary();
618 fields4->Set("scheduled_downtime_depth", checkable->GetDowntimeDepth());
620 query4.Fields = fields4;
621 query4.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
623 queries.emplace_back(std::move(query4));
626 void DbEvents::TriggerDowntime(const Downtime::Ptr& downtime)
628 Checkable::Ptr checkable = downtime->GetCheckable();
630 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
634 query1.Table = "scheduleddowntime";
635 query1.Type = DbQueryUpdate;
636 query1.Category = DbCatDowntime;
638 query1.Fields = new Dictionary({
639 { "was_started", 1 },
640 { "actual_start_time", DbValue::FromTimestamp(timeBag.first) },
641 { "actual_start_time_usec", timeBag.second },
642 { "is_in_effect", (downtime->IsInEffect() ? 1 : 0) },
643 { "trigger_time", DbValue::FromTimestamp(downtime->GetTriggerTime()) },
644 { "instance_id", 0 } /* DbConnection class fills in real ID */
647 query1.WhereCriteria = new Dictionary({
648 { "object_id", checkable },
649 { "entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()) },
650 { "instance_id", 0 }, /* DbConnection class fills in real ID */
651 { "scheduled_start_time", DbValue::FromTimestamp(downtime->GetStartTime()) },
652 { "scheduled_end_time", DbValue::FromTimestamp(downtime->GetEndTime()) },
653 { "name", downtime->GetName() }
656 DbObject::OnQuery(query1);
658 /* History - downtime was started for service (and host in case) */
660 query3.Table = "downtimehistory";
661 query3.Type = DbQueryUpdate;
662 query3.Category = DbCatDowntime;
664 query3.Fields = new Dictionary({
665 { "was_started", 1 },
666 { "is_in_effect", 1 },
667 { "actual_start_time", DbValue::FromTimestamp(timeBag.first) },
668 { "actual_start_time_usec", timeBag.second },
669 { "trigger_time", DbValue::FromTimestamp(downtime->GetTriggerTime()) }
672 query3.WhereCriteria = query1.WhereCriteria;
674 DbObject::OnQuery(query3);
676 /* host/service status */
678 Service::Ptr service;
679 tie(host, service) = GetHostService(checkable);
682 query4.WhereCriteria = new Dictionary();
685 query4.Table = "servicestatus";
686 query4.WhereCriteria->Set("service_object_id", service);
688 query4.Table = "hoststatus";
689 query4.WhereCriteria->Set("host_object_id", host);
692 query4.Type = DbQueryUpdate;
693 query4.Category = DbCatState;
694 query4.StatusUpdate = true;
695 query4.Object = DbObject::GetOrCreateByObject(checkable);
697 query4.Fields = new Dictionary({
698 { "scheduled_downtime_depth", checkable->GetDowntimeDepth() }
700 query4.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
702 DbObject::OnQuery(query4);
705 /* acknowledgements */
706 void DbEvents::AddAcknowledgementHistory(const Checkable::Ptr& checkable, const String& author, const String& comment,
707 AcknowledgementType type, bool notify, double expiry)
709 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
712 query1.Table = "acknowledgements";
713 query1.Type = DbQueryInsert;
714 query1.Category = DbCatAcknowledgement;
717 Service::Ptr service;
718 tie(host, service) = GetHostService(checkable);
720 Dictionary::Ptr fields1 = new Dictionary();
722 fields1->Set("entry_time", DbValue::FromTimestamp(timeBag.first));
723 fields1->Set("entry_time_usec", timeBag.second);
724 fields1->Set("acknowledgement_type", type);
725 fields1->Set("object_id", checkable);
726 fields1->Set("author_name", author);
727 fields1->Set("comment_data", comment);
728 fields1->Set("persistent_comment", 1);
729 fields1->Set("notify_contacts", notify);
730 fields1->Set("is_sticky", type == AcknowledgementSticky);
731 fields1->Set("end_time", DbValue::FromTimestamp(expiry));
732 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
735 fields1->Set("state", service->GetState());
737 fields1->Set("state", GetHostState(host));
739 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
742 fields1->Set("endpoint_object_id", endpoint);
744 query1.Fields = fields1;
745 DbObject::OnQuery(query1);
748 void DbEvents::AddAcknowledgement(const Checkable::Ptr& checkable, AcknowledgementType type)
750 AddAcknowledgementInternal(checkable, type, true);
753 void DbEvents::RemoveAcknowledgement(const Checkable::Ptr& checkable)
755 AddAcknowledgementInternal(checkable, AcknowledgementNone, false);
758 void DbEvents::AddAcknowledgementInternal(const Checkable::Ptr& checkable, AcknowledgementType type, bool add)
761 Service::Ptr service;
762 tie(host, service) = GetHostService(checkable);
765 query1.WhereCriteria = new Dictionary();
768 query1.Table = "servicestatus";
769 query1.WhereCriteria->Set("service_object_id", service);
771 query1.Table = "hoststatus";
772 query1.WhereCriteria->Set("host_object_id", host);
775 query1.Type = DbQueryUpdate;
776 query1.Category = DbCatState;
777 query1.StatusUpdate = true;
778 query1.Object = DbObject::GetOrCreateByObject(checkable);
780 query1.Fields = new Dictionary({
781 { "acknowledgement_type", type },
782 { "problem_has_been_acknowledged", add ? 1 : 0 }
785 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
787 DbObject::OnQuery(query1);
791 void DbEvents::AddNotificationHistory(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users, NotificationType type,
792 const CheckResult::Ptr& cr, const String& author, const String& text)
794 /* start and end happen at the same time */
795 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
798 query1.Table = "notifications";
799 query1.Type = DbQueryInsert;
800 query1.Category = DbCatNotification;
801 query1.NotificationInsertID = new DbValue(DbValueObjectInsertID, -1);
804 Service::Ptr service;
805 tie(host, service) = GetHostService(checkable);
807 Dictionary::Ptr fields1 = new Dictionary();
808 fields1->Set("notification_type", 1); /* service */
809 fields1->Set("notification_reason", MapNotificationReasonType(type));
810 fields1->Set("object_id", checkable);
811 fields1->Set("start_time", DbValue::FromTimestamp(timeBag.first));
812 fields1->Set("start_time_usec", timeBag.second);
813 fields1->Set("end_time", DbValue::FromTimestamp(timeBag.first));
814 fields1->Set("end_time_usec", timeBag.second);
817 fields1->Set("state", service->GetState());
819 fields1->Set("state", GetHostState(host));
822 fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
823 fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
826 fields1->Set("escalated", 0);
827 fields1->Set("contacts_notified", static_cast<long>(users.size()));
828 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
830 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
833 fields1->Set("endpoint_object_id", endpoint);
835 query1.Fields = fields1;
836 DbObject::OnQuery(query1);
838 std::vector<DbQuery> queries;
840 for (const User::Ptr& user : users) {
842 query2.Table = "contactnotifications";
843 query2.Type = DbQueryInsert;
844 query2.Category = DbCatNotification;
846 query2.Fields = new Dictionary({
847 { "contact_object_id", user },
848 { "start_time", DbValue::FromTimestamp(timeBag.first) },
849 { "start_time_usec", timeBag.second },
850 { "end_time", DbValue::FromTimestamp(timeBag.first) },
851 { "end_time_usec", timeBag.second },
852 { "notification_id", query1.NotificationInsertID },
853 { "instance_id", 0 } /* DbConnection class fills in real ID */
856 queries.emplace_back(std::move(query2));
859 DbObject::OnMultipleQueries(queries);
863 void DbEvents::AddStateChangeHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, StateType type)
865 double ts = cr->GetExecutionEnd();
866 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(ts);
869 query1.Table = "statehistory";
870 query1.Type = DbQueryInsert;
871 query1.Category = DbCatStateHistory;
874 Service::Ptr service;
875 tie(host, service) = GetHostService(checkable);
877 Dictionary::Ptr fields1 = new Dictionary();
878 fields1->Set("state_time", DbValue::FromTimestamp(timeBag.first));
879 fields1->Set("state_time_usec", timeBag.second);
880 fields1->Set("object_id", checkable);
881 fields1->Set("state_change", 1); /* service */
882 fields1->Set("state_type", checkable->GetStateType());
883 fields1->Set("current_check_attempt", checkable->GetCheckAttempt());
884 fields1->Set("max_check_attempts", checkable->GetMaxCheckAttempts());
887 fields1->Set("state", service->GetState());
888 fields1->Set("last_state", service->GetLastState());
889 fields1->Set("last_hard_state", service->GetLastHardState());
891 fields1->Set("state", GetHostState(host));
892 fields1->Set("last_state", host->GetLastState());
893 fields1->Set("last_hard_state", host->GetLastHardState());
897 fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
898 fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
899 fields1->Set("check_source", cr->GetCheckSource());
902 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
904 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
907 fields1->Set("endpoint_object_id", endpoint);
909 query1.Fields = fields1;
910 DbObject::OnQuery(query1);
914 void DbEvents::AddCheckResultLogHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr &cr)
919 Dictionary::Ptr varsBefore = cr->GetVarsBefore();
920 Dictionary::Ptr varsAfter = cr->GetVarsAfter();
922 if (varsBefore && varsAfter) {
923 if (varsBefore->Get("state") == varsAfter->Get("state") &&
924 varsBefore->Get("state_type") == varsAfter->Get("state_type") &&
925 varsBefore->Get("attempt") == varsAfter->Get("attempt") &&
926 varsBefore->Get("reachable") == varsAfter->Get("reachable"))
927 return; /* Nothing changed, ignore this checkresult. */
931 String output = CompatUtility::GetCheckResultOutput(cr);
934 Service::Ptr service;
935 tie(host, service) = GetHostService(checkable);
937 std::ostringstream msgbuf;
940 msgbuf << "SERVICE ALERT: "
941 << host->GetName() << ";"
942 << service->GetShortName() << ";"
943 << Service::StateToString(service->GetState()) << ";"
944 << Service::StateTypeToString(service->GetStateType()) << ";"
945 << service->GetCheckAttempt() << ";"
949 switch (service->GetState()) {
951 type = LogEntryTypeServiceOk;
954 type = LogEntryTypeServiceUnknown;
957 type = LogEntryTypeServiceWarning;
959 case ServiceCritical:
960 type = LogEntryTypeServiceCritical;
963 Log(LogCritical, "DbEvents")
964 << "Unknown service state: " << service->GetState();
968 msgbuf << "HOST ALERT: "
969 << host->GetName() << ";"
970 << GetHostStateString(host) << ";"
971 << Host::StateTypeToString(host->GetStateType()) << ";"
972 << host->GetCheckAttempt() << ";"
976 switch (host->GetState()) {
978 type = LogEntryTypeHostUp;
981 type = LogEntryTypeHostDown;
984 Log(LogCritical, "DbEvents")
985 << "Unknown host state: " << host->GetState();
989 if (!host->IsReachable())
990 type = LogEntryTypeHostUnreachable;
993 AddLogHistory(checkable, msgbuf.str(), type);
996 void DbEvents::AddTriggerDowntimeLogHistory(const Downtime::Ptr& downtime)
998 Checkable::Ptr checkable = downtime->GetCheckable();
1001 Service::Ptr service;
1002 tie(host, service) = GetHostService(checkable);
1004 std::ostringstream msgbuf;
1007 msgbuf << "SERVICE DOWNTIME ALERT: "
1008 << host->GetName() << ";"
1009 << service->GetShortName() << ";"
1010 << "STARTED" << "; "
1011 << "Service has entered a period of scheduled downtime."
1014 msgbuf << "HOST DOWNTIME ALERT: "
1015 << host->GetName() << ";"
1016 << "STARTED" << "; "
1017 << "Service has entered a period of scheduled downtime."
1021 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1024 void DbEvents::AddRemoveDowntimeLogHistory(const Downtime::Ptr& downtime)
1026 Checkable::Ptr checkable = downtime->GetCheckable();
1028 String downtimeOutput;
1029 String downtimeStateStr;
1031 if (downtime->GetWasCancelled()) {
1032 downtimeOutput = "Scheduled downtime for service has been cancelled.";
1033 downtimeStateStr = "CANCELLED";
1035 downtimeOutput = "Service has exited from a period of scheduled downtime.";
1036 downtimeStateStr = "STOPPED";
1040 Service::Ptr service;
1041 tie(host, service) = GetHostService(checkable);
1043 std::ostringstream msgbuf;
1046 msgbuf << "SERVICE DOWNTIME ALERT: "
1047 << host->GetName() << ";"
1048 << service->GetShortName() << ";"
1049 << downtimeStateStr << "; "
1053 msgbuf << "HOST DOWNTIME ALERT: "
1054 << host->GetName() << ";"
1055 << downtimeStateStr << "; "
1060 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1063 void DbEvents::AddNotificationSentLogHistory(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const User::Ptr& user,
1064 NotificationType notification_type, const CheckResult::Ptr& cr, const NotificationResult::Ptr& nr,
1065 const String& author, const String& comment_text)
1067 CheckCommand::Ptr commandObj = checkable->GetCheckCommand();
1069 String checkCommandName;
1072 checkCommandName = commandObj->GetName();
1074 String notificationTypeStr = Notification::NotificationTypeToString(notification_type);
1076 String author_comment = "";
1077 if (notification_type == NotificationCustom || notification_type == NotificationAcknowledgement) {
1078 author_comment = ";" + author + ";" + comment_text;
1084 String output = CompatUtility::GetCheckResultOutput(cr);
1087 Service::Ptr service;
1088 tie(host, service) = GetHostService(checkable);
1090 std::ostringstream msgbuf;
1093 msgbuf << "SERVICE NOTIFICATION: "
1094 << user->GetName() << ";"
1095 << host->GetName() << ";"
1096 << service->GetShortName() << ";"
1097 << notificationTypeStr << " "
1098 << "(" << Service::StateToString(service->GetState()) << ");"
1099 << checkCommandName << ";"
1100 << output << author_comment
1103 msgbuf << "HOST NOTIFICATION: "
1104 << user->GetName() << ";"
1105 << host->GetName() << ";"
1106 << notificationTypeStr << " "
1107 << "(" << Host::StateToString(host->GetState()) << ");"
1108 << checkCommandName << ";"
1109 << output << author_comment
1113 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeHostNotification);
1116 void DbEvents::AddFlappingChangedLogHistory(const Checkable::Ptr& checkable)
1118 String flappingStateStr;
1119 String flappingOutput;
1121 if (checkable->IsFlapping()) {
1122 flappingOutput = "Service appears to have started flapping (" + Convert::ToString(checkable->GetFlappingCurrent()) + "% change >= " + Convert::ToString(checkable->GetFlappingThresholdHigh()) + "% threshold)";
1123 flappingStateStr = "STARTED";
1125 flappingOutput = "Service appears to have stopped flapping (" + Convert::ToString(checkable->GetFlappingCurrent()) + "% change < " + Convert::ToString(checkable->GetFlappingThresholdLow()) + "% threshold)";
1126 flappingStateStr = "STOPPED";
1130 Service::Ptr service;
1131 tie(host, service) = GetHostService(checkable);
1133 std::ostringstream msgbuf;
1136 msgbuf << "SERVICE FLAPPING ALERT: "
1137 << host->GetName() << ";"
1138 << service->GetShortName() << ";"
1139 << flappingStateStr << "; "
1143 msgbuf << "HOST FLAPPING ALERT: "
1144 << host->GetName() << ";"
1145 << flappingStateStr << "; "
1150 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1153 void DbEvents::AddEnableFlappingChangedLogHistory(const Checkable::Ptr& checkable)
1155 if (!checkable->GetEnableFlapping())
1158 String flappingOutput = "Flap detection has been disabled";
1159 String flappingStateStr = "DISABLED";
1162 Service::Ptr service;
1163 tie(host, service) = GetHostService(checkable);
1165 std::ostringstream msgbuf;
1168 msgbuf << "SERVICE FLAPPING ALERT: "
1169 << host->GetName() << ";"
1170 << service->GetShortName() << ";"
1171 << flappingStateStr << "; "
1175 msgbuf << "HOST FLAPPING ALERT: "
1176 << host->GetName() << ";"
1177 << flappingStateStr << "; "
1182 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1185 void DbEvents::AddLogHistory(const Checkable::Ptr& checkable, const String& buffer, LogEntryType type)
1187 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
1190 query1.Table = "logentries";
1191 query1.Type = DbQueryInsert;
1192 query1.Category = DbCatLog;
1194 Dictionary::Ptr fields1 = new Dictionary();
1196 fields1->Set("logentry_time", DbValue::FromTimestamp(timeBag.first));
1197 fields1->Set("entry_time", DbValue::FromTimestamp(timeBag.first));
1198 fields1->Set("entry_time_usec", timeBag.second);
1199 fields1->Set("object_id", checkable);
1200 fields1->Set("logentry_type", type);
1201 fields1->Set("logentry_data", buffer);
1203 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1205 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1208 fields1->Set("endpoint_object_id", endpoint);
1210 query1.Fields = fields1;
1211 DbObject::OnQuery(query1);
1214 /* flappinghistory */
1215 void DbEvents::AddFlappingChangedHistory(const Checkable::Ptr& checkable)
1217 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
1220 query1.Table = "flappinghistory";
1221 query1.Type = DbQueryInsert;
1222 query1.Category = DbCatFlapping;
1224 Dictionary::Ptr fields1 = new Dictionary();
1226 fields1->Set("event_time", DbValue::FromTimestamp(timeBag.first));
1227 fields1->Set("event_time_usec", timeBag.second);
1229 if (checkable->IsFlapping())
1230 fields1->Set("event_type", 1000);
1232 fields1->Set("event_type", 1001);
1233 fields1->Set("reason_type", 1);
1237 Service::Ptr service;
1238 tie(host, service) = GetHostService(checkable);
1240 fields1->Set("flapping_type", service ? 1 : 0);
1241 fields1->Set("object_id", checkable);
1242 fields1->Set("percent_state_change", checkable->GetFlappingCurrent());
1243 fields1->Set("low_threshold", checkable->GetFlappingThresholdLow());
1244 fields1->Set("high_threshold", checkable->GetFlappingThresholdHigh());
1246 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1248 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1251 fields1->Set("endpoint_object_id", endpoint);
1253 query1.Fields = fields1;
1254 DbObject::OnQuery(query1);
1257 void DbEvents::AddEnableFlappingChangedHistory(const Checkable::Ptr& checkable)
1259 if (!checkable->GetEnableFlapping())
1262 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
1265 query1.Table = "flappinghistory";
1266 query1.Type = DbQueryInsert;
1267 query1.Category = DbCatFlapping;
1269 Dictionary::Ptr fields1 = new Dictionary();
1271 fields1->Set("event_time", DbValue::FromTimestamp(timeBag.first));
1272 fields1->Set("event_time_usec", timeBag.second);
1274 fields1->Set("event_type", 1001);
1275 fields1->Set("reason_type", 2);
1278 Service::Ptr service;
1279 tie(host, service) = GetHostService(checkable);
1281 fields1->Set("flapping_type", service ? 1 : 0);
1282 fields1->Set("object_id", checkable);
1283 fields1->Set("percent_state_change", checkable->GetFlappingCurrent());
1284 fields1->Set("low_threshold", checkable->GetFlappingThresholdLow());
1285 fields1->Set("high_threshold", checkable->GetFlappingThresholdHigh());
1286 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1288 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1291 fields1->Set("endpoint_object_id", endpoint);
1293 query1.Fields = fields1;
1294 DbObject::OnQuery(query1);
1298 void DbEvents::AddCheckableCheckHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr)
1304 Service::Ptr service;
1305 tie(host, service) = GetHostService(checkable);
1308 query1.Table = service ? "servicechecks" : "hostchecks";
1309 query1.Type = DbQueryInsert;
1310 query1.Category = DbCatCheck;
1312 Dictionary::Ptr fields1 = new Dictionary();
1313 fields1->Set("check_type", !checkable->GetEnableActiveChecks()); /* 0 .. active, 1 .. passive */
1314 fields1->Set("current_check_attempt", checkable->GetCheckAttempt());
1315 fields1->Set("max_check_attempts", checkable->GetMaxCheckAttempts());
1316 fields1->Set("state_type", checkable->GetStateType());
1318 double start = cr->GetExecutionStart();
1319 double end = cr->GetExecutionEnd();
1320 double executionTime = cr->CalculateExecutionTime();
1322 std::pair<unsigned long, unsigned long> timeBagStart = ConvertTimestamp(start);
1323 std::pair<unsigned long, unsigned long> timeBagEnd = ConvertTimestamp(end);
1325 fields1->Set("start_time", DbValue::FromTimestamp(timeBagStart.first));
1326 fields1->Set("start_time_usec", timeBagStart.second);
1327 fields1->Set("end_time", DbValue::FromTimestamp(timeBagEnd.first));
1328 fields1->Set("end_time_usec", timeBagEnd.second);
1329 fields1->Set("command_object_id", checkable->GetCheckCommand());
1330 fields1->Set("execution_time", executionTime);
1331 fields1->Set("latency", cr->CalculateLatency());
1332 fields1->Set("return_code", cr->GetExitStatus());
1333 fields1->Set("perfdata", PluginUtility::FormatPerfdata(cr->GetPerformanceData()));
1335 fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
1336 fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
1337 fields1->Set("command_line", CompatUtility::GetCommandLine(checkable->GetCheckCommand()));
1338 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1341 fields1->Set("service_object_id", service);
1342 fields1->Set("state", service->GetState());
1344 fields1->Set("host_object_id", host);
1345 fields1->Set("state", GetHostState(host));
1348 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1351 fields1->Set("endpoint_object_id", endpoint);
1353 query1.Fields = fields1;
1354 DbObject::OnQuery(query1);
1358 void DbEvents::AddEventHandlerHistory(const Checkable::Ptr& checkable)
1361 query1.Table = "eventhandlers";
1362 query1.Type = DbQueryInsert;
1363 query1.Category = DbCatEventHandler;
1365 Dictionary::Ptr fields1 = new Dictionary();
1368 Service::Ptr service;
1369 tie(host, service) = GetHostService(checkable);
1371 fields1->Set("object_id", checkable);
1372 fields1->Set("state_type", checkable->GetStateType());
1373 fields1->Set("command_object_id", checkable->GetEventCommand());
1374 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1377 fields1->Set("state", service->GetState());
1378 fields1->Set("eventhandler_type", 1);
1380 fields1->Set("state", GetHostState(host));
1381 fields1->Set("eventhandler_type", 0);
1384 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
1386 fields1->Set("start_time", DbValue::FromTimestamp(timeBag.first));
1387 fields1->Set("start_time_usec", timeBag.second);
1388 fields1->Set("end_time", DbValue::FromTimestamp(timeBag.first));
1389 fields1->Set("end_time_usec", timeBag.second);
1391 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1394 fields1->Set("endpoint_object_id", endpoint);
1396 query1.Fields = fields1;
1397 DbObject::OnQuery(query1);
1400 /* externalcommands */
1401 void DbEvents::AddExternalCommandHistory(double time, const String& command, const std::vector<String>& arguments)
1404 query1.Table = "externalcommands";
1405 query1.Type = DbQueryInsert;
1406 query1.Category = DbCatExternalCommand;
1408 Dictionary::Ptr fields1 = new Dictionary();
1410 fields1->Set("entry_time", DbValue::FromTimestamp(time));
1411 fields1->Set("command_type", MapExternalCommandType(command));
1412 fields1->Set("command_name", command);
1413 fields1->Set("command_args", boost::algorithm::join(arguments, ";"));
1414 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1416 Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1419 fields1->Set("endpoint_object_id", endpoint);
1421 query1.Fields = fields1;
1422 DbObject::OnQuery(query1);
1425 int DbEvents::GetHostState(const Host::Ptr& host)
1427 int currentState = host->GetState();
1429 if (currentState != HostUp && !host->IsReachable())
1430 currentState = 2; /* hardcoded compat state */
1432 return currentState;
1435 String DbEvents::GetHostStateString(const Host::Ptr& host)
1437 if (host->GetState() != HostUp && !host->IsReachable())
1438 return "UNREACHABLE"; /* hardcoded compat state */
1440 return Host::StateToString(host->GetState());
1443 std::pair<unsigned long, unsigned long> DbEvents::ConvertTimestamp(double time)
1445 unsigned long time_sec = static_cast<long>(time);
1446 unsigned long time_usec = (time - time_sec) * 1000 * 1000;
1448 return std::make_pair(time_sec, time_usec);
1451 int DbEvents::MapNotificationReasonType(NotificationType type)
1454 case NotificationDowntimeStart:
1456 case NotificationDowntimeEnd:
1458 case NotificationDowntimeRemoved:
1460 case NotificationCustom:
1462 case NotificationAcknowledgement:
1464 case NotificationProblem:
1466 case NotificationRecovery:
1468 case NotificationFlappingStart:
1470 case NotificationFlappingEnd:
1477 int DbEvents::MapExternalCommandType(const String& name)
1481 if (name == "ADD_HOST_COMMENT")
1483 if (name == "DEL_HOST_COMMENT")
1485 if (name == "ADD_SVC_COMMENT")
1487 if (name == "DEL_SVC_COMMENT")
1489 if (name == "ENABLE_SVC_CHECK")
1491 if (name == "DISABLE_SVC_CHECK")
1493 if (name == "SCHEDULE_SVC_CHECK")
1495 if (name == "DELAY_SVC_NOTIFICATION")
1497 if (name == "DELAY_HOST_NOTIFICATION")
1499 if (name == "DISABLE_NOTIFICATIONS")
1501 if (name == "ENABLE_NOTIFICATIONS")
1503 if (name == "RESTART_PROCESS")
1505 if (name == "SHUTDOWN_PROCESS")
1507 if (name == "ENABLE_HOST_SVC_CHECKS")
1509 if (name == "DISABLE_HOST_SVC_CHECKS")
1511 if (name == "SCHEDULE_HOST_SVC_CHECKS")
1513 if (name == "DELAY_HOST_SVC_NOTIFICATIONS")
1515 if (name == "DEL_ALL_HOST_COMMENTS")
1517 if (name == "DEL_ALL_SVC_COMMENTS")
1519 if (name == "ENABLE_SVC_NOTIFICATIONS")
1521 if (name == "DISABLE_SVC_NOTIFICATIONS")
1523 if (name == "ENABLE_HOST_NOTIFICATIONS")
1525 if (name == "DISABLE_HOST_NOTIFICATIONS")
1527 if (name == "ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST")
1529 if (name == "DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST")
1531 if (name == "ENABLE_HOST_SVC_NOTIFICATIONS")
1533 if (name == "DISABLE_HOST_SVC_NOTIFICATIONS")
1535 if (name == "PROCESS_SERVICE_CHECK_RESULT")
1537 if (name == "SAVE_STATE_INFORMATION")
1539 if (name == "READ_STATE_INFORMATION")
1541 if (name == "ACKNOWLEDGE_HOST_PROBLEM")
1543 if (name == "ACKNOWLEDGE_SVC_PROBLEM")
1545 if (name == "START_EXECUTING_SVC_CHECKS")
1547 if (name == "STOP_EXECUTING_SVC_CHECKS")
1549 if (name == "START_ACCEPTING_PASSIVE_SVC_CHECKS")
1551 if (name == "STOP_ACCEPTING_PASSIVE_SVC_CHECKS")
1553 if (name == "ENABLE_PASSIVE_SVC_CHECKS")
1555 if (name == "DISABLE_PASSIVE_SVC_CHECKS")
1557 if (name == "ENABLE_EVENT_HANDLERS")
1559 if (name == "DISABLE_EVENT_HANDLERS")
1561 if (name == "ENABLE_HOST_EVENT_HANDLER")
1563 if (name == "DISABLE_HOST_EVENT_HANDLER")
1565 if (name == "ENABLE_SVC_EVENT_HANDLER")
1567 if (name == "DISABLE_SVC_EVENT_HANDLER")
1569 if (name == "ENABLE_HOST_CHECK")
1571 if (name == "DISABLE_HOST_CHECK")
1573 if (name == "START_OBSESSING_OVER_SVC_CHECKS")
1575 if (name == "STOP_OBSESSING_OVER_SVC_CHECKS")
1577 if (name == "REMOVE_HOST_ACKNOWLEDGEMENT")
1579 if (name == "REMOVE_SVC_ACKNOWLEDGEMENT")
1581 if (name == "SCHEDULE_FORCED_HOST_SVC_CHECKS")
1583 if (name == "SCHEDULE_FORCED_SVC_CHECK")
1585 if (name == "SCHEDULE_HOST_DOWNTIME")
1587 if (name == "SCHEDULE_SVC_DOWNTIME")
1589 if (name == "ENABLE_HOST_FLAP_DETECTION")
1591 if (name == "DISABLE_HOST_FLAP_DETECTION")
1593 if (name == "ENABLE_SVC_FLAP_DETECTION")
1595 if (name == "DISABLE_SVC_FLAP_DETECTION")
1597 if (name == "ENABLE_FLAP_DETECTION")
1599 if (name == "DISABLE_FLAP_DETECTION")
1601 if (name == "ENABLE_HOSTGROUP_SVC_NOTIFICATIONS")
1603 if (name == "DISABLE_HOSTGROUP_SVC_NOTIFICATIONS")
1605 if (name == "ENABLE_HOSTGROUP_HOST_NOTIFICATIONS")
1607 if (name == "DISABLE_HOSTGROUP_HOST_NOTIFICATIONS")
1609 if (name == "ENABLE_HOSTGROUP_SVC_CHECKS")
1611 if (name == "DISABLE_HOSTGROUP_SVC_CHECKS")
1613 if (name == "CANCEL_HOST_DOWNTIME")
1615 if (name == "CANCEL_SVC_DOWNTIME")
1617 if (name == "CANCEL_ACTIVE_HOST_DOWNTIME")
1619 if (name == "CANCEL_PENDING_HOST_DOWNTIME")
1621 if (name == "CANCEL_ACTIVE_SVC_DOWNTIME")
1623 if (name == "CANCEL_PENDING_SVC_DOWNTIME")
1625 if (name == "CANCEL_ACTIVE_HOST_SVC_DOWNTIME")
1627 if (name == "CANCEL_PENDING_HOST_SVC_DOWNTIME")
1629 if (name == "FLUSH_PENDING_COMMANDS")
1631 if (name == "DEL_HOST_DOWNTIME")
1633 if (name == "DEL_SVC_DOWNTIME")
1635 if (name == "ENABLE_FAILURE_PREDICTION")
1637 if (name == "DISABLE_FAILURE_PREDICTION")
1639 if (name == "ENABLE_PERFORMANCE_DATA")
1641 if (name == "DISABLE_PERFORMANCE_DATA")
1643 if (name == "SCHEDULE_HOSTGROUP_HOST_DOWNTIME")
1645 if (name == "SCHEDULE_HOSTGROUP_SVC_DOWNTIME")
1647 if (name == "SCHEDULE_HOST_SVC_DOWNTIME")
1649 if (name == "PROCESS_HOST_CHECK_RESULT")
1651 if (name == "START_EXECUTING_HOST_CHECKS")
1653 if (name == "STOP_EXECUTING_HOST_CHECKS")
1655 if (name == "START_ACCEPTING_PASSIVE_HOST_CHECKS")
1657 if (name == "STOP_ACCEPTING_PASSIVE_HOST_CHECKS")
1659 if (name == "ENABLE_PASSIVE_HOST_CHECKS")
1661 if (name == "DISABLE_PASSIVE_HOST_CHECKS")
1663 if (name == "START_OBSESSING_OVER_HOST_CHECKS")
1665 if (name == "STOP_OBSESSING_OVER_HOST_CHECKS")
1667 if (name == "SCHEDULE_HOST_CHECK")
1669 if (name == "SCHEDULE_FORCED_HOST_CHECK")
1671 if (name == "START_OBSESSING_OVER_SVC")
1673 if (name == "STOP_OBSESSING_OVER_SVC")
1675 if (name == "START_OBSESSING_OVER_HOST")
1677 if (name == "STOP_OBSESSING_OVER_HOST")
1679 if (name == "ENABLE_HOSTGROUP_HOST_CHECKS")
1681 if (name == "DISABLE_HOSTGROUP_HOST_CHECKS")
1683 if (name == "ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS")
1685 if (name == "DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS")
1687 if (name == "ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS")
1689 if (name == "DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS")
1691 if (name == "ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS")
1693 if (name == "DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS")
1695 if (name == "ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS")
1697 if (name == "DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS")
1699 if (name == "ENABLE_SERVICEGROUP_SVC_CHECKS")
1701 if (name == "DISABLE_SERVICEGROUP_SVC_CHECKS")
1703 if (name == "ENABLE_SERVICEGROUP_HOST_CHECKS")
1705 if (name == "DISABLE_SERVICEGROUP_HOST_CHECKS")
1707 if (name == "ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS")
1709 if (name == "DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS")
1711 if (name == "ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS")
1713 if (name == "DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS")
1715 if (name == "SCHEDULE_SERVICEGROUP_HOST_DOWNTIME")
1717 if (name == "SCHEDULE_SERVICEGROUP_SVC_DOWNTIME")
1719 if (name == "CHANGE_GLOBAL_HOST_EVENT_HANDLER")
1721 if (name == "CHANGE_GLOBAL_SVC_EVENT_HANDLER")
1723 if (name == "CHANGE_HOST_EVENT_HANDLER")
1725 if (name == "CHANGE_SVC_EVENT_HANDLER")
1727 if (name == "CHANGE_HOST_CHECK_COMMAND")
1729 if (name == "CHANGE_SVC_CHECK_COMMAND")
1731 if (name == "CHANGE_NORMAL_HOST_CHECK_INTERVAL")
1733 if (name == "CHANGE_NORMAL_SVC_CHECK_INTERVAL")
1735 if (name == "CHANGE_RETRY_SVC_CHECK_INTERVAL")
1737 if (name == "CHANGE_MAX_HOST_CHECK_ATTEMPTS")
1739 if (name == "CHANGE_MAX_SVC_CHECK_ATTEMPTS")
1741 if (name == "SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME")
1743 if (name == "ENABLE_HOST_AND_CHILD_NOTIFICATIONS")
1745 if (name == "DISABLE_HOST_AND_CHILD_NOTIFICATIONS")
1747 if (name == "SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME")
1749 if (name == "ENABLE_SERVICE_FRESHNESS_CHECKS")
1751 if (name == "DISABLE_SERVICE_FRESHNESS_CHECKS")
1753 if (name == "ENABLE_HOST_FRESHNESS_CHECKS")
1755 if (name == "DISABLE_HOST_FRESHNESS_CHECKS")
1757 if (name == "SET_HOST_NOTIFICATION_NUMBER")
1759 if (name == "SET_SVC_NOTIFICATION_NUMBER")
1761 if (name == "CHANGE_HOST_CHECK_TIMEPERIOD")
1763 if (name == "CHANGE_SVC_CHECK_TIMEPERIOD")
1765 if (name == "PROCESS_FILE")
1767 if (name == "CHANGE_CUSTOM_HOST_VAR")
1769 if (name == "CHANGE_CUSTOM_SVC_VAR")
1771 if (name == "CHANGE_CUSTOM_CONTACT_VAR")
1773 if (name == "ENABLE_CONTACT_HOST_NOTIFICATIONS")
1775 if (name == "DISABLE_CONTACT_HOST_NOTIFICATIONS")
1777 if (name == "ENABLE_CONTACT_SVC_NOTIFICATIONS")
1779 if (name == "DISABLE_CONTACT_SVC_NOTIFICATIONS")
1781 if (name == "ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS")
1783 if (name == "DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS")
1785 if (name == "ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS")
1787 if (name == "DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS")
1789 if (name == "CHANGE_RETRY_HOST_CHECK_INTERVAL")
1791 if (name == "SEND_CUSTOM_HOST_NOTIFICATION")
1793 if (name == "SEND_CUSTOM_SVC_NOTIFICATION")
1795 if (name == "CHANGE_HOST_NOTIFICATION_TIMEPERIOD")
1797 if (name == "CHANGE_SVC_NOTIFICATION_TIMEPERIOD")
1799 if (name == "CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD")
1801 if (name == "CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD")
1803 if (name == "CHANGE_HOST_MODATTR")
1805 if (name == "CHANGE_SVC_MODATTR")
1807 if (name == "CHANGE_CONTACT_MODATTR")
1809 if (name == "CHANGE_CONTACT_MODHATTR")
1811 if (name == "CHANGE_CONTACT_MODSATTR")
1813 if (name == "SYNC_STATE_INFORMATION")
1815 if (name == "DEL_DOWNTIME_BY_HOST_NAME")
1817 if (name == "DEL_DOWNTIME_BY_HOSTGROUP_NAME")
1819 if (name == "DEL_DOWNTIME_BY_START_TIME_COMMENT")
1821 if (name == "ACKNOWLEDGE_HOST_PROBLEM_EXPIRE")
1823 if (name == "ACKNOWLEDGE_SVC_PROBLEM_EXPIRE")
1825 if (name == "DISABLE_NOTIFICATIONS_EXPIRE_TIME")
1827 if (name == "CUSTOM_COMMAND")