]> granicus.if.org Git - icinga2/blob - lib/db_ido/dbevents.cpp
Merge pull request #7124 from Icinga/bugfix/namespace-thread-safe
[icinga2] / lib / db_ido / dbevents.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
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>
21
22 using namespace icinga;
23
24 INITIALIZE_ONCE(&DbEvents::StaticInitialize);
25
26 void DbEvents::StaticInitialize()
27 {
28         /* Status */
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));
36
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));
40
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));
46
47         Checkable::OnReachabilityChanged.connect(std::bind(&DbEvents::ReachabilityChangedHandler, _1, _2, _3));
48
49         /* History */
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));
53
54         Checkable::OnNotificationSentToAllUsers.connect(std::bind(&DbEvents::AddNotificationHistory, _1, _2, _3, _4, _5, _6, _7));
55
56         Checkable::OnStateChange.connect(std::bind(&DbEvents::AddStateChangeHistory, _1, _2, _3));
57
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));
64
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));
68
69         Checkable::OnEventCommandExecuted.connect(std::bind(&DbEvents::AddEventHandlerHistory, _1));
70
71         ExternalCommandProcessor::OnNewExternalCommand.connect(std::bind(&DbEvents::AddExternalCommandHistory, _1, _2, _3));
72 }
73
74 /* check events */
75 void DbEvents::NextCheckUpdatedHandler(const Checkable::Ptr& checkable)
76 {
77         Host::Ptr host;
78         Service::Ptr service;
79         tie(host, service) = GetHostService(checkable);
80
81         DbQuery query1;
82         query1.WhereCriteria = new Dictionary();
83
84         if (service) {
85                 query1.Table = "servicestatus";
86                 query1.WhereCriteria->Set("service_object_id", service);
87         } else {
88                 query1.Table = "hoststatus";
89                 query1.WhereCriteria->Set("host_object_id", host);
90         }
91
92         query1.Type = DbQueryUpdate;
93         query1.Category = DbCatState;
94         query1.StatusUpdate = true;
95         query1.Object = DbObject::GetOrCreateByObject(checkable);
96
97         query1.Fields = new Dictionary({
98                 { "next_check", DbValue::FromTimestamp(checkable->GetNextCheck()) }
99         });
100
101         DbObject::OnQuery(query1);
102 }
103
104 void DbEvents::FlappingChangedHandler(const Checkable::Ptr& checkable)
105 {
106         Host::Ptr host;
107         Service::Ptr service;
108         tie(host, service) = GetHostService(checkable);
109
110         DbQuery query1;
111         query1.WhereCriteria = new Dictionary();
112
113         if (service) {
114                 query1.Table = "servicestatus";
115                 query1.WhereCriteria->Set("service_object_id", service);
116         } else {
117                 query1.Table = "hoststatus";
118                 query1.WhereCriteria->Set("host_object_id", host);
119         }
120
121         query1.Type = DbQueryUpdate;
122         query1.Category = DbCatState;
123         query1.StatusUpdate = true;
124         query1.Object = DbObject::GetOrCreateByObject(checkable);
125
126         Dictionary::Ptr fields1 = new Dictionary();
127         fields1->Set("is_flapping", checkable->IsFlapping());
128         fields1->Set("percent_state_change", checkable->GetFlappingCurrent());
129
130         query1.Fields = new Dictionary({
131                 { "is_flapping", checkable->IsFlapping() },
132                 { "percent_state_change", checkable->GetFlappingCurrent() }
133         });
134
135         query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
136
137         DbObject::OnQuery(query1);
138 }
139
140 void DbEvents::LastNotificationChangedHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable)
141 {
142         std::pair<unsigned long, unsigned long> now_bag = ConvertTimestamp(Utility::GetTime());
143         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(notification->GetNextNotification());
144
145         Host::Ptr host;
146         Service::Ptr service;
147         tie(host, service) = GetHostService(checkable);
148
149         DbQuery query1;
150         query1.WhereCriteria = new Dictionary();
151
152         if (service) {
153                 query1.Table = "servicestatus";
154                 query1.WhereCriteria->Set("service_object_id", service);
155         } else {
156                 query1.Table = "hoststatus";
157                 query1.WhereCriteria->Set("host_object_id", host);
158         }
159
160         query1.Type = DbQueryUpdate;
161         query1.Category = DbCatState;
162         query1.StatusUpdate = true;
163         query1.Object = DbObject::GetOrCreateByObject(checkable);
164
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() }
169         });
170
171         query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
172
173         DbObject::OnQuery(query1);
174 }
175
176 void DbEvents::ReachabilityChangedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, std::set<Checkable::Ptr> children)
177 {
178         int is_reachable = 0;
179
180         if (cr->GetState() == ServiceOK)
181                 is_reachable = 1;
182
183         for (const Checkable::Ptr& child : children) {
184                 Host::Ptr host;
185                 Service::Ptr service;
186                 tie(host, service) = GetHostService(child);
187
188                 DbQuery query1;
189                 query1.WhereCriteria = new Dictionary();
190
191                 if (service) {
192                         query1.Table = "servicestatus";
193                         query1.WhereCriteria->Set("service_object_id", service);
194                 } else {
195                         query1.Table = "hoststatus";
196                         query1.WhereCriteria->Set("host_object_id", host);
197                 }
198
199                 query1.Type = DbQueryUpdate;
200                 query1.Category = DbCatState;
201                 query1.StatusUpdate = true;
202                 query1.Object = DbObject::GetOrCreateByObject(child);
203
204                 query1.Fields = new Dictionary({
205                         { "is_reachable", is_reachable }
206                 });
207
208                 query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
209
210                 DbObject::OnQuery(query1);
211         }
212 }
213
214 /* enable changed events */
215 void DbEvents::EnableActiveChecksChangedHandler(const Checkable::Ptr& checkable)
216 {
217         EnableChangedHandlerInternal(checkable, "active_checks_enabled", checkable->GetEnableActiveChecks());
218 }
219
220 void DbEvents::EnablePassiveChecksChangedHandler(const Checkable::Ptr& checkable)
221 {
222         EnableChangedHandlerInternal(checkable, "passive_checks_enabled", checkable->GetEnablePassiveChecks());
223 }
224
225 void DbEvents::EnableNotificationsChangedHandler(const Checkable::Ptr& checkable)
226 {
227         EnableChangedHandlerInternal(checkable, "notifications_enabled", checkable->GetEnableNotifications());
228 }
229
230 void DbEvents::EnablePerfdataChangedHandler(const Checkable::Ptr& checkable)
231 {
232         EnableChangedHandlerInternal(checkable, "process_performance_data", checkable->GetEnablePerfdata());
233 }
234
235 void DbEvents::EnableFlappingChangedHandler(const Checkable::Ptr& checkable)
236 {
237         EnableChangedHandlerInternal(checkable, "flap_detection_enabled", checkable->GetEnableFlapping());
238 }
239
240 void DbEvents::EnableChangedHandlerInternal(const Checkable::Ptr& checkable, const String& fieldName, bool enabled)
241 {
242         Host::Ptr host;
243         Service::Ptr service;
244         tie(host, service) = GetHostService(checkable);
245
246         DbQuery query1;
247         query1.WhereCriteria = new Dictionary();
248
249         if (service) {
250                 query1.Table = "servicestatus";
251                 query1.WhereCriteria->Set("service_object_id", service);
252         } else {
253                 query1.Table = "hoststatus";
254                 query1.WhereCriteria->Set("host_object_id", host);
255         }
256
257         query1.Type = DbQueryUpdate;
258         query1.Category = DbCatState;
259         query1.StatusUpdate = true;
260         query1.Object = DbObject::GetOrCreateByObject(checkable);
261
262         query1.Fields = new Dictionary({
263                 { fieldName, enabled }
264         });
265
266         query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
267
268         DbObject::OnQuery(query1);
269 }
270
271
272 /* comments */
273 void DbEvents::AddComments(const Checkable::Ptr& checkable)
274 {
275         std::set<Comment::Ptr> comments = checkable->GetComments();
276
277         std::vector<DbQuery> queries;
278
279         for (const Comment::Ptr& comment : comments) {
280                 AddCommentInternal(queries, comment, false);
281         }
282
283         DbObject::OnMultipleQueries(queries);
284 }
285
286 void DbEvents::AddComment(const Comment::Ptr& comment)
287 {
288         std::vector<DbQuery> queries;
289         AddCommentInternal(queries, comment, false);
290         DbObject::OnMultipleQueries(queries);
291 }
292
293 void DbEvents::AddCommentHistory(const Comment::Ptr& comment)
294 {
295         std::vector<DbQuery> queries;
296         AddCommentInternal(queries, comment, true);
297         DbObject::OnMultipleQueries(queries);
298 }
299
300 void DbEvents::AddCommentInternal(std::vector<DbQuery>& queries, const Comment::Ptr& comment, bool historical)
301 {
302         Checkable::Ptr checkable = comment->GetCheckable();
303
304         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(comment->GetEntryTime());
305
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);
311
312         int commentType = 0;
313
314         if (checkable->GetReflectionType() == Host::TypeInstance)
315                 commentType = 2;
316         else if (checkable->GetReflectionType() == Service::TypeInstance)
317                 commentType = 1;
318         else {
319                 return;
320         }
321
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 */
333
334         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
335
336         if (endpoint)
337                 fields1->Set("endpoint_object_id", endpoint);
338
339         DbQuery query1;
340
341         if (!historical) {
342                 query1.Table = "comments";
343                 query1.Type = DbQueryInsert | DbQueryUpdate;
344
345                 fields1->Set("session_token", 0); /* DbConnection class fills in real ID */
346
347                 query1.WhereCriteria = new Dictionary({
348                         { "object_id", checkable },
349                         { "name", comment->GetName() },
350                         { "entry_time", DbValue::FromTimestamp(timeBag.first) }
351                 });
352         } else {
353                 query1.Table = "commenthistory";
354                 query1.Type = DbQueryInsert;
355         }
356
357         query1.Category = DbCatComment;
358         query1.Fields = fields1;
359         queries.emplace_back(std::move(query1));
360 }
361
362 void DbEvents::RemoveComment(const Comment::Ptr& comment)
363 {
364         std::vector<DbQuery> queries;
365         RemoveCommentInternal(queries, comment);
366         DbObject::OnMultipleQueries(queries);
367 }
368
369 void DbEvents::RemoveCommentInternal(std::vector<DbQuery>& queries, const Comment::Ptr& comment)
370 {
371         Checkable::Ptr checkable = comment->GetCheckable();
372
373         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(comment->GetEntryTime());
374
375         /* Status */
376         DbQuery query1;
377         query1.Table = "comments";
378         query1.Type = DbQueryDelete;
379         query1.Category = DbCatComment;
380
381         query1.WhereCriteria = new Dictionary({
382                 { "object_id", checkable },
383                 { "entry_time", DbValue::FromTimestamp(timeBag.first) },
384                 { "name", comment->GetName() }
385         });
386
387         queries.emplace_back(std::move(query1));
388
389         /* History - update deletion time for service/host */
390         std::pair<unsigned long, unsigned long> timeBagNow = ConvertTimestamp(Utility::GetTime());
391
392         DbQuery query2;
393         query2.Table = "commenthistory";
394         query2.Type = DbQueryUpdate;
395         query2.Category = DbCatComment;
396
397         query2.Fields = new Dictionary({
398                 { "deletion_time", DbValue::FromTimestamp(timeBagNow.first) },
399                 { "deletion_time_usec", timeBagNow.second }
400         });
401
402         query2.WhereCriteria = new Dictionary({
403                 { "object_id", checkable },
404                 { "entry_time", DbValue::FromTimestamp(timeBag.first) },
405                 { "name", comment->GetName() }
406         });
407
408         queries.emplace_back(std::move(query2));
409 }
410
411 /* downtimes */
412 void DbEvents::AddDowntimes(const Checkable::Ptr& checkable)
413 {
414         std::set<Downtime::Ptr> downtimes = checkable->GetDowntimes();
415
416         std::vector<DbQuery> queries;
417
418         for (const Downtime::Ptr& downtime : downtimes) {
419                 AddDowntimeInternal(queries, downtime, false);
420         }
421
422         DbObject::OnMultipleQueries(queries);
423 }
424
425 void DbEvents::AddDowntime(const Downtime::Ptr& downtime)
426 {
427         std::vector<DbQuery> queries;
428         AddDowntimeInternal(queries, downtime, false);
429         DbObject::OnMultipleQueries(queries);
430 }
431
432 void DbEvents::AddDowntimeHistory(const Downtime::Ptr& downtime)
433 {
434         std::vector<DbQuery> queries;
435         AddDowntimeInternal(queries, downtime, true);
436         DbObject::OnMultipleQueries(queries);
437 }
438
439 void DbEvents::AddDowntimeInternal(std::vector<DbQuery>& queries, const Downtime::Ptr& downtime, bool historical)
440 {
441         Checkable::Ptr checkable = downtime->GetCheckable();
442
443         Dictionary::Ptr fields1 = new Dictionary();
444         fields1->Set("entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()));
445         fields1->Set("object_id", checkable);
446
447         int downtimeType = 0;
448
449         if (checkable->GetReflectionType() == Host::TypeInstance)
450                 downtimeType = 2;
451         else if (checkable->GetReflectionType() == Service::TypeInstance)
452                 downtimeType = 1;
453         else {
454                 return;
455         }
456
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());
467
468         /* flexible downtimes are started at trigger time */
469         if (downtime->GetFixed()) {
470                 std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(downtime->GetStartTime());
471
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));
475         }
476
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 */
480
481         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
482
483         if (endpoint)
484                 fields1->Set("endpoint_object_id", endpoint);
485
486         DbQuery query1;
487
488         if (!historical) {
489                 query1.Table = "scheduleddowntime";
490                 query1.Type = DbQueryInsert | DbQueryUpdate;
491
492                 fields1->Set("session_token", 0); /* DbConnection class fills in real ID */
493
494                 query1.WhereCriteria = new Dictionary({
495                         { "object_id", checkable },
496                         { "name", downtime->GetName() },
497                         { "entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()) }
498                 });
499         } else {
500                 query1.Table = "downtimehistory";
501                 query1.Type = DbQueryInsert;
502         }
503
504         query1.Category = DbCatDowntime;
505         query1.Fields = fields1;
506         queries.emplace_back(std::move(query1));
507
508         /* host/service status */
509         if (!historical) {
510                 Host::Ptr host;
511                 Service::Ptr service;
512                 tie(host, service) = GetHostService(checkable);
513
514                 DbQuery query2;
515                 query2.WhereCriteria = new Dictionary();
516
517                 if (service) {
518                         query2.Table = "servicestatus";
519                         query2.WhereCriteria->Set("service_object_id", service);
520                 } else {
521                         query2.Table = "hoststatus";
522                         query2.WhereCriteria->Set("host_object_id", host);
523                 }
524
525                 query2.Type = DbQueryUpdate;
526                 query2.Category = DbCatState;
527                 query2.StatusUpdate = true;
528                 query2.Object = DbObject::GetOrCreateByObject(checkable);
529
530                 Dictionary::Ptr fields2 = new Dictionary();
531                 fields2->Set("scheduled_downtime_depth", checkable->GetDowntimeDepth());
532
533                 query2.Fields = fields2;
534                 query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
535
536                 queries.emplace_back(std::move(query2));
537         }
538 }
539
540 void DbEvents::RemoveDowntime(const Downtime::Ptr& downtime)
541 {
542         std::vector<DbQuery> queries;
543         RemoveDowntimeInternal(queries, downtime);
544         DbObject::OnMultipleQueries(queries);
545 }
546
547 void DbEvents::RemoveDowntimeInternal(std::vector<DbQuery>& queries, const Downtime::Ptr& downtime)
548 {
549         Checkable::Ptr checkable = downtime->GetCheckable();
550
551         /* Status */
552         DbQuery query1;
553         query1.Table = "scheduleddowntime";
554         query1.Type = DbQueryDelete;
555         query1.Category = DbCatDowntime;
556         query1.WhereCriteria = new Dictionary();
557
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));
565
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());
568
569         DbQuery query3;
570         query3.Table = "downtimehistory";
571         query3.Type = DbQueryUpdate;
572         query3.Category = DbCatDowntime;
573
574         Dictionary::Ptr fields3 = new Dictionary();
575         fields3->Set("was_cancelled", downtime->GetWasCancelled() ? 1 : 0);
576
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);
580         }
581
582         fields3->Set("is_in_effect", 0);
583         query3.Fields = fields3;
584
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() }
592         });
593
594         queries.emplace_back(std::move(query3));
595
596         /* host/service status */
597         Host::Ptr host;
598         Service::Ptr service;
599         tie(host, service) = GetHostService(checkable);
600
601         DbQuery query4;
602         query4.WhereCriteria = new Dictionary();
603
604         if (service) {
605                 query4.Table = "servicestatus";
606                 query4.WhereCriteria->Set("service_object_id", service);
607         } else {
608                 query4.Table = "hoststatus";
609                 query4.WhereCriteria->Set("host_object_id", host);
610         }
611
612         query4.Type = DbQueryUpdate;
613         query4.Category = DbCatState;
614         query4.StatusUpdate = true;
615         query4.Object = DbObject::GetOrCreateByObject(checkable);
616
617         Dictionary::Ptr fields4 = new Dictionary();
618         fields4->Set("scheduled_downtime_depth", checkable->GetDowntimeDepth());
619
620         query4.Fields = fields4;
621         query4.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
622
623         queries.emplace_back(std::move(query4));
624 }
625
626 void DbEvents::TriggerDowntime(const Downtime::Ptr& downtime)
627 {
628         Checkable::Ptr checkable = downtime->GetCheckable();
629
630         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
631
632         /* Status */
633         DbQuery query1;
634         query1.Table = "scheduleddowntime";
635         query1.Type = DbQueryUpdate;
636         query1.Category = DbCatDowntime;
637
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 */
645         });
646
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() }
654         });
655
656         DbObject::OnQuery(query1);
657
658         /* History - downtime was started for service (and host in case) */
659         DbQuery query3;
660         query3.Table = "downtimehistory";
661         query3.Type = DbQueryUpdate;
662         query3.Category = DbCatDowntime;
663
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()) }
670         });
671
672         query3.WhereCriteria = query1.WhereCriteria;
673
674         DbObject::OnQuery(query3);
675
676         /* host/service status */
677         Host::Ptr host;
678         Service::Ptr service;
679         tie(host, service) = GetHostService(checkable);
680
681         DbQuery query4;
682         query4.WhereCriteria = new Dictionary();
683
684         if (service) {
685                 query4.Table = "servicestatus";
686                 query4.WhereCriteria->Set("service_object_id", service);
687         } else {
688                 query4.Table = "hoststatus";
689                 query4.WhereCriteria->Set("host_object_id", host);
690         }
691
692         query4.Type = DbQueryUpdate;
693         query4.Category = DbCatState;
694         query4.StatusUpdate = true;
695         query4.Object = DbObject::GetOrCreateByObject(checkable);
696
697         query4.Fields = new Dictionary({
698                 { "scheduled_downtime_depth", checkable->GetDowntimeDepth() }
699         });
700         query4.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
701
702         DbObject::OnQuery(query4);
703 }
704
705 /* acknowledgements */
706 void DbEvents::AddAcknowledgementHistory(const Checkable::Ptr& checkable, const String& author, const String& comment,
707         AcknowledgementType type, bool notify, double expiry)
708 {
709         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
710
711         DbQuery query1;
712         query1.Table = "acknowledgements";
713         query1.Type = DbQueryInsert;
714         query1.Category = DbCatAcknowledgement;
715
716         Host::Ptr host;
717         Service::Ptr service;
718         tie(host, service) = GetHostService(checkable);
719
720         Dictionary::Ptr fields1 = new Dictionary();
721
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 */
733
734         if (service)
735                 fields1->Set("state", service->GetState());
736         else
737                 fields1->Set("state", GetHostState(host));
738
739         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
740
741         if (endpoint)
742                 fields1->Set("endpoint_object_id", endpoint);
743
744         query1.Fields = fields1;
745         DbObject::OnQuery(query1);
746 }
747
748 void DbEvents::AddAcknowledgement(const Checkable::Ptr& checkable, AcknowledgementType type)
749 {
750         AddAcknowledgementInternal(checkable, type, true);
751 }
752
753 void DbEvents::RemoveAcknowledgement(const Checkable::Ptr& checkable)
754 {
755         AddAcknowledgementInternal(checkable, AcknowledgementNone, false);
756 }
757
758 void DbEvents::AddAcknowledgementInternal(const Checkable::Ptr& checkable, AcknowledgementType type, bool add)
759 {
760         Host::Ptr host;
761         Service::Ptr service;
762         tie(host, service) = GetHostService(checkable);
763
764         DbQuery query1;
765         query1.WhereCriteria = new Dictionary();
766
767         if (service) {
768                 query1.Table = "servicestatus";
769                 query1.WhereCriteria->Set("service_object_id", service);
770         } else {
771                 query1.Table = "hoststatus";
772                 query1.WhereCriteria->Set("host_object_id", host);
773         }
774
775         query1.Type = DbQueryUpdate;
776         query1.Category = DbCatState;
777         query1.StatusUpdate = true;
778         query1.Object = DbObject::GetOrCreateByObject(checkable);
779
780         query1.Fields = new Dictionary({
781                 { "acknowledgement_type", type },
782                 { "problem_has_been_acknowledged", add ? 1 : 0 }
783         });
784
785         query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
786
787         DbObject::OnQuery(query1);
788 }
789
790 /* notifications */
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)
793 {
794         /* start and end happen at the same time */
795         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
796
797         DbQuery query1;
798         query1.Table = "notifications";
799         query1.Type = DbQueryInsert;
800         query1.Category = DbCatNotification;
801         query1.NotificationInsertID = new DbValue(DbValueObjectInsertID, -1);
802
803         Host::Ptr host;
804         Service::Ptr service;
805         tie(host, service) = GetHostService(checkable);
806
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);
815
816         if (service)
817                 fields1->Set("state", service->GetState());
818         else
819                 fields1->Set("state", GetHostState(host));
820
821         if (cr) {
822                 fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
823                 fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
824         }
825
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 */
829
830         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
831
832         if (endpoint)
833                 fields1->Set("endpoint_object_id", endpoint);
834
835         query1.Fields = fields1;
836         DbObject::OnQuery(query1);
837
838         std::vector<DbQuery> queries;
839
840         for (const User::Ptr& user : users) {
841                 DbQuery query2;
842                 query2.Table = "contactnotifications";
843                 query2.Type = DbQueryInsert;
844                 query2.Category = DbCatNotification;
845
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 */
854                 });
855
856                 queries.emplace_back(std::move(query2));
857         }
858
859         DbObject::OnMultipleQueries(queries);
860 }
861
862 /* statehistory */
863 void DbEvents::AddStateChangeHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, StateType type)
864 {
865         double ts = cr->GetExecutionEnd();
866         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(ts);
867
868         DbQuery query1;
869         query1.Table = "statehistory";
870         query1.Type = DbQueryInsert;
871         query1.Category = DbCatStateHistory;
872
873         Host::Ptr host;
874         Service::Ptr service;
875         tie(host, service) = GetHostService(checkable);
876
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());
885
886         if (service) {
887                 fields1->Set("state", service->GetState());
888                 fields1->Set("last_state", service->GetLastState());
889                 fields1->Set("last_hard_state", service->GetLastHardState());
890         } else {
891                 fields1->Set("state", GetHostState(host));
892                 fields1->Set("last_state", host->GetLastState());
893                 fields1->Set("last_hard_state", host->GetLastHardState());
894         }
895
896         if (cr) {
897                 fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
898                 fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
899                 fields1->Set("check_source", cr->GetCheckSource());
900         }
901
902         fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
903
904         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
905
906         if (endpoint)
907                 fields1->Set("endpoint_object_id", endpoint);
908
909         query1.Fields = fields1;
910         DbObject::OnQuery(query1);
911 }
912
913 /* logentries */
914 void DbEvents::AddCheckResultLogHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr &cr)
915 {
916         if (!cr)
917                 return;
918
919         Dictionary::Ptr varsBefore = cr->GetVarsBefore();
920         Dictionary::Ptr varsAfter = cr->GetVarsAfter();
921
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. */
928         }
929
930         LogEntryType type;
931         String output = CompatUtility::GetCheckResultOutput(cr);
932
933         Host::Ptr host;
934         Service::Ptr service;
935         tie(host, service) = GetHostService(checkable);
936
937         std::ostringstream msgbuf;
938
939         if (service) {
940                 msgbuf << "SERVICE ALERT: "
941                         << host->GetName() << ";"
942                         << service->GetShortName() << ";"
943                         << Service::StateToString(service->GetState()) << ";"
944                         << Service::StateTypeToString(service->GetStateType()) << ";"
945                         << service->GetCheckAttempt() << ";"
946                         << output << ""
947                         << "";
948
949                 switch (service->GetState()) {
950                         case ServiceOK:
951                                 type = LogEntryTypeServiceOk;
952                                 break;
953                         case ServiceUnknown:
954                                 type = LogEntryTypeServiceUnknown;
955                                 break;
956                         case ServiceWarning:
957                                 type = LogEntryTypeServiceWarning;
958                                 break;
959                         case ServiceCritical:
960                                 type = LogEntryTypeServiceCritical;
961                                 break;
962                         default:
963                                 Log(LogCritical, "DbEvents")
964                                         << "Unknown service state: " << service->GetState();
965                                 return;
966                 }
967         } else {
968                 msgbuf << "HOST ALERT: "
969                         << host->GetName() << ";"
970                         << GetHostStateString(host) << ";"
971                         << Host::StateTypeToString(host->GetStateType()) << ";"
972                         << host->GetCheckAttempt() << ";"
973                         << output << ""
974                         << "";
975
976                 switch (host->GetState()) {
977                         case HostUp:
978                                 type = LogEntryTypeHostUp;
979                                 break;
980                         case HostDown:
981                                 type = LogEntryTypeHostDown;
982                                 break;
983                         default:
984                                 Log(LogCritical, "DbEvents")
985                                         << "Unknown host state: " << host->GetState();
986                                 return;
987                 }
988
989                 if (!host->IsReachable())
990                         type = LogEntryTypeHostUnreachable;
991         }
992
993         AddLogHistory(checkable, msgbuf.str(), type);
994 }
995
996 void DbEvents::AddTriggerDowntimeLogHistory(const Downtime::Ptr& downtime)
997 {
998         Checkable::Ptr checkable = downtime->GetCheckable();
999
1000         Host::Ptr host;
1001         Service::Ptr service;
1002         tie(host, service) = GetHostService(checkable);
1003
1004         std::ostringstream msgbuf;
1005
1006         if (service) {
1007                 msgbuf << "SERVICE DOWNTIME ALERT: "
1008                         << host->GetName() << ";"
1009                         << service->GetShortName() << ";"
1010                         << "STARTED" << "; "
1011                         << "Service has entered a period of scheduled downtime."
1012                         << "";
1013         } else {
1014                 msgbuf << "HOST DOWNTIME ALERT: "
1015                         << host->GetName() << ";"
1016                         << "STARTED" << "; "
1017                         << "Service has entered a period of scheduled downtime."
1018                         << "";
1019         }
1020
1021         AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1022 }
1023
1024 void DbEvents::AddRemoveDowntimeLogHistory(const Downtime::Ptr& downtime)
1025 {
1026         Checkable::Ptr checkable = downtime->GetCheckable();
1027
1028         String downtimeOutput;
1029         String downtimeStateStr;
1030
1031         if (downtime->GetWasCancelled()) {
1032                 downtimeOutput = "Scheduled downtime for service has been cancelled.";
1033                 downtimeStateStr = "CANCELLED";
1034         } else {
1035                 downtimeOutput = "Service has exited from a period of scheduled downtime.";
1036                 downtimeStateStr = "STOPPED";
1037         }
1038
1039         Host::Ptr host;
1040         Service::Ptr service;
1041         tie(host, service) = GetHostService(checkable);
1042
1043         std::ostringstream msgbuf;
1044
1045         if (service) {
1046                 msgbuf << "SERVICE DOWNTIME ALERT: "
1047                         << host->GetName() << ";"
1048                         << service->GetShortName() << ";"
1049                         << downtimeStateStr << "; "
1050                         << downtimeOutput
1051                         << "";
1052         } else {
1053                 msgbuf << "HOST DOWNTIME ALERT: "
1054                         << host->GetName() << ";"
1055                         << downtimeStateStr << "; "
1056                         << downtimeOutput
1057                         << "";
1058         }
1059
1060         AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1061 }
1062
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)
1066 {
1067         CheckCommand::Ptr commandObj = checkable->GetCheckCommand();
1068
1069         String checkCommandName;
1070
1071         if (commandObj)
1072                 checkCommandName = commandObj->GetName();
1073
1074         String notificationTypeStr = Notification::NotificationTypeToString(notification_type);
1075
1076         String author_comment = "";
1077         if (notification_type == NotificationCustom || notification_type == NotificationAcknowledgement) {
1078                 author_comment = ";" + author + ";" + comment_text;
1079         }
1080
1081         if (!cr)
1082                 return;
1083
1084         String output = CompatUtility::GetCheckResultOutput(cr);
1085
1086         Host::Ptr host;
1087         Service::Ptr service;
1088         tie(host, service) = GetHostService(checkable);
1089
1090         std::ostringstream msgbuf;
1091
1092         if (service) {
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
1101                         << "";
1102         } else {
1103                 msgbuf << "HOST NOTIFICATION: "
1104                         << user->GetName() << ";"
1105                         << host->GetName() << ";"
1106                         << notificationTypeStr << " "
1107                         << "(" << Host::StateToString(host->GetState()) << ");"
1108                         << checkCommandName << ";"
1109                         << output << author_comment
1110                         << "";
1111         }
1112
1113         AddLogHistory(checkable, msgbuf.str(), LogEntryTypeHostNotification);
1114 }
1115
1116 void DbEvents::AddFlappingChangedLogHistory(const Checkable::Ptr& checkable)
1117 {
1118         String flappingStateStr;
1119         String flappingOutput;
1120
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";
1124         } else {
1125                 flappingOutput = "Service appears to have stopped flapping (" + Convert::ToString(checkable->GetFlappingCurrent()) + "% change < " + Convert::ToString(checkable->GetFlappingThresholdLow()) + "% threshold)";
1126                 flappingStateStr = "STOPPED";
1127         }
1128
1129         Host::Ptr host;
1130         Service::Ptr service;
1131         tie(host, service) = GetHostService(checkable);
1132
1133         std::ostringstream msgbuf;
1134
1135         if (service) {
1136                 msgbuf << "SERVICE FLAPPING ALERT: "
1137                         << host->GetName() << ";"
1138                         << service->GetShortName() << ";"
1139                         << flappingStateStr << "; "
1140                         << flappingOutput
1141                         << "";
1142         } else {
1143                 msgbuf << "HOST FLAPPING ALERT: "
1144                         << host->GetName() << ";"
1145                         << flappingStateStr << "; "
1146                         << flappingOutput
1147                         << "";
1148         }
1149
1150         AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1151 }
1152
1153 void DbEvents::AddEnableFlappingChangedLogHistory(const Checkable::Ptr& checkable)
1154 {
1155         if (!checkable->GetEnableFlapping())
1156                 return;
1157
1158         String flappingOutput = "Flap detection has been disabled";
1159         String flappingStateStr = "DISABLED";
1160
1161         Host::Ptr host;
1162         Service::Ptr service;
1163         tie(host, service) = GetHostService(checkable);
1164
1165         std::ostringstream msgbuf;
1166
1167         if (service) {
1168                 msgbuf << "SERVICE FLAPPING ALERT: "
1169                         << host->GetName() << ";"
1170                         << service->GetShortName() << ";"
1171                         << flappingStateStr << "; "
1172                         << flappingOutput
1173                         << "";
1174         } else {
1175                 msgbuf << "HOST FLAPPING ALERT: "
1176                         << host->GetName() << ";"
1177                         << flappingStateStr << "; "
1178                         << flappingOutput
1179                         << "";
1180         }
1181
1182         AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
1183 }
1184
1185 void DbEvents::AddLogHistory(const Checkable::Ptr& checkable, const String& buffer, LogEntryType type)
1186 {
1187         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
1188
1189         DbQuery query1;
1190         query1.Table = "logentries";
1191         query1.Type = DbQueryInsert;
1192         query1.Category = DbCatLog;
1193
1194         Dictionary::Ptr fields1 = new Dictionary();
1195
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);
1202
1203         fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1204
1205         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1206
1207         if (endpoint)
1208                 fields1->Set("endpoint_object_id", endpoint);
1209
1210         query1.Fields = fields1;
1211         DbObject::OnQuery(query1);
1212 }
1213
1214 /* flappinghistory */
1215 void DbEvents::AddFlappingChangedHistory(const Checkable::Ptr& checkable)
1216 {
1217         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
1218
1219         DbQuery query1;
1220         query1.Table = "flappinghistory";
1221         query1.Type = DbQueryInsert;
1222         query1.Category = DbCatFlapping;
1223
1224         Dictionary::Ptr fields1 = new Dictionary();
1225
1226         fields1->Set("event_time", DbValue::FromTimestamp(timeBag.first));
1227         fields1->Set("event_time_usec", timeBag.second);
1228
1229         if (checkable->IsFlapping())
1230                 fields1->Set("event_type", 1000);
1231         else {
1232                 fields1->Set("event_type", 1001);
1233                 fields1->Set("reason_type", 1);
1234         }
1235
1236         Host::Ptr host;
1237         Service::Ptr service;
1238         tie(host, service) = GetHostService(checkable);
1239
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());
1245
1246         fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
1247
1248         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1249
1250         if (endpoint)
1251                 fields1->Set("endpoint_object_id", endpoint);
1252
1253         query1.Fields = fields1;
1254         DbObject::OnQuery(query1);
1255 }
1256
1257 void DbEvents::AddEnableFlappingChangedHistory(const Checkable::Ptr& checkable)
1258 {
1259         if (!checkable->GetEnableFlapping())
1260                 return;
1261
1262         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
1263
1264         DbQuery query1;
1265         query1.Table = "flappinghistory";
1266         query1.Type = DbQueryInsert;
1267         query1.Category = DbCatFlapping;
1268
1269         Dictionary::Ptr fields1 = new Dictionary();
1270
1271         fields1->Set("event_time", DbValue::FromTimestamp(timeBag.first));
1272         fields1->Set("event_time_usec", timeBag.second);
1273
1274         fields1->Set("event_type", 1001);
1275         fields1->Set("reason_type", 2);
1276
1277         Host::Ptr host;
1278         Service::Ptr service;
1279         tie(host, service) = GetHostService(checkable);
1280
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 */
1287
1288         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1289
1290         if (endpoint)
1291                 fields1->Set("endpoint_object_id", endpoint);
1292
1293         query1.Fields = fields1;
1294         DbObject::OnQuery(query1);
1295 }
1296
1297 /* servicechecks */
1298 void DbEvents::AddCheckableCheckHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr)
1299 {
1300         if (!cr)
1301                 return;
1302
1303         Host::Ptr host;
1304         Service::Ptr service;
1305         tie(host, service) = GetHostService(checkable);
1306
1307         DbQuery query1;
1308         query1.Table = service ? "servicechecks" : "hostchecks";
1309         query1.Type = DbQueryInsert;
1310         query1.Category = DbCatCheck;
1311
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());
1317
1318         double start = cr->GetExecutionStart();
1319         double end = cr->GetExecutionEnd();
1320         double executionTime = cr->CalculateExecutionTime();
1321
1322         std::pair<unsigned long, unsigned long> timeBagStart = ConvertTimestamp(start);
1323         std::pair<unsigned long, unsigned long> timeBagEnd = ConvertTimestamp(end);
1324
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()));
1334
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 */
1339
1340         if (service) {
1341                 fields1->Set("service_object_id", service);
1342                 fields1->Set("state", service->GetState());
1343         } else {
1344                 fields1->Set("host_object_id", host);
1345                 fields1->Set("state", GetHostState(host));
1346         }
1347
1348         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1349
1350         if (endpoint)
1351                 fields1->Set("endpoint_object_id", endpoint);
1352
1353         query1.Fields = fields1;
1354         DbObject::OnQuery(query1);
1355 }
1356
1357 /* eventhandlers */
1358 void DbEvents::AddEventHandlerHistory(const Checkable::Ptr& checkable)
1359 {
1360         DbQuery query1;
1361         query1.Table = "eventhandlers";
1362         query1.Type = DbQueryInsert;
1363         query1.Category = DbCatEventHandler;
1364
1365         Dictionary::Ptr fields1 = new Dictionary();
1366
1367         Host::Ptr host;
1368         Service::Ptr service;
1369         tie(host, service) = GetHostService(checkable);
1370
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 */
1375
1376         if (service) {
1377                 fields1->Set("state", service->GetState());
1378                 fields1->Set("eventhandler_type", 1);
1379         } else {
1380                 fields1->Set("state", GetHostState(host));
1381                 fields1->Set("eventhandler_type", 0);
1382         }
1383
1384         std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
1385
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);
1390
1391         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1392
1393         if (endpoint)
1394                 fields1->Set("endpoint_object_id", endpoint);
1395
1396         query1.Fields = fields1;
1397         DbObject::OnQuery(query1);
1398 }
1399
1400 /* externalcommands */
1401 void DbEvents::AddExternalCommandHistory(double time, const String& command, const std::vector<String>& arguments)
1402 {
1403         DbQuery query1;
1404         query1.Table = "externalcommands";
1405         query1.Type = DbQueryInsert;
1406         query1.Category = DbCatExternalCommand;
1407
1408         Dictionary::Ptr fields1 = new Dictionary();
1409
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 */
1415
1416         Endpoint::Ptr endpoint = Endpoint::GetByName(IcingaApplication::GetInstance()->GetNodeName());
1417
1418         if (endpoint)
1419                 fields1->Set("endpoint_object_id", endpoint);
1420
1421         query1.Fields = fields1;
1422         DbObject::OnQuery(query1);
1423 }
1424
1425 int DbEvents::GetHostState(const Host::Ptr& host)
1426 {
1427         int currentState = host->GetState();
1428
1429         if (currentState != HostUp && !host->IsReachable())
1430                 currentState = 2; /* hardcoded compat state */
1431
1432         return currentState;
1433 }
1434
1435 String DbEvents::GetHostStateString(const Host::Ptr& host)
1436 {
1437         if (host->GetState() != HostUp && !host->IsReachable())
1438                 return "UNREACHABLE"; /* hardcoded compat state */
1439
1440         return Host::StateToString(host->GetState());
1441 }
1442
1443 std::pair<unsigned long, unsigned long> DbEvents::ConvertTimestamp(double time)
1444 {
1445         unsigned long time_sec = static_cast<long>(time);
1446         unsigned long time_usec = (time - time_sec) * 1000 * 1000;
1447
1448         return std::make_pair(time_sec, time_usec);
1449 }
1450
1451 int DbEvents::MapNotificationReasonType(NotificationType type)
1452 {
1453         switch (type) {
1454                 case NotificationDowntimeStart:
1455                         return 5;
1456                 case NotificationDowntimeEnd:
1457                         return 6;
1458                 case NotificationDowntimeRemoved:
1459                         return 7;
1460                 case NotificationCustom:
1461                         return 8;
1462                 case NotificationAcknowledgement:
1463                         return 1;
1464                 case NotificationProblem:
1465                         return 0;
1466                 case NotificationRecovery:
1467                         return 0;
1468                 case NotificationFlappingStart:
1469                         return 2;
1470                 case NotificationFlappingEnd:
1471                         return 3;
1472                 default:
1473                         return 0;
1474         }
1475 }
1476
1477 int DbEvents::MapExternalCommandType(const String& name)
1478 {
1479         if (name == "NONE")
1480                 return 0;
1481         if (name == "ADD_HOST_COMMENT")
1482                 return 1;
1483         if (name == "DEL_HOST_COMMENT")
1484                 return 2;
1485         if (name == "ADD_SVC_COMMENT")
1486                 return 3;
1487         if (name == "DEL_SVC_COMMENT")
1488                 return 4;
1489         if (name == "ENABLE_SVC_CHECK")
1490                 return 5;
1491         if (name == "DISABLE_SVC_CHECK")
1492                 return 6;
1493         if (name == "SCHEDULE_SVC_CHECK")
1494                 return 7;
1495         if (name == "DELAY_SVC_NOTIFICATION")
1496                 return 9;
1497         if (name == "DELAY_HOST_NOTIFICATION")
1498                 return 10;
1499         if (name == "DISABLE_NOTIFICATIONS")
1500                 return 11;
1501         if (name == "ENABLE_NOTIFICATIONS")
1502                 return 12;
1503         if (name == "RESTART_PROCESS")
1504                 return 13;
1505         if (name == "SHUTDOWN_PROCESS")
1506                 return 14;
1507         if (name == "ENABLE_HOST_SVC_CHECKS")
1508                 return 15;
1509         if (name == "DISABLE_HOST_SVC_CHECKS")
1510                 return 16;
1511         if (name == "SCHEDULE_HOST_SVC_CHECKS")
1512                 return 17;
1513         if (name == "DELAY_HOST_SVC_NOTIFICATIONS")
1514                 return 19;
1515         if (name == "DEL_ALL_HOST_COMMENTS")
1516                 return 20;
1517         if (name == "DEL_ALL_SVC_COMMENTS")
1518                 return 21;
1519         if (name == "ENABLE_SVC_NOTIFICATIONS")
1520                 return 22;
1521         if (name == "DISABLE_SVC_NOTIFICATIONS")
1522                 return 23;
1523         if (name == "ENABLE_HOST_NOTIFICATIONS")
1524                 return 24;
1525         if (name == "DISABLE_HOST_NOTIFICATIONS")
1526                 return 25;
1527         if (name == "ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST")
1528                 return 26;
1529         if (name == "DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST")
1530                 return 27;
1531         if (name == "ENABLE_HOST_SVC_NOTIFICATIONS")
1532                 return 28;
1533         if (name == "DISABLE_HOST_SVC_NOTIFICATIONS")
1534                 return 29;
1535         if (name == "PROCESS_SERVICE_CHECK_RESULT")
1536                 return 30;
1537         if (name == "SAVE_STATE_INFORMATION")
1538                 return 31;
1539         if (name == "READ_STATE_INFORMATION")
1540                 return 32;
1541         if (name == "ACKNOWLEDGE_HOST_PROBLEM")
1542                 return 33;
1543         if (name == "ACKNOWLEDGE_SVC_PROBLEM")
1544                 return 34;
1545         if (name == "START_EXECUTING_SVC_CHECKS")
1546                 return 35;
1547         if (name == "STOP_EXECUTING_SVC_CHECKS")
1548                 return 36;
1549         if (name == "START_ACCEPTING_PASSIVE_SVC_CHECKS")
1550                 return 37;
1551         if (name == "STOP_ACCEPTING_PASSIVE_SVC_CHECKS")
1552                 return 38;
1553         if (name == "ENABLE_PASSIVE_SVC_CHECKS")
1554                 return 39;
1555         if (name == "DISABLE_PASSIVE_SVC_CHECKS")
1556                 return 40;
1557         if (name == "ENABLE_EVENT_HANDLERS")
1558                 return 41;
1559         if (name == "DISABLE_EVENT_HANDLERS")
1560                 return 42;
1561         if (name == "ENABLE_HOST_EVENT_HANDLER")
1562                 return 43;
1563         if (name == "DISABLE_HOST_EVENT_HANDLER")
1564                 return 44;
1565         if (name == "ENABLE_SVC_EVENT_HANDLER")
1566                 return 45;
1567         if (name == "DISABLE_SVC_EVENT_HANDLER")
1568                 return 46;
1569         if (name == "ENABLE_HOST_CHECK")
1570                 return 47;
1571         if (name == "DISABLE_HOST_CHECK")
1572                 return 48;
1573         if (name == "START_OBSESSING_OVER_SVC_CHECKS")
1574                 return 49;
1575         if (name == "STOP_OBSESSING_OVER_SVC_CHECKS")
1576                 return 50;
1577         if (name == "REMOVE_HOST_ACKNOWLEDGEMENT")
1578                 return 51;
1579         if (name == "REMOVE_SVC_ACKNOWLEDGEMENT")
1580                 return 52;
1581         if (name == "SCHEDULE_FORCED_HOST_SVC_CHECKS")
1582                 return 53;
1583         if (name == "SCHEDULE_FORCED_SVC_CHECK")
1584                 return 54;
1585         if (name == "SCHEDULE_HOST_DOWNTIME")
1586                 return 55;
1587         if (name == "SCHEDULE_SVC_DOWNTIME")
1588                 return 56;
1589         if (name == "ENABLE_HOST_FLAP_DETECTION")
1590                 return 57;
1591         if (name == "DISABLE_HOST_FLAP_DETECTION")
1592                 return 58;
1593         if (name == "ENABLE_SVC_FLAP_DETECTION")
1594                 return 59;
1595         if (name == "DISABLE_SVC_FLAP_DETECTION")
1596                 return 60;
1597         if (name == "ENABLE_FLAP_DETECTION")
1598                 return 61;
1599         if (name == "DISABLE_FLAP_DETECTION")
1600                 return 62;
1601         if (name == "ENABLE_HOSTGROUP_SVC_NOTIFICATIONS")
1602                 return 63;
1603         if (name == "DISABLE_HOSTGROUP_SVC_NOTIFICATIONS")
1604                 return 64;
1605         if (name == "ENABLE_HOSTGROUP_HOST_NOTIFICATIONS")
1606                 return 65;
1607         if (name == "DISABLE_HOSTGROUP_HOST_NOTIFICATIONS")
1608                 return 66;
1609         if (name == "ENABLE_HOSTGROUP_SVC_CHECKS")
1610                 return 67;
1611         if (name == "DISABLE_HOSTGROUP_SVC_CHECKS")
1612                 return 68;
1613         if (name == "CANCEL_HOST_DOWNTIME")
1614                 return 69;
1615         if (name == "CANCEL_SVC_DOWNTIME")
1616                 return 70;
1617         if (name == "CANCEL_ACTIVE_HOST_DOWNTIME")
1618                 return 71;
1619         if (name == "CANCEL_PENDING_HOST_DOWNTIME")
1620                 return 72;
1621         if (name == "CANCEL_ACTIVE_SVC_DOWNTIME")
1622                 return 73;
1623         if (name == "CANCEL_PENDING_SVC_DOWNTIME")
1624                 return 74;
1625         if (name == "CANCEL_ACTIVE_HOST_SVC_DOWNTIME")
1626                 return 75;
1627         if (name == "CANCEL_PENDING_HOST_SVC_DOWNTIME")
1628                 return 76;
1629         if (name == "FLUSH_PENDING_COMMANDS")
1630                 return 77;
1631         if (name == "DEL_HOST_DOWNTIME")
1632                 return 78;
1633         if (name == "DEL_SVC_DOWNTIME")
1634                 return 79;
1635         if (name == "ENABLE_FAILURE_PREDICTION")
1636                 return 80;
1637         if (name == "DISABLE_FAILURE_PREDICTION")
1638                 return 81;
1639         if (name == "ENABLE_PERFORMANCE_DATA")
1640                 return 82;
1641         if (name == "DISABLE_PERFORMANCE_DATA")
1642                 return 83;
1643         if (name == "SCHEDULE_HOSTGROUP_HOST_DOWNTIME")
1644                 return 84;
1645         if (name == "SCHEDULE_HOSTGROUP_SVC_DOWNTIME")
1646                 return 85;
1647         if (name == "SCHEDULE_HOST_SVC_DOWNTIME")
1648                 return 86;
1649         if (name == "PROCESS_HOST_CHECK_RESULT")
1650                 return 87;
1651         if (name == "START_EXECUTING_HOST_CHECKS")
1652                 return 88;
1653         if (name == "STOP_EXECUTING_HOST_CHECKS")
1654                 return 89;
1655         if (name == "START_ACCEPTING_PASSIVE_HOST_CHECKS")
1656                 return 90;
1657         if (name == "STOP_ACCEPTING_PASSIVE_HOST_CHECKS")
1658                 return 91;
1659         if (name == "ENABLE_PASSIVE_HOST_CHECKS")
1660                 return 92;
1661         if (name == "DISABLE_PASSIVE_HOST_CHECKS")
1662                 return 93;
1663         if (name == "START_OBSESSING_OVER_HOST_CHECKS")
1664                 return 94;
1665         if (name == "STOP_OBSESSING_OVER_HOST_CHECKS")
1666                 return 95;
1667         if (name == "SCHEDULE_HOST_CHECK")
1668                 return 96;
1669         if (name == "SCHEDULE_FORCED_HOST_CHECK")
1670                 return 98;
1671         if (name == "START_OBSESSING_OVER_SVC")
1672                 return 99;
1673         if (name == "STOP_OBSESSING_OVER_SVC")
1674                 return 100;
1675         if (name == "START_OBSESSING_OVER_HOST")
1676                 return 101;
1677         if (name == "STOP_OBSESSING_OVER_HOST")
1678                 return 102;
1679         if (name == "ENABLE_HOSTGROUP_HOST_CHECKS")
1680                 return 103;
1681         if (name == "DISABLE_HOSTGROUP_HOST_CHECKS")
1682                 return 104;
1683         if (name == "ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS")
1684                 return 105;
1685         if (name == "DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS")
1686                 return 106;
1687         if (name == "ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS")
1688                 return 107;
1689         if (name == "DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS")
1690                 return 108;
1691         if (name == "ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS")
1692                 return 109;
1693         if (name == "DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS")
1694                 return 110;
1695         if (name == "ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS")
1696                 return 111;
1697         if (name == "DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS")
1698                 return 112;
1699         if (name == "ENABLE_SERVICEGROUP_SVC_CHECKS")
1700                 return 113;
1701         if (name == "DISABLE_SERVICEGROUP_SVC_CHECKS")
1702                 return 114;
1703         if (name == "ENABLE_SERVICEGROUP_HOST_CHECKS")
1704                 return 115;
1705         if (name == "DISABLE_SERVICEGROUP_HOST_CHECKS")
1706                 return 116;
1707         if (name == "ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS")
1708                 return 117;
1709         if (name == "DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS")
1710                 return 118;
1711         if (name == "ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS")
1712                 return 119;
1713         if (name == "DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS")
1714                 return 120;
1715         if (name == "SCHEDULE_SERVICEGROUP_HOST_DOWNTIME")
1716                 return 121;
1717         if (name == "SCHEDULE_SERVICEGROUP_SVC_DOWNTIME")
1718                 return 122;
1719         if (name == "CHANGE_GLOBAL_HOST_EVENT_HANDLER")
1720                 return 123;
1721         if (name == "CHANGE_GLOBAL_SVC_EVENT_HANDLER")
1722                 return 124;
1723         if (name == "CHANGE_HOST_EVENT_HANDLER")
1724                 return 125;
1725         if (name == "CHANGE_SVC_EVENT_HANDLER")
1726                 return 126;
1727         if (name == "CHANGE_HOST_CHECK_COMMAND")
1728                 return 127;
1729         if (name == "CHANGE_SVC_CHECK_COMMAND")
1730                 return 128;
1731         if (name == "CHANGE_NORMAL_HOST_CHECK_INTERVAL")
1732                 return 129;
1733         if (name == "CHANGE_NORMAL_SVC_CHECK_INTERVAL")
1734                 return 130;
1735         if (name == "CHANGE_RETRY_SVC_CHECK_INTERVAL")
1736                 return 131;
1737         if (name == "CHANGE_MAX_HOST_CHECK_ATTEMPTS")
1738                 return 132;
1739         if (name == "CHANGE_MAX_SVC_CHECK_ATTEMPTS")
1740                 return 133;
1741         if (name == "SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME")
1742                 return 134;
1743         if (name == "ENABLE_HOST_AND_CHILD_NOTIFICATIONS")
1744                 return 135;
1745         if (name == "DISABLE_HOST_AND_CHILD_NOTIFICATIONS")
1746                 return 136;
1747         if (name == "SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME")
1748                 return 137;
1749         if (name == "ENABLE_SERVICE_FRESHNESS_CHECKS")
1750                 return 138;
1751         if (name == "DISABLE_SERVICE_FRESHNESS_CHECKS")
1752                 return 139;
1753         if (name == "ENABLE_HOST_FRESHNESS_CHECKS")
1754                 return 140;
1755         if (name == "DISABLE_HOST_FRESHNESS_CHECKS")
1756                 return 141;
1757         if (name == "SET_HOST_NOTIFICATION_NUMBER")
1758                 return 142;
1759         if (name == "SET_SVC_NOTIFICATION_NUMBER")
1760                 return 143;
1761         if (name == "CHANGE_HOST_CHECK_TIMEPERIOD")
1762                 return 144;
1763         if (name == "CHANGE_SVC_CHECK_TIMEPERIOD")
1764                 return 145;
1765         if (name == "PROCESS_FILE")
1766                 return 146;
1767         if (name == "CHANGE_CUSTOM_HOST_VAR")
1768                 return 147;
1769         if (name == "CHANGE_CUSTOM_SVC_VAR")
1770                 return 148;
1771         if (name == "CHANGE_CUSTOM_CONTACT_VAR")
1772                 return 149;
1773         if (name == "ENABLE_CONTACT_HOST_NOTIFICATIONS")
1774                 return 150;
1775         if (name == "DISABLE_CONTACT_HOST_NOTIFICATIONS")
1776                 return 151;
1777         if (name == "ENABLE_CONTACT_SVC_NOTIFICATIONS")
1778                 return 152;
1779         if (name == "DISABLE_CONTACT_SVC_NOTIFICATIONS")
1780                 return 153;
1781         if (name == "ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS")
1782                 return 154;
1783         if (name == "DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS")
1784                 return 155;
1785         if (name == "ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS")
1786                 return 156;
1787         if (name == "DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS")
1788                 return 157;
1789         if (name == "CHANGE_RETRY_HOST_CHECK_INTERVAL")
1790                 return 158;
1791         if (name == "SEND_CUSTOM_HOST_NOTIFICATION")
1792                 return 159;
1793         if (name == "SEND_CUSTOM_SVC_NOTIFICATION")
1794                 return 160;
1795         if (name == "CHANGE_HOST_NOTIFICATION_TIMEPERIOD")
1796                 return 161;
1797         if (name == "CHANGE_SVC_NOTIFICATION_TIMEPERIOD")
1798                 return 162;
1799         if (name == "CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD")
1800                 return 163;
1801         if (name == "CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD")
1802                 return 164;
1803         if (name == "CHANGE_HOST_MODATTR")
1804                 return 165;
1805         if (name == "CHANGE_SVC_MODATTR")
1806                 return 166;
1807         if (name == "CHANGE_CONTACT_MODATTR")
1808                 return 167;
1809         if (name == "CHANGE_CONTACT_MODHATTR")
1810                 return 168;
1811         if (name == "CHANGE_CONTACT_MODSATTR")
1812                 return 169;
1813         if (name == "SYNC_STATE_INFORMATION")
1814                 return 170;
1815         if (name == "DEL_DOWNTIME_BY_HOST_NAME")
1816                 return 171;
1817         if (name == "DEL_DOWNTIME_BY_HOSTGROUP_NAME")
1818                 return 172;
1819         if (name == "DEL_DOWNTIME_BY_START_TIME_COMMENT")
1820                 return 173;
1821         if (name == "ACKNOWLEDGE_HOST_PROBLEM_EXPIRE")
1822                 return 174;
1823         if (name == "ACKNOWLEDGE_SVC_PROBLEM_EXPIRE")
1824                 return 175;
1825         if (name == "DISABLE_NOTIFICATIONS_EXPIRE_TIME")
1826                 return 176;
1827         if (name == "CUSTOM_COMMAND")
1828                 return 999;
1829
1830         return 0;
1831 }