1 /******************************************************************************
3 * Copyright (C) 2012-2014 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 "db_ido/dbevents.hpp"
21 #include "db_ido/dbtype.hpp"
22 #include "db_ido/dbvalue.hpp"
23 #include "base/convert.hpp"
24 #include "base/objectlock.hpp"
25 #include "base/initialize.hpp"
26 #include "base/dynamictype.hpp"
27 #include "base/utility.hpp"
28 #include "base/logger.hpp"
29 #include "remote/endpoint.hpp"
30 #include "icinga/notification.hpp"
31 #include "icinga/checkcommand.hpp"
32 #include "icinga/eventcommand.hpp"
33 #include "icinga/externalcommandprocessor.hpp"
34 #include "icinga/compatutility.hpp"
35 #include "icinga/icingaapplication.hpp"
36 #include <boost/foreach.hpp>
37 #include <boost/algorithm/string/join.hpp>
39 using namespace icinga;
41 INITIALIZE_ONCE(&DbEvents::StaticInitialize);
43 void DbEvents::StaticInitialize(void)
46 Checkable::OnCommentAdded.connect(boost::bind(&DbEvents::AddComment, _1, _2));
47 Checkable::OnCommentRemoved.connect(boost::bind(&DbEvents::RemoveComment, _1, _2));
48 Checkable::OnDowntimeAdded.connect(boost::bind(&DbEvents::AddDowntime, _1, _2));
49 Checkable::OnDowntimeRemoved.connect(boost::bind(&DbEvents::RemoveDowntime, _1, _2));
50 Checkable::OnDowntimeTriggered.connect(boost::bind(&DbEvents::TriggerDowntime, _1, _2));
51 Checkable::OnAcknowledgementSet.connect(boost::bind(&DbEvents::AddAcknowledgement, _1, _4));
52 Checkable::OnAcknowledgementCleared.connect(boost::bind(&DbEvents::RemoveAcknowledgement, _1));
54 Checkable::OnNextCheckChanged.connect(boost::bind(&DbEvents::NextCheckChangedHandler, _1, _2));
55 Checkable::OnFlappingChanged.connect(boost::bind(&DbEvents::FlappingChangedHandler, _1, _2));
56 Checkable::OnNotificationSentToAllUsers.connect(boost::bind(&DbEvents::LastNotificationChangedHandler, _1, _2));
58 Checkable::OnEnableActiveChecksChanged.connect(boost::bind(&DbEvents::EnableActiveChecksChangedHandler, _1, _2));
59 Checkable::OnEnablePassiveChecksChanged.connect(boost::bind(&DbEvents::EnablePassiveChecksChangedHandler, _1, _2));
60 Checkable::OnEnableNotificationsChanged.connect(boost::bind(&DbEvents::EnableNotificationsChangedHandler, _1, _2));
61 Checkable::OnEnablePerfdataChanged.connect(boost::bind(&DbEvents::EnablePerfdataChangedHandler, _1, _2));
62 Checkable::OnEnableFlappingChanged.connect(boost::bind(&DbEvents::EnableFlappingChangedHandler, _1, _2));
65 Checkable::OnCommentAdded.connect(boost::bind(&DbEvents::AddCommentHistory, _1, _2));
66 Checkable::OnDowntimeAdded.connect(boost::bind(&DbEvents::AddDowntimeHistory, _1, _2));
67 Checkable::OnAcknowledgementSet.connect(boost::bind(&DbEvents::AddAcknowledgementHistory, _1, _2, _3, _4, _5));
69 Checkable::OnNotificationSentToAllUsers.connect(boost::bind(&DbEvents::AddNotificationHistory, _1, _2, _3, _4, _5, _6, _7));
71 Checkable::OnStateChange.connect(boost::bind(&DbEvents::AddStateChangeHistory, _1, _2, _3));
73 Checkable::OnNewCheckResult.connect(boost::bind(&DbEvents::AddCheckResultLogHistory, _1, _2));
74 Checkable::OnNotificationSentToUser.connect(boost::bind(&DbEvents::AddNotificationSentLogHistory, _1, _2, _3, _4, _5, _6, _7));
75 Checkable::OnFlappingChanged.connect(boost::bind(&DbEvents::AddFlappingLogHistory, _1, _2));
76 Checkable::OnDowntimeTriggered.connect(boost::bind(&DbEvents::AddTriggerDowntimeLogHistory, _1, _2));
77 Checkable::OnDowntimeRemoved.connect(boost::bind(&DbEvents::AddRemoveDowntimeLogHistory, _1, _2));
79 Checkable::OnFlappingChanged.connect(boost::bind(&DbEvents::AddFlappingHistory, _1, _2));
80 Checkable::OnNewCheckResult.connect(boost::bind(&DbEvents::AddServiceCheckHistory, _1, _2));
82 Checkable::OnEventCommandExecuted.connect(boost::bind(&DbEvents::AddEventHandlerHistory, _1));
84 ExternalCommandProcessor::OnNewExternalCommand.connect(boost::bind(&DbEvents::AddExternalCommandHistory, _1, _2, _3));
88 void DbEvents::NextCheckChangedHandler(const Checkable::Ptr& checkable, double nextCheck)
92 tie(host, service) = GetHostService(checkable);
96 query1.Table = "servicestatus";
98 query1.Table = "hoststatus";
100 query1.Type = DbQueryUpdate;
102 Dictionary::Ptr fields1 = make_shared<Dictionary>();
103 fields1->Set("next_check", DbValue::FromTimestamp(nextCheck));
105 query1.Fields = fields1;
107 query1.WhereCriteria = make_shared<Dictionary>();
109 query1.WhereCriteria->Set("service_object_id", service);
111 query1.WhereCriteria->Set("host_object_id", host);
113 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
115 DbObject::OnQuery(query1);
118 void DbEvents::FlappingChangedHandler(const Checkable::Ptr& checkable, FlappingState state)
121 Service::Ptr service;
122 tie(host, service) = GetHostService(checkable);
126 query1.Table = "servicestatus";
128 query1.Table = "hoststatus";
130 query1.Type = DbQueryUpdate;
132 Dictionary::Ptr fields1 = make_shared<Dictionary>();
133 fields1->Set("is_flapping", CompatUtility::GetCheckableIsFlapping(checkable));
134 fields1->Set("percent_state_change", CompatUtility::GetCheckablePercentStateChange(checkable));
136 query1.Fields = fields1;
138 query1.WhereCriteria = make_shared<Dictionary>();
140 query1.WhereCriteria->Set("service_object_id", service);
142 query1.WhereCriteria->Set("host_object_id", host);
144 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
146 DbObject::OnQuery(query1);
149 void DbEvents::LastNotificationChangedHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable)
151 double now = Utility::GetTime();
152 std::pair<unsigned long, unsigned long> now_bag = CompatUtility::ConvertTimestamp(now);
153 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(notification->GetNextNotification());
156 Service::Ptr service;
157 tie(host, service) = GetHostService(checkable);
161 query1.Table = "servicestatus";
163 query1.Table = "hoststatus";
165 query1.Type = DbQueryUpdate;
167 Dictionary::Ptr fields1 = make_shared<Dictionary>();
168 fields1->Set("last_notification", DbValue::FromTimestamp(now_bag.first));
169 fields1->Set("next_notification", DbValue::FromTimestamp(time_bag.first));
170 fields1->Set("current_notification_number", notification->GetNotificationNumber());
172 query1.Fields = fields1;
174 query1.WhereCriteria = make_shared<Dictionary>();
176 query1.WhereCriteria->Set("service_object_id", service);
178 query1.WhereCriteria->Set("host_object_id", host);
180 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
182 DbObject::OnQuery(query1);
185 /* enable changed events */
186 void DbEvents::EnableActiveChecksChangedHandler(const Checkable::Ptr& checkable, bool enabled)
188 EnableChangedHandlerInternal(checkable, enabled, EnableActiveChecks);
191 void DbEvents::EnablePassiveChecksChangedHandler(const Checkable::Ptr& checkable, bool enabled)
193 EnableChangedHandlerInternal(checkable, enabled, EnablePassiveChecks);
196 void DbEvents::EnableNotificationsChangedHandler(const Checkable::Ptr& checkable, bool enabled)
198 EnableChangedHandlerInternal(checkable, enabled, EnableNotifications);
201 void DbEvents::EnablePerfdataChangedHandler(const Checkable::Ptr& checkable, bool enabled)
203 EnableChangedHandlerInternal(checkable, enabled, EnablePerfdata);
206 void DbEvents::EnableFlappingChangedHandler(const Checkable::Ptr& checkable, bool enabled)
208 EnableChangedHandlerInternal(checkable, enabled, EnableFlapping);
211 void DbEvents::EnableChangedHandlerInternal(const Checkable::Ptr& checkable, bool enabled, EnableType type)
214 Service::Ptr service;
215 tie(host, service) = GetHostService(checkable);
219 query1.Table = "servicestatus";
221 query1.Table = "hoststatus";
223 query1.Type = DbQueryUpdate;
225 Dictionary::Ptr fields1 = make_shared<Dictionary>();
227 if (type == EnableActiveChecks) {
228 fields1->Set("active_checks_enabled", enabled ? 1 : 0);
229 } else if (type == EnablePassiveChecks) {
230 fields1->Set("passive_checks_enabled", enabled ? 1 : 0);
231 } else if (type == EnableNotifications) {
232 fields1->Set("notifications_enabled", enabled ? 1 : 0);
233 } else if (type == EnablePerfdata) {
234 fields1->Set("process_performance_data", enabled ? 1 : 0);
235 } else if (type == EnableFlapping) {
236 fields1->Set("flap_detection_enabled", enabled ? 1 : 0);
239 query1.Fields = fields1;
241 query1.WhereCriteria = make_shared<Dictionary>();
243 query1.WhereCriteria->Set("service_object_id", service);
245 query1.WhereCriteria->Set("host_object_id", host);
247 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
249 DbObject::OnQuery(query1);
253 void DbEvents::AddComments(const Checkable::Ptr& checkable)
255 /* dump all comments */
256 Dictionary::Ptr comments = checkable->GetComments();
258 if (comments->GetLength() > 0)
259 RemoveComments(checkable);
261 ObjectLock olock(comments);
263 BOOST_FOREACH(const Dictionary::Pair& kv, comments) {
264 AddComment(checkable, kv.second);
268 void DbEvents::AddComment(const Checkable::Ptr& checkable, const Comment::Ptr& comment)
270 AddCommentInternal(checkable, comment, false);
273 void DbEvents::AddCommentHistory(const Checkable::Ptr& checkable, const Comment::Ptr& comment)
275 AddCommentInternal(checkable, comment, true);
278 void DbEvents::AddCommentInternal(const Checkable::Ptr& checkable, const Comment::Ptr& comment, bool historical)
281 Log(LogWarning, "DbEvents", "comment does not exist. not adding it.");
285 Log(LogDebug, "DbEvents")
286 << "adding service comment (id = " << comment->GetLegacyId() << ") for '" << checkable->GetName() << "'";
288 /* add the service comment */
289 AddCommentByType(checkable, comment, historical);
292 void DbEvents::AddCommentByType(const DynamicObject::Ptr& object, const Comment::Ptr& comment, bool historical)
294 unsigned long entry_time = static_cast<long>(comment->GetEntryTime());
295 unsigned long entry_time_usec = (comment->GetEntryTime() - entry_time) * 1000 * 1000;
297 Dictionary::Ptr fields1 = make_shared<Dictionary>();
298 fields1->Set("entry_time", DbValue::FromTimestamp(entry_time));
299 fields1->Set("entry_time_usec", entry_time_usec);
300 fields1->Set("entry_type", comment->GetEntryType());
301 fields1->Set("object_id", object);
303 if (object->GetType() == DynamicType::GetByName("Host")) {
304 fields1->Set("comment_type", 2);
305 /* requires idoutils 1.10 schema fix */
306 fields1->Set("internal_comment_id", comment->GetLegacyId());
307 } else if (object->GetType() == DynamicType::GetByName("Service")) {
308 fields1->Set("comment_type", 1);
309 fields1->Set("internal_comment_id", comment->GetLegacyId());
311 Log(LogDebug, "DbEvents", "unknown object type for adding comment.");
315 fields1->Set("comment_time", DbValue::FromTimestamp(entry_time)); /* same as entry_time */
316 fields1->Set("author_name", comment->GetAuthor());
317 fields1->Set("comment_data", comment->GetText());
318 fields1->Set("is_persistent", 1);
319 fields1->Set("comment_source", 1); /* external */
320 fields1->Set("expires", (comment->GetExpireTime() > 0) ? 1 : 0);
321 fields1->Set("expiration_time", DbValue::FromTimestamp(comment->GetExpireTime()));
322 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
324 String node = IcingaApplication::GetInstance()->GetNodeName();
326 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
328 fields1->Set("endpoint_object_id", endpoint);
332 query1.Table = "comments";
334 query1.Table = "commenthistory";
336 query1.Type = DbQueryInsert;
337 query1.Category = DbCatComment;
338 query1.Fields = fields1;
339 DbObject::OnQuery(query1);
342 void DbEvents::RemoveComments(const Checkable::Ptr& checkable)
344 Log(LogDebug, "DbEvents")
345 << "removing service comments for '" << checkable->GetName() << "'";
348 query1.Table = "comments";
349 query1.Type = DbQueryDelete;
350 query1.Category = DbCatComment;
351 query1.WhereCriteria = make_shared<Dictionary>();
352 query1.WhereCriteria->Set("object_id", checkable);
353 DbObject::OnQuery(query1);
356 void DbEvents::RemoveComment(const Checkable::Ptr& checkable, const Comment::Ptr& comment)
359 Log(LogWarning, "DbEvents", "comment does not exist. not deleting it.");
363 Log(LogDebug, "DbEvents")
364 << "removing service comment (id = " << comment->GetLegacyId() << ") for '" << checkable->GetName() << "'";
368 query1.Table = "comments";
369 query1.Type = DbQueryDelete;
370 query1.Category = DbCatComment;
371 query1.WhereCriteria = make_shared<Dictionary>();
372 query1.WhereCriteria->Set("object_id", checkable);
373 query1.WhereCriteria->Set("internal_comment_id", comment->GetLegacyId());
374 DbObject::OnQuery(query1);
376 /* History - update deletion time for service/host */
377 unsigned long entry_time = static_cast<long>(comment->GetEntryTime());
379 double now = Utility::GetTime();
380 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
383 query2.Table = "commenthistory";
384 query2.Type = DbQueryUpdate;
385 query2.Category = DbCatComment;
387 Dictionary::Ptr fields2 = make_shared<Dictionary>();
388 fields2->Set("deletion_time", DbValue::FromTimestamp(time_bag.first));
389 fields2->Set("deletion_time_usec", time_bag.second);
390 query2.Fields = fields2;
392 query2.WhereCriteria = make_shared<Dictionary>();
393 query2.WhereCriteria->Set("internal_comment_id", comment->GetLegacyId());
394 query2.WhereCriteria->Set("comment_time", DbValue::FromTimestamp(entry_time));
395 query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
397 DbObject::OnQuery(query2);
401 void DbEvents::AddDowntimes(const Checkable::Ptr& checkable)
403 /* dump all downtimes */
404 Dictionary::Ptr downtimes = checkable->GetDowntimes();
406 if (downtimes->GetLength() > 0)
407 RemoveDowntimes(checkable);
409 ObjectLock olock(downtimes);
411 BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
412 AddDowntime(checkable, kv.second);
416 void DbEvents::AddDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
418 AddDowntimeInternal(checkable, downtime, false);
421 void DbEvents::AddDowntimeHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
423 AddDowntimeInternal(checkable, downtime, true);
426 void DbEvents::AddDowntimeInternal(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, bool historical)
429 Log(LogWarning, "DbEvents", "downtime does not exist. not adding it.");
433 Log(LogDebug, "DbEvents")
434 << "adding service downtime (id = " << downtime->GetLegacyId() << ") for '" << checkable->GetName() << "'";
436 /* add the downtime */
437 AddDowntimeByType(checkable, downtime, historical);}
439 void DbEvents::AddDowntimeByType(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, bool historical)
441 Dictionary::Ptr fields1 = make_shared<Dictionary>();
442 fields1->Set("entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()));
443 fields1->Set("object_id", checkable);
445 if (checkable->GetType() == DynamicType::GetByName("Host")) {
446 fields1->Set("downtime_type", 2);
447 /* requires idoutils 1.10 schema fix */
448 fields1->Set("internal_downtime_id", downtime->GetLegacyId());
449 } else if (checkable->GetType() == DynamicType::GetByName("Service")) {
450 fields1->Set("downtime_type", 1);
451 fields1->Set("internal_downtime_id", downtime->GetLegacyId());
453 Log(LogDebug, "DbEvents", "unknown object type for adding downtime.");
457 fields1->Set("author_name", downtime->GetAuthor());
458 fields1->Set("comment_data", downtime->GetComment());
459 fields1->Set("triggered_by_id", Service::GetDowntimeByID(downtime->GetTriggeredBy()));
460 fields1->Set("is_fixed", downtime->GetFixed());
461 fields1->Set("duration", downtime->GetDuration());
462 fields1->Set("scheduled_start_time", DbValue::FromTimestamp(downtime->GetStartTime()));
463 fields1->Set("scheduled_end_time", DbValue::FromTimestamp(downtime->GetEndTime()));
464 fields1->Set("was_started", Empty);
465 fields1->Set("actual_start_time", Empty);
466 fields1->Set("actual_start_time_usec", Empty);
467 fields1->Set("is_in_effect", Empty);
468 fields1->Set("trigger_time", DbValue::FromTimestamp(downtime->GetTriggerTime()));
469 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
471 String node = IcingaApplication::GetInstance()->GetNodeName();
473 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
475 fields1->Set("endpoint_object_id", endpoint);
480 query1.Table = "scheduleddowntime";
482 query1.Table = "downtimehistory";
484 query1.Type = DbQueryInsert;
485 query1.Category = DbCatDowntime;
486 query1.Fields = fields1;
487 DbObject::OnQuery(query1);
490 void DbEvents::RemoveDowntimes(const Checkable::Ptr& checkable)
492 Log(LogDebug, "DbEvents")
493 << "removing service downtimes for '" << checkable->GetName() << "'";
496 query1.Table = "scheduleddowntime";
497 query1.Type = DbQueryDelete;
498 query1.Category = DbCatDowntime;
499 query1.WhereCriteria = make_shared<Dictionary>();
500 query1.WhereCriteria->Set("object_id", checkable);
501 DbObject::OnQuery(query1);
504 void DbEvents::RemoveDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
507 Log(LogWarning, "DbEvents", "downtime does not exist. not adding it.");
511 Log(LogDebug, "DbEvents")
512 << "removing service downtime (id = " << downtime->GetLegacyId() << ") for '" << checkable->GetName() << "'";
516 query1.Table = "scheduleddowntime";
517 query1.Type = DbQueryDelete;
518 query1.Category = DbCatDowntime;
519 query1.WhereCriteria = make_shared<Dictionary>();
520 query1.WhereCriteria->Set("object_id", checkable);
521 query1.WhereCriteria->Set("internal_downtime_id", downtime->GetLegacyId());
522 DbObject::OnQuery(query1);
524 /* History - update actual_end_time, was_cancelled for service (and host in case) */
525 double now = Utility::GetTime();
526 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
529 query3.Table = "downtimehistory";
530 query3.Type = DbQueryUpdate;
531 query3.Category = DbCatDowntime;
533 Dictionary::Ptr fields3 = make_shared<Dictionary>();
534 fields3->Set("was_cancelled", downtime->GetWasCancelled() ? 1 : 0);
535 fields3->Set("actual_end_time", DbValue::FromTimestamp(time_bag.first));
536 fields3->Set("actual_end_time_usec", time_bag.second);
537 query3.Fields = fields3;
539 query3.WhereCriteria = make_shared<Dictionary>();
540 query3.WhereCriteria->Set("internal_downtime_id", downtime->GetLegacyId());
541 query3.WhereCriteria->Set("entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()));
542 query3.WhereCriteria->Set("scheduled_start_time", DbValue::FromTimestamp(downtime->GetStartTime()));
543 query3.WhereCriteria->Set("scheduled_end_time", DbValue::FromTimestamp(downtime->GetEndTime()));
544 query3.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
546 DbObject::OnQuery(query3);
549 void DbEvents::TriggerDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
552 Log(LogWarning, "DbEvents", "downtime does not exist. not updating it.");
556 Log(LogDebug, "DbEvents")
557 << "updating triggered service downtime (id = " << downtime->GetLegacyId() << ") for '" << checkable->GetName() << "'";
559 double now = Utility::GetTime();
560 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
564 query1.Table = "scheduleddowntime";
565 query1.Type = DbQueryUpdate;
566 query1.Category = DbCatDowntime;
568 Dictionary::Ptr fields1 = make_shared<Dictionary>();
569 fields1->Set("was_started", 1);
570 fields1->Set("actual_start_time", DbValue::FromTimestamp(time_bag.first));
571 fields1->Set("actual_start_time_usec", time_bag.second);
572 fields1->Set("is_in_effect", 1);
573 fields1->Set("trigger_time", DbValue::FromTimestamp(downtime->GetTriggerTime()));
574 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
576 query1.WhereCriteria = make_shared<Dictionary>();
577 query1.WhereCriteria->Set("object_id", checkable);
578 query1.WhereCriteria->Set("internal_downtime_id", downtime->GetLegacyId());
580 query1.Fields = fields1;
581 DbObject::OnQuery(query1);
583 /* History - downtime was started for service (and host in case) */
585 query3.Table = "downtimehistory";
586 query3.Type = DbQueryUpdate;
587 query3.Category = DbCatDowntime;
589 Dictionary::Ptr fields3 = make_shared<Dictionary>();
590 fields3->Set("was_started", 1);
591 fields3->Set("is_in_effect", 1);
592 fields3->Set("actual_start_time", DbValue::FromTimestamp(time_bag.first));
593 fields3->Set("actual_start_time_usec", time_bag.second);
594 fields3->Set("trigger_time", DbValue::FromTimestamp(downtime->GetTriggerTime()));
595 query3.Fields = fields3;
597 query3.WhereCriteria = make_shared<Dictionary>();
598 query3.WhereCriteria->Set("internal_downtime_id", downtime->GetLegacyId());
599 query3.WhereCriteria->Set("entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()));
600 query3.WhereCriteria->Set("scheduled_start_time", DbValue::FromTimestamp(downtime->GetStartTime()));
601 query3.WhereCriteria->Set("scheduled_end_time", DbValue::FromTimestamp(downtime->GetEndTime()));
602 query3.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
604 DbObject::OnQuery(query3);
606 /* host/service status */
608 Service::Ptr service;
609 tie(host, service) = GetHostService(checkable);
613 query4.Table = "servicestatus";
615 query4.Table = "hoststatus";
617 query4.Type = DbQueryUpdate;
619 Dictionary::Ptr fields4 = make_shared<Dictionary>();
620 fields4->Set("scheduled_downtime_depth", checkable->GetDowntimeDepth());
622 query4.Fields = fields4;
624 query4.WhereCriteria = make_shared<Dictionary>();
626 query4.WhereCriteria->Set("service_object_id", service);
628 query4.WhereCriteria->Set("host_object_id", host);
630 query4.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
632 DbObject::OnQuery(query4);
635 /* acknowledgements */
636 void DbEvents::AddAcknowledgementHistory(const Checkable::Ptr& checkable, const String& author, const String& comment,
637 AcknowledgementType type, double expiry)
639 Log(LogDebug, "DbEvents")
640 << "add acknowledgement history for '" << checkable->GetName() << "'";
642 double now = Utility::GetTime();
643 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
645 unsigned long end_time = static_cast<long>(expiry);
648 query1.Table = "acknowledgements";
649 query1.Type = DbQueryInsert;
650 query1.Category = DbCatAcknowledgement;
653 Service::Ptr service;
654 tie(host, service) = GetHostService(checkable);
656 Dictionary::Ptr fields1 = make_shared<Dictionary>();
657 fields1->Set("entry_time", DbValue::FromTimestamp(time_bag.first));
658 fields1->Set("entry_time_usec", time_bag.second);
659 fields1->Set("acknowledgement_type", type);
660 fields1->Set("object_id", checkable);
661 fields1->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
662 fields1->Set("author_name", author);
663 fields1->Set("comment_data", comment);
664 fields1->Set("is_sticky", type == AcknowledgementSticky ? 1 : 0);
665 fields1->Set("end_time", DbValue::FromTimestamp(end_time));
666 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
668 String node = IcingaApplication::GetInstance()->GetNodeName();
670 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
672 fields1->Set("endpoint_object_id", endpoint);
674 query1.Fields = fields1;
675 DbObject::OnQuery(query1);
678 void DbEvents::AddAcknowledgement(const Checkable::Ptr& checkable, AcknowledgementType type)
680 Log(LogDebug, "DbEvents")
681 << "add acknowledgement for '" << checkable->GetName() << "'";
683 AddAcknowledgementInternal(checkable, type, true);
686 void DbEvents::RemoveAcknowledgement(const Checkable::Ptr& checkable)
688 Log(LogDebug, "DbEvents")
689 << "remove acknowledgement for '" << checkable->GetName() << "'";
691 AddAcknowledgementInternal(checkable, AcknowledgementNone, false);
694 void DbEvents::AddAcknowledgementInternal(const Checkable::Ptr& checkable, AcknowledgementType type, bool add)
697 Service::Ptr service;
698 tie(host, service) = GetHostService(checkable);
702 query1.Table = "servicestatus";
704 query1.Table = "hoststatus";
706 query1.Type = DbQueryUpdate;
707 query1.Category = DbCatAcknowledgement;
709 Dictionary::Ptr fields1 = make_shared<Dictionary>();
710 fields1->Set("acknowledgement_type", type);
711 fields1->Set("problem_has_been_acknowledged", add ? 1 : 0);
712 query1.Fields = fields1;
714 query1.WhereCriteria = make_shared<Dictionary>();
716 query1.WhereCriteria->Set("service_object_id", service);
718 query1.WhereCriteria->Set("host_object_id", host);
720 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
722 DbObject::OnQuery(query1);
726 void DbEvents::AddNotificationHistory(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users, NotificationType type,
727 const CheckResult::Ptr& cr, const String& author, const String& text)
729 Log(LogDebug, "DbEvents")
730 << "add notification history for '" << checkable->GetName() << "'";
732 /* start and end happen at the same time */
733 double now = Utility::GetTime();
734 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
737 query1.Table = "notifications";
738 query1.Type = DbQueryInsert;
739 query1.Category = DbCatNotification;
740 /* store the object ptr for caching the insert id for this object */
741 query1.NotificationObject = notification;
744 Service::Ptr service;
745 tie(host, service) = GetHostService(checkable);
747 Dictionary::Ptr fields1 = make_shared<Dictionary>();
748 fields1->Set("notification_type", 1); /* service */
749 fields1->Set("notification_reason", CompatUtility::MapNotificationReasonType(type));
750 fields1->Set("object_id", checkable);
751 fields1->Set("start_time", DbValue::FromTimestamp(time_bag.first));
752 fields1->Set("start_time_usec", time_bag.second);
753 fields1->Set("end_time", DbValue::FromTimestamp(time_bag.first));
754 fields1->Set("end_time_usec", time_bag.second);
755 fields1->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
758 fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
759 fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
762 fields1->Set("escalated", 0);
763 fields1->Set("contacts_notified", static_cast<long>(users.size()));
764 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
766 String node = IcingaApplication::GetInstance()->GetNodeName();
768 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
770 fields1->Set("endpoint_object_id", endpoint);
772 query1.Fields = fields1;
773 DbObject::OnQuery(query1);
776 query2.Table = "contactnotifications";
777 query2.Type = DbQueryInsert;
778 query2.Category = DbCatNotification;
781 BOOST_FOREACH(const User::Ptr& user, users) {
782 Log(LogDebug, "DbEvents")
783 << "add contact notification history for service '" << checkable->GetName() << "' and user '" << user->GetName() << "'.";
785 Dictionary::Ptr fields2 = make_shared<Dictionary>();
786 fields2->Set("contact_object_id", user);
787 fields2->Set("start_time", DbValue::FromTimestamp(time_bag.first));
788 fields2->Set("start_time_usec", time_bag.second);
789 fields2->Set("end_time", DbValue::FromTimestamp(time_bag.first));
790 fields2->Set("end_time_usec", time_bag.second);
792 fields2->Set("notification_id", notification); /* DbConnection class fills in real ID from notification insert id cache */
793 fields2->Set("instance_id", 0); /* DbConnection class fills in real ID */
795 query2.Fields = fields2;
796 DbObject::OnQuery(query2);
801 void DbEvents::AddStateChangeHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, StateType type)
803 Log(LogDebug, "DbEvents")
804 << "add state change history for '" << checkable->GetName() << "'";
806 double now = Utility::GetTime();
807 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
810 query1.Table = "statehistory";
811 query1.Type = DbQueryInsert;
812 query1.Category = DbCatStateHistory;
815 Service::Ptr service;
816 tie(host, service) = GetHostService(checkable);
818 Dictionary::Ptr fields1 = make_shared<Dictionary>();
819 fields1->Set("state_time", DbValue::FromTimestamp(time_bag.first));
820 fields1->Set("state_time_usec", time_bag.second);
821 fields1->Set("object_id", checkable);
822 fields1->Set("state_change", 1); /* service */
823 fields1->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
824 fields1->Set("state_type", checkable->GetStateType());
825 fields1->Set("current_check_attempt", checkable->GetCheckAttempt());
826 fields1->Set("max_check_attempts", checkable->GetMaxCheckAttempts());
829 fields1->Set("last_state", service->GetLastState());
830 fields1->Set("last_hard_state", service->GetLastHardState());
832 fields1->Set("last_state", host->GetLastState());
833 fields1->Set("last_hard_state", host->GetLastHardState());
837 fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
838 fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
839 fields1->Set("check_source", cr->GetCheckSource());
842 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
844 String node = IcingaApplication::GetInstance()->GetNodeName();
846 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
848 fields1->Set("endpoint_object_id", endpoint);
850 query1.Fields = fields1;
851 DbObject::OnQuery(query1);
855 void DbEvents::AddCheckResultLogHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr &cr)
857 Dictionary::Ptr vars_after = cr->GetVarsAfter();
859 long state_after = vars_after->Get("state");
860 long stateType_after = vars_after->Get("state_type");
861 long attempt_after = vars_after->Get("attempt");
862 bool reachable_after = vars_after->Get("reachable");
864 Dictionary::Ptr vars_before = cr->GetVarsBefore();
867 long state_before = vars_before->Get("state");
868 long stateType_before = vars_before->Get("state_type");
869 long attempt_before = vars_before->Get("attempt");
870 bool reachable_before = vars_before->Get("reachable");
872 if (state_before == state_after && stateType_before == stateType_after &&
873 attempt_before == attempt_after && reachable_before == reachable_after)
874 return; /* Nothing changed, ignore this checkresult. */
881 output = CompatUtility::GetCheckResultOutput(cr);
884 Service::Ptr service;
885 tie(host, service) = GetHostService(checkable);
887 std::ostringstream msgbuf;
890 msgbuf << "SERVICE ALERT: "
891 << host->GetName() << ";"
892 << service->GetShortName() << ";"
893 << Service::StateToString(static_cast<ServiceState>(state_after)) << ";"
894 << Service::StateTypeToString(static_cast<StateType>(stateType_after)) << ";"
895 << attempt_after << ";"
899 switch (service->GetState()) {
901 type = LogEntryTypeServiceOk;
904 type = LogEntryTypeServiceUnknown;
907 type = LogEntryTypeServiceWarning;
909 case ServiceCritical:
910 type = LogEntryTypeServiceCritical;
913 Log(LogCritical, "DbEvents")
914 << "Unknown service state: " << state_after;
918 String state = Host::StateToString(Host::CalculateState(static_cast<ServiceState>(state_after)));
920 if (!reachable_after)
921 state = "UNREACHABLE";
923 msgbuf << "HOST ALERT: "
924 << host->GetName() << ";"
926 << Service::StateTypeToString(static_cast<StateType>(stateType_after)) << ";"
927 << attempt_after << ";"
931 switch (host->GetState()) {
933 type = LogEntryTypeHostUp;
936 type = LogEntryTypeHostDown;
939 Log(LogCritical, "DbEvents")
940 << "Unknown host state: " << state_after;
944 if (!reachable_after)
945 type = LogEntryTypeHostUnreachable;
948 AddLogHistory(checkable, msgbuf.str(), type);
951 void DbEvents::AddTriggerDowntimeLogHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
957 Service::Ptr service;
958 tie(host, service) = GetHostService(checkable);
960 std::ostringstream msgbuf;
963 msgbuf << "SERVICE DOWNTIME ALERT: "
964 << host->GetName() << ";"
965 << service->GetShortName() << ";"
967 << "Service has entered a period of scheduled downtime."
970 msgbuf << "HOST DOWNTIME ALERT: "
971 << host->GetName() << ";"
973 << "Service has entered a period of scheduled downtime."
977 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
980 void DbEvents::AddRemoveDowntimeLogHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
985 String downtime_output;
986 String downtime_state_str;
988 if (downtime->GetWasCancelled()) {
989 downtime_output = "Scheduled downtime for service has been cancelled.";
990 downtime_state_str = "CANCELLED";
992 downtime_output = "Service has exited from a period of scheduled downtime.";
993 downtime_state_str = "STOPPED";
997 Service::Ptr service;
998 tie(host, service) = GetHostService(checkable);
1000 std::ostringstream msgbuf;
1003 msgbuf << "SERVICE DOWNTIME ALERT: "
1004 << host->GetName() << ";"
1005 << service->GetShortName() << ";"
1006 << downtime_state_str << "; "
1010 msgbuf << "HOST DOWNTIME ALERT: "
1011 << host->GetName() << ";"
1012 << downtime_state_str << "; "
1017 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1020 void DbEvents::AddNotificationSentLogHistory(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const User::Ptr& user,
1021 NotificationType notification_type, const CheckResult::Ptr& cr,
1022 const String& author, const String& comment_text)
1024 CheckCommand::Ptr commandObj = checkable->GetCheckCommand();
1026 String check_command = "";
1028 check_command = commandObj->GetName();
1030 String notification_type_str = Notification::NotificationTypeToString(notification_type);
1032 String author_comment = "";
1033 if (notification_type == NotificationCustom || notification_type == NotificationAcknowledgement) {
1034 author_comment = ";" + author + ";" + comment_text;
1043 output = CompatUtility::GetCheckResultOutput(cr);
1046 Service::Ptr service;
1047 tie(host, service) = GetHostService(checkable);
1049 std::ostringstream msgbuf;
1052 msgbuf << "SERVICE NOTIFICATION: "
1053 << user->GetName() << ";"
1054 << host->GetName() << ";"
1055 << service->GetShortName() << ";"
1056 << notification_type_str << " "
1057 << "(" << Service::StateToString(service->GetState()) << ");"
1058 << check_command << ";"
1059 << output << author_comment
1062 msgbuf << "HOST NOTIFICATION: "
1063 << user->GetName() << ";"
1064 << host->GetName() << ";"
1065 << notification_type_str << " "
1066 << "(" << Host::StateToString(host->GetState()) << ");"
1067 << check_command << ";"
1068 << output << author_comment
1072 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeHostNotification);
1075 void DbEvents::AddFlappingLogHistory(const Checkable::Ptr& checkable, FlappingState flapping_state)
1077 String flapping_state_str;
1078 String flapping_output;
1080 switch (flapping_state) {
1081 case FlappingStarted:
1082 flapping_output = "Service appears to have started flapping (" + Convert::ToString(checkable->GetFlappingCurrent()) + "% change >= " + Convert::ToString(checkable->GetFlappingThreshold()) + "% threshold)";
1083 flapping_state_str = "STARTED";
1085 case FlappingStopped:
1086 flapping_output = "Service appears to have stopped flapping (" + Convert::ToString(checkable->GetFlappingCurrent()) + "% change < " + Convert::ToString(checkable->GetFlappingThreshold()) + "% threshold)";
1087 flapping_state_str = "STOPPED";
1089 case FlappingDisabled:
1090 flapping_output = "Flap detection has been disabled";
1091 flapping_state_str = "DISABLED";
1094 Log(LogCritical, "DbEvents")
1095 << "Unknown flapping state: " << flapping_state;
1100 Service::Ptr service;
1101 tie(host, service) = GetHostService(checkable);
1103 std::ostringstream msgbuf;
1106 msgbuf << "SERVICE FLAPPING ALERT: "
1107 << host->GetName() << ";"
1108 << service->GetShortName() << ";"
1109 << flapping_state_str << "; "
1113 msgbuf << "HOST FLAPPING ALERT: "
1114 << host->GetName() << ";"
1115 << flapping_state_str << "; "
1120 AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1123 void DbEvents::AddLogHistory(const Checkable::Ptr& checkable, String buffer, LogEntryType type)
1125 Log(LogDebug, "DbEvents")
1126 << "add log entry history for '" << checkable->GetName() << "'";
1128 double now = Utility::GetTime();
1129 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
1132 query1.Table = "logentries";
1133 query1.Type = DbQueryInsert;
1134 query1.Category = DbCatLog;
1136 Dictionary::Ptr fields1 = make_shared<Dictionary>();
1137 fields1->Set("logentry_time", DbValue::FromTimestamp(time_bag.first));
1138 fields1->Set("entry_time", DbValue::FromTimestamp(time_bag.first));
1139 fields1->Set("entry_time_usec", time_bag.second);
1140 fields1->Set("object_id", checkable); // added in 1.10 see #4754
1141 fields1->Set("logentry_type", type);
1142 fields1->Set("logentry_data", buffer);
1144 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1146 String node = IcingaApplication::GetInstance()->GetNodeName();
1148 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
1150 fields1->Set("endpoint_object_id", endpoint);
1152 query1.Fields = fields1;
1153 DbObject::OnQuery(query1);
1156 /* flappinghistory */
1157 void DbEvents::AddFlappingHistory(const Checkable::Ptr& checkable, FlappingState flapping_state)
1159 Log(LogDebug, "DbEvents")
1160 << "add flapping history for '" << checkable->GetName() << "'";
1162 double now = Utility::GetTime();
1163 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
1166 query1.Table = "flappinghistory";
1167 query1.Type = DbQueryInsert;
1168 query1.Category = DbCatFlapping;
1170 Dictionary::Ptr fields1 = make_shared<Dictionary>();
1172 fields1->Set("event_time", DbValue::FromTimestamp(time_bag.first));
1173 fields1->Set("event_time_usec", time_bag.second);
1175 switch (flapping_state) {
1176 case FlappingStarted:
1177 fields1->Set("event_type", 1000);
1179 case FlappingStopped:
1180 fields1->Set("event_type", 1001);
1181 fields1->Set("reason_type", 1);
1183 case FlappingDisabled:
1184 fields1->Set("event_type", 1001);
1185 fields1->Set("reason_type", 2);
1188 Log(LogDebug, "DbEvents")
1189 << "Unhandled flapping state: " << flapping_state;
1194 Service::Ptr service;
1195 tie(host, service) = GetHostService(checkable);
1197 fields1->Set("flapping_type", service ? 1 : 0);
1198 fields1->Set("object_id", checkable);
1199 fields1->Set("percent_state_change", checkable->GetFlappingCurrent());
1200 fields1->Set("low_threshold", checkable->GetFlappingThreshold());
1201 fields1->Set("high_threshold", checkable->GetFlappingThreshold());
1203 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1205 String node = IcingaApplication::GetInstance()->GetNodeName();
1207 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
1209 fields1->Set("endpoint_object_id", endpoint);
1211 query1.Fields = fields1;
1212 DbObject::OnQuery(query1);
1216 void DbEvents::AddServiceCheckHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr &cr)
1221 Log(LogDebug, "DbEvents")
1222 << "add service check history for '" << checkable->GetName() << "'";
1225 Service::Ptr service;
1226 tie(host, service) = GetHostService(checkable);
1228 std::ostringstream msgbuf;
1231 query1.Table = service ? "servicechecks" : "hostchecks";
1232 query1.Type = DbQueryInsert;
1233 query1.Category = DbCatCheck;
1235 Dictionary::Ptr fields1 = make_shared<Dictionary>();
1236 double execution_time = Service::CalculateExecutionTime(cr);
1238 fields1->Set("check_type", CompatUtility::GetCheckableCheckType(checkable));
1239 fields1->Set("current_check_attempt", checkable->GetCheckAttempt());
1240 fields1->Set("max_check_attempts", checkable->GetMaxCheckAttempts());
1241 fields1->Set("state_type", checkable->GetStateType());
1243 double now = Utility::GetTime();
1244 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
1246 double end = now + execution_time;
1247 std::pair<unsigned long, unsigned long> time_bag_end = CompatUtility::ConvertTimestamp(end);
1249 fields1->Set("start_time", DbValue::FromTimestamp(time_bag.first));
1250 fields1->Set("start_time_usec", time_bag.second);
1251 fields1->Set("end_time", DbValue::FromTimestamp(time_bag_end.first));
1252 fields1->Set("end_time_usec", time_bag_end.second);
1253 fields1->Set("command_object_id", checkable->GetCheckCommand());
1254 fields1->Set("command_args", Empty);
1255 fields1->Set("command_line", cr->GetCommand());
1256 fields1->Set("execution_time", Convert::ToString(execution_time));
1257 fields1->Set("latency", Convert::ToString(Service::CalculateLatency(cr)));
1258 fields1->Set("return_code", cr->GetExitStatus());
1259 fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
1260 fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
1261 fields1->Set("perfdata", CompatUtility::GetCheckResultPerfdata(cr));
1263 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1266 fields1->Set("service_object_id", service);
1267 fields1->Set("state", service->GetState());
1269 fields1->Set("host_object_id", host);
1270 fields1->Set("state", host->GetState());
1273 String node = IcingaApplication::GetInstance()->GetNodeName();
1275 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
1277 fields1->Set("endpoint_object_id", endpoint);
1279 query1.Fields = fields1;
1280 DbObject::OnQuery(query1);
1284 void DbEvents::AddEventHandlerHistory(const Checkable::Ptr& checkable)
1286 Log(LogDebug, "DbEvents")
1287 << "add eventhandler history for '" << checkable->GetName() << "'";
1289 double now = Utility::GetTime();
1290 std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
1293 query1.Table = "eventhandlers";
1294 query1.Type = DbQueryInsert;
1295 query1.Category = DbCatEventHandler;
1297 Dictionary::Ptr fields1 = make_shared<Dictionary>();
1300 Service::Ptr service;
1301 tie(host, service) = GetHostService(checkable);
1303 fields1->Set("eventhandler_type", service ? 1 : 0);
1304 fields1->Set("object_id", checkable);
1305 fields1->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
1306 fields1->Set("state_type", checkable->GetStateType());
1308 fields1->Set("start_time", DbValue::FromTimestamp(time_bag.first));
1309 fields1->Set("start_time_usec", time_bag.second);
1310 fields1->Set("end_time", DbValue::FromTimestamp(time_bag.first));
1311 fields1->Set("end_time_usec", time_bag.second);
1312 fields1->Set("command_object_id", checkable->GetEventCommand());
1314 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1316 String node = IcingaApplication::GetInstance()->GetNodeName();
1318 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
1320 fields1->Set("endpoint_object_id", endpoint);
1322 query1.Fields = fields1;
1323 DbObject::OnQuery(query1);
1326 /* externalcommands */
1327 void DbEvents::AddExternalCommandHistory(double time, const String& command, const std::vector<String>& arguments)
1329 Log(LogDebug, "DbEvents", "add external command history");
1332 query1.Table = "externalcommands";
1333 query1.Type = DbQueryInsert;
1334 query1.Category = DbCatExternalCommand;
1336 Dictionary::Ptr fields1 = make_shared<Dictionary>();
1338 fields1->Set("entry_time", DbValue::FromTimestamp(static_cast<long>(time)));
1339 fields1->Set("command_type", CompatUtility::MapExternalCommandType(command));
1340 fields1->Set("command_name", command);
1341 fields1->Set("command_args", boost::algorithm::join(arguments, ";"));
1343 fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1345 String node = IcingaApplication::GetInstance()->GetNodeName();
1347 Endpoint::Ptr endpoint = Endpoint::GetByName(node);
1349 fields1->Set("endpoint_object_id", endpoint);
1351 query1.Fields = fields1;
1352 DbObject::OnQuery(query1);