[icinga-checkins] icinga.org: icinga2/master: Ensure that DowntimeStart notifications are not immediately sent

git at icinga.org git at icinga.org
Fri Nov 11 19:38:16 CET 2016


Module: icinga2
Branch: master
Commit: 1bfb91f0655ab0cdc6026b9068ac1a19216f3485
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=1bfb91f0655ab0cdc6026b9068ac1a19216f3485

Author: Michael Friedrich <michael.friedrich at icinga.com>
Date:   Fri Nov 11 19:36:19 2016 +0100

Ensure that DowntimeStart notifications are not immediately sent

fixes #12549

---

 doc/12-icinga2-api.md    |    1 +
 lib/icinga/apievents.cpp |   21 +++++++++++++++++++
 lib/icinga/apievents.hpp |    1 +
 lib/icinga/checkable.cpp |    2 +-
 lib/icinga/downtime.cpp  |   52 +++++++++++++++++++++++++++++++++-------------
 lib/icinga/downtime.hpp  |    4 ++++
 6 files changed, 65 insertions(+), 16 deletions(-)

diff --git a/doc/12-icinga2-api.md b/doc/12-icinga2-api.md
index 94a65ec..38b1ec6 100644
--- a/doc/12-icinga2-api.md
+++ b/doc/12-icinga2-api.md
@@ -1186,6 +1186,7 @@ The following event stream types are available:
   CommentRemoved         | Comment removed for hosts and services.
   DowntimeAdded          | Downtime added for hosts and services.
   DowntimeRemoved        | Downtime removed for hosts and services.
+  DowntimeStarted        | Downtime started for hosts and services.
   DowntimeTriggered      | Downtime triggered for hosts and services.
 
 Note: Each type requires [API permissions](12-icinga2-api.md#icinga2-api-permissions)
diff --git a/lib/icinga/apievents.cpp b/lib/icinga/apievents.cpp
index 6c4e9cb..a512d6f 100644
--- a/lib/icinga/apievents.cpp
+++ b/lib/icinga/apievents.cpp
@@ -44,6 +44,7 @@ void ApiEvents::StaticInitialize(void)
 
 	Downtime::OnDowntimeAdded.connect(&ApiEvents::DowntimeAddedHandler);
 	Downtime::OnDowntimeRemoved.connect(&ApiEvents::DowntimeRemovedHandler);
+	Downtime::OnDowntimeStarted.connect(&ApiEvents::DowntimeStartedHandler);
 	Downtime::OnDowntimeTriggered.connect(&ApiEvents::DowntimeTriggeredHandler);
 }
 
@@ -323,6 +324,26 @@ void ApiEvents::DowntimeRemovedHandler(const Downtime::Ptr& downtime)
 	}
 }
 
+void ApiEvents::DowntimeStartedHandler(const Downtime::Ptr& downtime)
+{
+	std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeStarted");
+
+	if (queues.empty())
+		return;
+
+	Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeStarted'.");
+
+	Dictionary::Ptr result = new Dictionary();
+	result->Set("type", "DowntimeStarted");
+	result->Set("timestamp", Utility::GetTime());
+
+	result->Set("downtime", Serialize(downtime, FAConfig | FAState));
+
+	for (const EventQueue::Ptr& queue : queues) {
+		queue->ProcessEvent(result);
+	}
+}
+
 void ApiEvents::DowntimeTriggeredHandler(const Downtime::Ptr& downtime)
 {
 	std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeTriggered");
diff --git a/lib/icinga/apievents.hpp b/lib/icinga/apievents.hpp
index dfbd64c..70ad46d 100644
--- a/lib/icinga/apievents.hpp
+++ b/lib/icinga/apievents.hpp
@@ -54,6 +54,7 @@ public:
 
 	static void DowntimeAddedHandler(const Downtime::Ptr& downtime);
 	static void DowntimeRemovedHandler(const Downtime::Ptr& downtime);
+	static void DowntimeStartedHandler(const Downtime::Ptr& downtime);
 	static void DowntimeTriggeredHandler(const Downtime::Ptr& downtime);
 };
 
