From 99bd0f018969d80700d50849c036afaf8fb64b11 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 21 Mar 2013 13:42:46 +0100 Subject: [PATCH] Implement the 'notification_period' attribute. --- .../notification/notificationcomponent.cpp | 6 +-- lib/icinga/icinga-type.conf | 17 +++++-- lib/icinga/notification.cpp | 46 ++++++++++++++----- lib/icinga/notification.h | 7 ++- lib/icinga/service-notification.cpp | 6 ++- lib/icinga/user.cpp | 6 +++ lib/icinga/user.h | 3 ++ 7 files changed, 69 insertions(+), 22 deletions(-) diff --git a/components/notification/notificationcomponent.cpp b/components/notification/notificationcomponent.cpp index 0ea55fe3c..358da3052 100644 --- a/components/notification/notificationcomponent.cpp +++ b/components/notification/notificationcomponent.cpp @@ -92,12 +92,14 @@ void NotificationComponent::NotificationTimerHandler(void) send_notification = reachable && !service->IsInDowntime() && !service->IsAcknowledged(); } + notification->SetNextNotification(Utility::GetTime() + notification->GetNotificationInterval()); + if (!send_notification) continue; try { Log(LogInformation, "notification", "Sending reminder notification for service '" + service->GetName() + "'"); - notification->BeginExecuteNotification(NotificationProblem, service->GetLastCheckResult()); + notification->BeginExecuteNotification(NotificationProblem, service->GetLastCheckResult(), false); } catch (const std::exception& ex) { std::ostringstream msgbuf; msgbuf << "Exception occured during notification for service '" @@ -106,8 +108,6 @@ void NotificationComponent::NotificationTimerHandler(void) Log(LogWarning, "icinga", message); } - - notification->SetNextNotification(Utility::GetTime() + notification->GetNotificationInterval()); } } diff --git a/lib/icinga/icinga-type.conf b/lib/icinga/icinga-type.conf index eae1fbffb..1c89e8516 100644 --- a/lib/icinga/icinga-type.conf +++ b/lib/icinga/icinga-type.conf @@ -54,6 +54,9 @@ type Host { %attribute number "check_interval", %attribute number "retry_interval", + %attribute number "notification_interval", + %attribute string "notification_period", + %attribute array "servicegroups" { %attribute string "*" }, @@ -99,7 +102,10 @@ type Host { %attribute string "check_period", %attribute number "check_interval", %attribute number "retry_interval", + %attribute number "notification_interval", + %attribute string "notification_period", + %attribute dictionary "macros" { %attribute string "*" }, @@ -145,6 +151,10 @@ type Service { %attribute string "check_period", %attribute number "check_interval", %attribute number "retry_interval", + + %attribute number "notification_interval", + %attribute string "notification_period", + %attribute array "hostdependencies" { %attribute string "*" }, @@ -187,9 +197,7 @@ type Service { %attribute string "*" } } - }, - - %attribute number "notification_interval" + } } type ServiceGroup { @@ -225,7 +233,8 @@ type Notification { }, %attribute string "notification_command", - %attribute number "notification_interval" + %attribute number "notification_interval", + %attribute string "notification_period" } type User { diff --git a/lib/icinga/notification.cpp b/lib/icinga/notification.cpp index 1a56b8c3b..228138348 100644 --- a/lib/icinga/notification.cpp +++ b/lib/icinga/notification.cpp @@ -36,6 +36,7 @@ Notification::Notification(const Dictionary::Ptr& serializedUpdate) { RegisterAttribute("notification_command", Attribute_Config, &m_NotificationCommand); RegisterAttribute("notification_interval", Attribute_Config, &m_NotificationInterval); + RegisterAttribute("notification_period", Attribute_Config, &m_NotificationPeriod); RegisterAttribute("last_notification", Attribute_Replicated, &m_LastNotification); RegisterAttribute("next_notification", Attribute_Replicated, &m_NextNotification); RegisterAttribute("macros", Attribute_Config, &m_Macros); @@ -153,6 +154,14 @@ double Notification::GetNotificationInterval(void) const return m_NotificationInterval; } +/** + * @threadsafety Always. + */ +TimePeriod::Ptr Notification::GetNotificationPeriod(void) const +{ + return TimePeriod::GetByName(m_NotificationPeriod); +} + /** * @threadsafety Always. */ @@ -222,10 +231,19 @@ String Notification::NotificationTypeToString(NotificationType type) /** * @threadsafety Always. */ -void Notification::BeginExecuteNotification(NotificationType type, const Dictionary::Ptr& cr) +void Notification::BeginExecuteNotification(NotificationType type, const Dictionary::Ptr& cr, bool ignore_timeperiod) { ASSERT(!OwnsLock()); + if (!ignore_timeperiod) { + TimePeriod::Ptr tp = GetNotificationPeriod(); + + if (tp && !tp->IsInside(Utility::GetTime())) { + Log(LogInformation, "icinga", "Not sending notifications for notification object '" + GetName() + "': not in timeperiod"); + return; + } + } + { ObjectLock olock(this); @@ -246,28 +264,32 @@ void Notification::BeginExecuteNotification(NotificationType type, const Diction BOOST_FOREACH(const User::Ptr& user, allUsers) { Log(LogDebug, "icinga", "Sending notification for user " + user->GetName()); - BeginExecuteNotificationHelper(macros, type, user); - } - - if (allUsers.empty()) { - /* Send a notification even if there are no users specified. */ - BeginExecuteNotificationHelper(macros, type, User::Ptr()); + BeginExecuteNotificationHelper(macros, type, user, ignore_timeperiod); } } /** * @threadsafety Always. */ -void Notification::BeginExecuteNotificationHelper(const Dictionary::Ptr& notificationMacros, NotificationType type, const User::Ptr& user) +void Notification::BeginExecuteNotificationHelper(const Dictionary::Ptr& notificationMacros, + NotificationType type, const User::Ptr& user, bool ignore_timeperiod) { ASSERT(!OwnsLock()); + if (!ignore_timeperiod) { + TimePeriod::Ptr tp = user->GetNotificationPeriod(); + + if (tp && !tp->IsInside(Utility::GetTime())) { + Log(LogInformation, "icinga", "Not sending notifications for notification object '" + + GetName() + " and user '" + user->GetName() + "': user not in timeperiod"); + return; + } + } + std::vector macroDicts; - if (user) { - macroDicts.push_back(user->GetMacros()); - macroDicts.push_back(user->CalculateDynamicMacros()); - } + macroDicts.push_back(user->GetMacros()); + macroDicts.push_back(user->CalculateDynamicMacros()); macroDicts.push_back(notificationMacros); diff --git a/lib/icinga/notification.h b/lib/icinga/notification.h index 256c260e2..d9bf03e7d 100644 --- a/lib/icinga/notification.h +++ b/lib/icinga/notification.h @@ -23,6 +23,7 @@ #include "icinga/i2-icinga.h" #include "icinga/user.h" #include "icinga/usergroup.h" +#include "icinga/timeperiod.h" #include "base/array.h" namespace icinga @@ -65,6 +66,7 @@ public: shared_ptr GetService(void) const; Value GetNotificationCommand(void) const; double GetNotificationInterval(void) const; + TimePeriod::Ptr GetNotificationPeriod(void) const; Dictionary::Ptr GetMacros(void) const; std::set GetUsers(void) const; std::set GetGroups(void) const; @@ -75,7 +77,7 @@ public: double GetNextNotification(void) const; void SetNextNotification(double time); - void BeginExecuteNotification(NotificationType type, const Dictionary::Ptr& cr); + void BeginExecuteNotification(NotificationType type, const Dictionary::Ptr& cr, bool ignore_timeperiod); static String NotificationTypeToString(NotificationType type); @@ -85,6 +87,7 @@ protected: private: Attribute m_NotificationCommand; Attribute m_NotificationInterval; + Attribute m_NotificationPeriod; Attribute m_LastNotification; Attribute m_NextNotification; Attribute m_Macros; @@ -98,7 +101,7 @@ private: void NotificationCompletedHandler(const ScriptTask::Ptr& task); void BeginExecuteNotificationHelper(const Dictionary::Ptr& notificationMacros, - NotificationType type, const User::Ptr& user); + NotificationType type, const User::Ptr& user, bool ignore_timeperiod); }; } diff --git a/lib/icinga/service-notification.cpp b/lib/icinga/service-notification.cpp index 2da027df4..016c43e46 100644 --- a/lib/icinga/service-notification.cpp +++ b/lib/icinga/service-notification.cpp @@ -60,12 +60,15 @@ void Service::RequestNotifications(NotificationType type, const Dictionary::Ptr& */ void Service::SendNotifications(NotificationType type, const Dictionary::Ptr& cr) { + bool force = false; + if (!GetEnableNotifications()) { if (!GetForceNextNotification()) { Log(LogInformation, "icinga", "Notifications are disabled for service '" + GetName() + "'."); return; } + force = true; SetForceNextNotification(false); } @@ -78,7 +81,7 @@ void Service::SendNotifications(NotificationType type, const Dictionary::Ptr& cr BOOST_FOREACH(const Notification::Ptr& notification, notifications) { try { - notification->BeginExecuteNotification(type, cr); + notification->BeginExecuteNotification(type, cr, force); } catch (const std::exception& ex) { std::ostringstream msgbuf; msgbuf << "Exception occured during notification for service '" @@ -254,6 +257,7 @@ void Service::UpdateSlaveNotifications(void) keys.insert("users"); keys.insert("groups"); keys.insert("notification_interval"); + keys.insert("notification_period"); ExpressionList::Ptr svc_exprl = boost::make_shared(); item->GetLinkedExpressionList()->ExtractFiltered(keys, svc_exprl); diff --git a/lib/icinga/user.cpp b/lib/icinga/user.cpp index 41a843b76..d384a435a 100644 --- a/lib/icinga/user.cpp +++ b/lib/icinga/user.cpp @@ -32,6 +32,7 @@ User::User(const Dictionary::Ptr& serializedUpdate) RegisterAttribute("display_name", Attribute_Config, &m_DisplayName); RegisterAttribute("macros", Attribute_Config, &m_Macros); RegisterAttribute("groups", Attribute_Config, &m_Groups); + RegisterAttribute("notification_period", Attribute_Config, &m_NotificationPeriod); } User::~User(void) @@ -87,6 +88,11 @@ Dictionary::Ptr User::GetMacros(void) const return m_Macros; } +TimePeriod::Ptr User::GetNotificationPeriod(void) const +{ + return TimePeriod::GetByName(m_NotificationPeriod); +} + /** * @threadsafety Always. */ diff --git a/lib/icinga/user.h b/lib/icinga/user.h index dd0e849b6..53d33d243 100644 --- a/lib/icinga/user.h +++ b/lib/icinga/user.h @@ -21,6 +21,7 @@ #define USER_H #include "icinga/i2-icinga.h" +#include "icinga/timeperiod.h" #include "base/dynamicobject.h" #include "base/array.h" @@ -45,6 +46,7 @@ public: String GetDisplayName(void) const; Array::Ptr GetGroups(void) const; + TimePeriod::Ptr GetNotificationPeriod(void) const; Dictionary::Ptr GetMacros(void) const; Dictionary::Ptr CalculateDynamicMacros(void) const; @@ -55,6 +57,7 @@ protected: private: Attribute m_DisplayName; Attribute m_Macros; + Attribute m_NotificationPeriod; Attribute m_Groups; };