From: Gunnar Beutner Date: Wed, 26 Jun 2013 07:08:50 +0000 (+0200) Subject: Implement notification conditions. X-Git-Tag: v0.0.2~60 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d2b31f6a06aa79dc039c562ecc91c09df6d5d045;p=icinga2 Implement notification conditions. Fixes #2841 --- diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index 94e7fed28..18a91afac 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -52,15 +52,15 @@ static bool LoadConfigFiles(bool validateOnly) ConfigCompilerContext::SetContext(&context); - BOOST_FOREACH(const String& configPath, g_AppParams["config"].as >()) { - ConfigCompiler::CompileFile(configPath); - } - String name, fragment; BOOST_FOREACH(boost::tie(name, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) { ConfigCompiler::CompileText(name, fragment); } + BOOST_FOREACH(const String& configPath, g_AppParams["config"].as >()) { + ConfigCompiler::CompileFile(configPath); + } + ConfigCompilerContext::SetContext(NULL); bool hasError = false; diff --git a/lib/base/scriptvariable.cpp b/lib/base/scriptvariable.cpp index 149ad60a5..6c93513b4 100644 --- a/lib/base/scriptvariable.cpp +++ b/lib/base/scriptvariable.cpp @@ -18,6 +18,7 @@ ******************************************************************************/ #include "base/scriptvariable.h" +#include "base/logger_fwd.h" using namespace icinga; @@ -25,7 +26,11 @@ Registry ScriptVariable::m_Registry; Value ScriptVariable::Get(const String& name) { - return m_Registry.GetItem(name); + Value value = m_Registry.GetItem(name); + if (value.IsEmpty()) + Log(LogWarning, "icinga", "Tried to access empty variable: " + name); + + return value; } void ScriptVariable::Set(const String& name, const Value& value) diff --git a/lib/icinga/icinga-type.conf b/lib/icinga/icinga-type.conf index 37179d212..bac85be1b 100644 --- a/lib/icinga/icinga-type.conf +++ b/lib/icinga/icinga-type.conf @@ -231,6 +231,8 @@ type Service { %attribute number "end", }, + %attribute number "type_filter", + %attribute number "state_filter" } } } @@ -241,6 +243,44 @@ type ServiceGroup { %attribute string "action_url" } +set StateOK = (0) +set StateWarning = (1) +set StateCritical = (2) +set StateUnknown = (3) +set StateUncheckable = (4) + +/* + * Converting states to their filter values: 1< #include #include @@ -45,6 +46,8 @@ Notification::Notification(const Dictionary::Ptr& serializedUpdate) RegisterAttribute("users", Attribute_Config, &m_Users); RegisterAttribute("groups", Attribute_Config, &m_Groups); RegisterAttribute("times", Attribute_Config, &m_Times); + RegisterAttribute("type_filter", Attribute_Config, &m_TypeFilter); + RegisterAttribute("state_filter", Attribute_Config, &m_StateFilter); RegisterAttribute("host_name", Attribute_Config, &m_HostName); RegisterAttribute("service", Attribute_Config, &m_Service); RegisterAttribute("export_macros", Attribute_Config, &m_ExportMacros); @@ -139,6 +142,22 @@ Dictionary::Ptr Notification::GetTimes(void) const return m_Times; } +unsigned long Notification::GetTypeFilter(void) const +{ + if (m_TypeFilter.IsEmpty()) + return ~(unsigned long)0; /* All states. */ + else + return m_TypeFilter; +} + +unsigned long Notification::GetStateFilter(void) const +{ + if (m_StateFilter.IsEmpty()) + return ~(unsigned long)0; /* All states. */ + else + return m_StateFilter; +} + double Notification::GetNotificationInterval(void) const { if (m_NotificationInterval.IsEmpty()) @@ -238,6 +257,24 @@ void Notification::BeginExecuteNotification(NotificationType type, const Diction Log(LogInformation, "icinga", "Not sending notifications for notification object '" + GetName() + "': after escalation range"); return; } + + unsigned long ftype = 1 << type; + + Log(LogDebug, "icinga", "FType=" + Convert::ToString(ftype) + ", TypeFilter=" + Convert::ToString(GetTypeFilter())); + + if (!(ftype & GetTypeFilter())) { + Log(LogInformation, "icinga", "Not sending notifications for notification object '" + GetName() + "': type filter does not match"); + return; + } + + unsigned long fstate = 1 << GetService()->GetState(); + + Log(LogDebug, "icinga", "FState=" + Convert::ToString(fstate) + ", StateFilter=" + Convert::ToString(GetStateFilter())); + + if (!(fstate & GetStateFilter())) { + Log(LogInformation, "icinga", "Not sending notifications for notification object '" + GetName() + "': state filter does not match"); + return; + } } { @@ -262,11 +299,11 @@ void Notification::BeginExecuteNotification(NotificationType type, const Diction } } -void Notification::ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const Dictionary::Ptr& cr, bool ignore_timeperiod) +void Notification::ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const Dictionary::Ptr& cr, bool force) { ASSERT(!OwnsLock()); - if (!ignore_timeperiod) { + if (!force) { TimePeriod::Ptr tp = user->GetNotificationPeriod(); if (tp && !tp->IsInside(Utility::GetTime())) { @@ -274,6 +311,22 @@ void Notification::ExecuteNotificationHelper(NotificationType type, const User:: GetName() + " and user '" + user->GetName() + "': user not in timeperiod"); return; } + + unsigned long ftype = 1 << type; + + if (!(ftype & user->GetTypeFilter())) { + Log(LogInformation, "icinga", "Not sending notifications for notification object '" + + GetName() + " and user '" + user->GetName() + "': type filter does not match"); + return; + } + + unsigned long fstate = 1 << GetService()->GetState(); + + if (!(fstate & user->GetStateFilter())) { + Log(LogInformation, "icinga", "Not sending notifications for notification object '" + + GetName() + " and user '" + user->GetName() + "': state filter does not match"); + return; + } } try { diff --git a/lib/icinga/notification.h b/lib/icinga/notification.h index 95024a0d6..6fa736253 100644 --- a/lib/icinga/notification.h +++ b/lib/icinga/notification.h @@ -36,15 +36,15 @@ namespace icinga */ enum NotificationType { - NotificationDowntimeStart, - NotificationDowntimeEnd, - NotificationDowntimeRemoved, - NotificationCustom, - NotificationAcknowledgement, - NotificationProblem, - NotificationRecovery, - NotificationFlappingStart, - NotificationFlappingEnd, + NotificationDowntimeStart = 0, + NotificationDowntimeEnd = 1, + NotificationDowntimeRemoved = 2, + NotificationCustom = 3, + NotificationAcknowledgement = 4, + NotificationProblem = 5, + NotificationRecovery = 6, + NotificationFlappingStart = 7 , + NotificationFlappingEnd = 8, }; class Service; @@ -75,6 +75,8 @@ public: std::set GetUsers(void) const; std::set GetGroups(void) const; Dictionary::Ptr GetTimes(void) const; + unsigned long GetTypeFilter(void) const; + unsigned long GetStateFilter(void) const; double GetLastNotification(void) const; void SetLastNotification(double time); @@ -102,6 +104,8 @@ private: Attribute m_Users; Attribute m_Groups; Attribute m_Times; + Attribute m_TypeFilter; + Attribute m_StateFilter; Attribute m_HostName; Attribute m_Service; diff --git a/lib/icinga/user.cpp b/lib/icinga/user.cpp index c0cabb492..2b740963a 100644 --- a/lib/icinga/user.cpp +++ b/lib/icinga/user.cpp @@ -34,6 +34,8 @@ User::User(const Dictionary::Ptr& serializedUpdate) RegisterAttribute("macros", Attribute_Config, &m_Macros); RegisterAttribute("groups", Attribute_Config, &m_Groups); RegisterAttribute("notification_period", Attribute_Config, &m_NotificationPeriod); + RegisterAttribute("type_filter", Attribute_Config, &m_TypeFilter); + RegisterAttribute("state_filter", Attribute_Config, &m_StateFilter); } User::~User(void) @@ -79,6 +81,22 @@ TimePeriod::Ptr User::GetNotificationPeriod(void) const return TimePeriod::GetByName(m_NotificationPeriod); } +unsigned long User::GetTypeFilter(void) const +{ + if (m_TypeFilter.IsEmpty()) + return ~(unsigned long)0; /* All states. */ + else + return m_TypeFilter; +} + +unsigned long User::GetStateFilter(void) const +{ + if (m_StateFilter.IsEmpty()) + return ~(unsigned long)0; /* All states. */ + else + return m_StateFilter; +} + bool User::ResolveMacro(const String& macro, const Dictionary::Ptr& cr, String *result) const { if (macro == "CONTACTNAME") { diff --git a/lib/icinga/user.h b/lib/icinga/user.h index f8f89a649..855a8ecdc 100644 --- a/lib/icinga/user.h +++ b/lib/icinga/user.h @@ -48,6 +48,8 @@ public: String GetDisplayName(void) const; Array::Ptr GetGroups(void) const; TimePeriod::Ptr GetNotificationPeriod(void) const; + unsigned long GetTypeFilter(void) const; + unsigned long GetStateFilter(void) const; Dictionary::Ptr GetMacros(void) const; @@ -61,6 +63,8 @@ private: Attribute m_Macros; Attribute m_NotificationPeriod; Attribute m_Groups; + Attribute m_TypeFilter; + Attribute m_StateFilter; }; }