diff --git a/lib/icinga/checkable.cpp b/lib/icinga/checkable.cpp
index 1ddb962..7f6fa7b 100644
--- a/lib/icinga/checkable.cpp
+++ b/lib/icinga/checkable.cpp
@@ -36,7 +36,7 @@ boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin::Ptr&)>
 void Checkable::StaticInitialize(void)
 {
 	/* fixed downtime start */
-	Downtime::OnDowntimeAdded.connect(boost::bind(&Checkable::NotifyFixedDowntimeStart, _1));
+	Downtime::OnDowntimeStarted.connect(boost::bind(&Checkable::NotifyFixedDowntimeStart, _1));
 	/* flexible downtime start */
 	Downtime::OnDowntimeTriggered.connect(boost::bind(&Checkable::NotifyFlexibleDowntimeStart, _1));
 	/* fixed/flexible downtime end */
diff --git a/lib/icinga/downtime.cpp b/lib/icinga/downtime.cpp
index 8adf30c..84cc5b9 100644
--- a/lib/icinga/downtime.cpp
+++ b/lib/icinga/downtime.cpp
@@ -34,9 +34,11 @@ static int l_NextDowntimeID = 1;
 static boost::mutex l_DowntimeMutex;
 static std::map<int, String> l_LegacyDowntimesCache;
 static Timer::Ptr l_DowntimesExpireTimer;
+static Timer::Ptr l_DowntimesStartTimer;
 
 boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeAdded;
 boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeRemoved;
+boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeStarted;
 boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeTriggered;
 
 INITIALIZE_ONCE(&Downtime::StaticInitialize);
@@ -45,6 +47,11 @@ REGISTER_TYPE(Downtime);
 
 void Downtime::StaticInitialize(void)
 {
+	l_DowntimesStartTimer = new Timer();
+	l_DowntimesStartTimer->SetInterval(5);
+	l_DowntimesStartTimer->OnTimerExpired.connect(boost::bind(&Downtime::DowntimesStartTimerHandler));
+	l_DowntimesStartTimer->Start();
+
 	l_DowntimesExpireTimer = new Timer();
 	l_DowntimesExpireTimer->SetInterval(60);
 	l_DowntimesExpireTimer->OnTimerExpired.connect(boost::bind(&Downtime::DowntimesExpireTimerHandler));
@@ -315,27 +322,26 @@ void Downtime::RemoveDowntime(const String& id, bool cancelled, bool expired, co
 	}
 }
 
-void Downtime::TriggerDowntime(void)
+bool Downtime::CanBeTriggered(void)
 {
-	if (IsInEffect() && IsTriggered()) {
-		Log(LogDebug, "Downtime")
-		    << "Not triggering downtime '" << GetName() << "': already triggered.";
-		return;
-	}
+	if (IsInEffect() && IsTriggered())
+		return false;
 
-	if (IsExpired()) {
-		Log(LogDebug, "Downtime")
-		    << "Not triggering downtime '" << GetName() << "': expired.";
-		return;
-	}
+	if (IsExpired())
+		return false;
 
 	double now = Utility::GetTime();
 
-	if (now < GetStartTime() || now > GetEndTime()) {
-		Log(LogDebug, "Downtime")
-		    << "Not triggering downtime '" << GetName() << "': current time is outside downtime window.";
+	if (now < GetStartTime() || now > GetEndTime())
+		return false;
+
+	return true;
+}
+
+void Downtime::TriggerDowntime(void)
+{
+	if (!CanBeTriggered())
 		return;
-	}
 
 	Log(LogNotice, "Downtime")
 		<< "Triggering downtime '" << GetName() << "'.";
@@ -372,6 +378,22 @@ String Downtime::GetDowntimeIDFromLegacyID(int id)
 	return it->second;
 }
 
+void Downtime::DowntimesStartTimerHandler(void)
+{
+	/* Start fixed downtimes. Flexible downtimes will be triggered on-demand. */
+	for (const Downtime::Ptr& downtime : ConfigType::GetObjectsByType<Downtime>()) {
+		if (downtime->IsActive() &&
+		    downtime->CanBeTriggered() &&
+		    downtime->GetFixed()) {
+			/* Send notifications. */
+			OnDowntimeStarted(downtime);
+
+			/* Trigger fixed downtime immediately. */
+			downtime->TriggerDowntime();
+		}
+	}
+}
+
 void Downtime::DowntimesExpireTimerHandler(void)
 {
 	std::vector<Downtime::Ptr> downtimes;
diff --git a/lib/icinga/downtime.hpp b/lib/icinga/downtime.hpp
index 8122ebe..6ccf0c5 100644
--- a/lib/icinga/downtime.hpp
+++ b/lib/icinga/downtime.hpp
@@ -41,6 +41,7 @@ public:
 
 	static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeAdded;
 	static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeRemoved;
+	static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeStarted;
 	static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeTriggered;
 
 	intrusive_ptr<Checkable> GetCheckable(void) const;
@@ -77,6 +78,9 @@ protected:
 private:
 	ObjectImpl<Checkable>::Ptr m_Checkable;
 
+	bool CanBeTriggered(void);
+
+	static void DowntimesStartTimerHandler(void);
 	static void DowntimesExpireTimerHandler(void);
 };
 



More information about the icinga-checkins mailing list