[prev in list] [next in list] [prev in thread] [next in thread] 

List:       nagios-devel
Subject:    [Nagios-devel] [PATCH] reduce notification load;
From:       Michael Friedrich <michael.friedrich () univie ! ac ! at>
Date:       2011-11-01 13:05:33
Message-ID: 4EAFEE9D.5070201 () univie ! ac ! at
[Download RAW message or body]

hi,

recently we've been debugging on team icinga in the middle of 
notifications and macros, and while investigating on a users problem, 
we've digged a bit deeper into the notification viability checks, 
resulting in deeper analysis of an Opsview patch to reduce the 
notification load significantly by moving the viability checks from the 
actual notification into the creation of the contacts notified, passing 
only a list of 'qualified' contacts to the actual notification logic. 
the only thing to remark over here is that the checks against the valid 
notification_period now happen sooner, and not actually when the 
notification is sent to each contact.

while implementing that patch into current code (needs some macro 
passing with current code), we did remember nagios bug #98 where the 
$NOTIFICATIONRECEIPIENTS$ macro is demanded to be only populated with 
the actual contacts to be notified, but not all of those assigned to the 
host/service. while this is considered to be a real bug, further 
investigation showed that thanks to the viability checks before calling 
add_notification(), contacts won't be added to that macro as the macro 
logic happens within that function too.

so by applying the attached git patch, you will a. reduce notification 
load and b. fix the $NOTIFICATIONRECEIPIENTS$ macro holding all 
contacts, but not the viable contacts.

since the code remains actually the same on icinga and nagios in this 
stage, the tests can be found at the icinga dev tracker as usual.
https://dev.icinga.org/issues/1744
https://dev.icinga.org/issues/2023

kudos to Opsview Team for their initial patch as well as Icinga 
Development Team for the further analysis on the macro bug.

feel free to apply, matches against latest HEAD.

kind regards,
Michael

-- 
DI (FH) Michael Friedrich

Vienna University Computer Center
Universitaetsstrasse 7 A-1010 Vienna, Austria

email:     michael.friedrich@univie.ac.at
phone:     +43 1 4277 14359
mobile:    +43 664 60277 14359
fax:	   +43 1 4277 14338
web:       http://www.univie.ac.at/zid
            http://www.aco.net

Lead Icinga Core&  IDOUtils Developer
http://www.icinga.org


["0001-reduce-notification-load-fix-NOTIFICATIONRECIPIENTS-.patch" (text/x-diff)]

> From 34d71eb4a947051cc0a1251745b8829245cd2e7d Mon Sep 17 00:00:00 2001
From: Michael Friedrich <michael.friedrich@univie.ac.at>
Date: Tue, 1 Nov 2011 13:35:20 +0100
Subject: [PATCH] reduce notification load; fix $NOTIFICATIONRECIPIENTS$ macro
 #98

1) currently, the list of contacts to be notified is created
and finally on the notification actually happening, the
viability checks happen. this will cause heavy load on systems
with many contacts configured, looping even for the contacts
who won't pass the notification viability tests.
in order to solve that, a patch by Opsview Team was taken into
account, moving the viability checks directly into the notification
list creation before adding a contact to the list.

note: the check against the timeperiod will happen on list creation,
not an actual notification being sent. but that's a minor flaw.

2) while moving the viability checks on list creation, this will
cause that not *all* contacts of the host/service will be added to
the list, but just those actually receiving the notification. the
macro $NOTIFICATIONSRECEIPIENTS$ gets populated in add_notification()
and will therefore hold only those contacts being viable for a
notification.

note: this fixes #98 on the bug tracker.

for further analysis and tests, please refer over here
https://dev.icinga.org/issues/1744
https://dev.icinga.org/issues/2023

kudos to Opsview Team for their initial patch, this has been
reworked into current macro threadsafety logic with some proper
inline comments.
---
 Changelog            |   11 +++++
 base/notifications.c |  106 +++++++++++++++++++++++++++++++++++++-------------
 include/nagios.h     |    4 +-
 3 files changed, 92 insertions(+), 29 deletions(-)

diff --git a/Changelog b/Changelog
index 0a5e9e6..8742ca8 100644
--- a/Changelog
+++ b/Changelog
@@ -2,6 +2,17 @@
 Nagios 3.x Change Log
 #####################
 
+3.x.x - ??/??/????
+
+ENHANCEMENTS
+* reduce notification load by moving notification viability check into notification \
list creation (Opsview Team) +
+FIXES
+* fix $NOTIFICATIONRECIPIENTS$ macro contains all contacts assigned to host|service, \
not only notified contacts (Icinga Development Team) #98 +
+WARNINGS
+
+
 3.3.1 - 07/25/2011
 ------------------
 ENHANCEMENTS
diff --git a/base/notifications.c b/base/notifications.c
index 6f5a5ab..1dbd849 100644
--- a/base/notifications.c
+++ b/base/notifications.c
@@ -108,9 +108,26 @@ int service_notification(service *svc, int type, char \
*not_author, char *not_dat  
 	log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Creating list of contacts to be \
notified.\n");  
-	/* create the contact notification list for this service */
+	/* allocate memory for macros */
 	memset(&mac, 0, sizeof(mac));
-	create_notification_list_from_service(&mac, svc, options, &escalated);
+
+	/* create the contact notification list for this service */
+
+	/* 2011-11-01 MF:  
+	   check viability before adding a contact
+	   to the notification list, requires type
+	   this prevents us from running through all
+	   the steps until notify_contact_of_host|service
+	   is reached. furthermore the $NOTIFICATIONRECIPIENTS$
+	   macro only gets populated with actual recipients,
+	   not all contacts assigned to that host|service.
+
+	   note: checks against timeperiod will happen now(),
+	   and not when the notification is actually being sent.
+
+	   original patch by Opsview Team
+	*/
+	create_notification_list_from_service(&mac, svc, options, &escalated, type);
 
 #ifdef USE_EVENT_BROKER
 	/* send data to event broker */
@@ -696,12 +713,6 @@ int notify_contact_of_service(nagios_macros *mac, contact \
*cntct, service *svc,  
 
 	log_debug_info(DEBUGL_FUNCTIONS, 0, "notify_contact_of_service()\n");
-	log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Attempting to notifying contact \
                '%s'...\n", cntct->name);
-
-	/* check viability of notifying this user */
-	/* acknowledgements are no longer excluded from this test - added 8/19/02 Tom \
                Bertelson */
-	if(check_contact_service_notification_viability(cntct, svc, type, options) == \
                ERROR)
-		return ERROR;
 
 	log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Notifying contact '%s'\n", \
cntct->name);  
@@ -908,8 +919,8 @@ int should_service_notification_be_escalated(service *svc) {
 	}
 
 
-/* given a service, create a list of contacts to be notified, removing duplicates */
-int create_notification_list_from_service(nagios_macros *mac, service *svc, int \
options, int *escalated) { +/* given a service, create a list of contacts to be \
notified, removing duplicates, checking contact notification viability */ +int \
create_notification_list_from_service(nagios_macros *mac, service *svc, int options, \
int *escalated, int type) {  serviceescalation *temp_se = NULL;
 	contactsmember *temp_contactsmember = NULL;
 	contact *temp_contact = NULL;
@@ -954,7 +965,11 @@ int create_notification_list_from_service(nagios_macros *mac, \
service *svc, int  for(temp_contactsmember = temp_se->contacts; temp_contactsmember \
!= NULL; temp_contactsmember = temp_contactsmember->next) {  if((temp_contact = \
temp_contactsmember->contact_ptr) == NULL)  continue;
-				add_notification(mac, temp_contact);
+				/* check now if the contact can be notified */
+				if (check_contact_service_notification_viability(temp_contact, svc, type, \
options) == OK) +					add_notification(mac, temp_contact);
+				else
+					log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact \
'%s'\n",temp_contact->name);  }
 
 			log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact groups from \
service escalation(s) to notification list.\n"); @@ -967,7 +982,11 @@ int \
                create_notification_list_from_service(nagios_macros *mac, service \
                *svc, int
 				for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != \
NULL; temp_contactsmember = temp_contactsmember->next) {  if((temp_contact = \
temp_contactsmember->contact_ptr) == NULL)  continue;
-					add_notification(mac, temp_contact);
+					/* check now if the contact can be notified */
+					if (check_contact_service_notification_viability(temp_contact, svc, type, \
options) == OK) +						add_notification(mac, temp_contact);
+					else
+						log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact \
'%s'\n",temp_contact->name);  }
 				}
 			}
@@ -982,7 +1001,11 @@ int create_notification_list_from_service(nagios_macros *mac, \
service *svc, int  for(temp_contactsmember = svc->contacts; temp_contactsmember != \
NULL; temp_contactsmember = temp_contactsmember->next) {  if((temp_contact = \
temp_contactsmember->contact_ptr) == NULL)  continue;
-			add_notification(mac, temp_contact);
+			/* check now if the contact can be notified */
+                        if \
(check_contact_service_notification_viability(temp_contact, svc, type, options) == \
OK) +                                add_notification(mac, temp_contact);
+                        else
+                                log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding \
contact '%s'\n",temp_contact->name);  }
 
 		/* add all contacts that belong to contactgroups for this service */
@@ -993,7 +1016,11 @@ int create_notification_list_from_service(nagios_macros *mac, \
service *svc, int  for(temp_contactsmember = temp_contactgroup->members; \
temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {  \
if((temp_contact = temp_contactsmember->contact_ptr) == NULL)  continue;
-				add_notification(mac, temp_contact);
+	                        /* check now if the contact can be notified */
+	                        if \
(check_contact_service_notification_viability(temp_contact, svc, type, options) == \
OK) +                                	add_notification(mac, temp_contact);
+	                        else
+	                                log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding \
contact '%s'\n",temp_contact->name);  }
 			}
 		}
@@ -1057,7 +1084,22 @@ int host_notification(host *hst, int type, char *not_author, \
char *not_data, int  log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Creating list of \
contacts to be notified.\n");  
 	/* create the contact notification list for this host */
-	create_notification_list_from_host(&mac, hst, options, &escalated);
+
+        /* 2011-11-01 MF:  
+           check viability before adding a contact
+           to the notification list, requires type
+           this prevents us from running through all
+           the steps until notify_contact_of_host|service
+           is reached. furthermore the $NOTIFICATIONRECIPIENTS$
+           macro only gets populated with actual recipients,
+           not all contacts assigned to that host|service.
+
+           note: checks against timeperiod will happen now(),
+           and not when the notification is actually being sent.
+
+           original patch by Opsview Team
+        */
+	create_notification_list_from_host(&mac, hst, options, &escalated, type);
 
 #ifdef USE_EVENT_BROKER
 	/* send data to event broker */
@@ -1600,12 +1642,6 @@ int notify_contact_of_host(nagios_macros *mac, contact *cntct, \
host *hst, int ty  
 
 	log_debug_info(DEBUGL_FUNCTIONS, 0, "notify_contact_of_host()\n");
-	log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Attempting to notifying contact \
                '%s'...\n", cntct->name);
-
-	/* check viability of notifying this user about the host */
-	/* acknowledgements are no longer excluded from this test - added 8/19/02 Tom \
                Bertelson */
-	if(check_contact_host_notification_viability(cntct, hst, type, options) == ERROR)
-		return ERROR;
 
 	log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Notifying contact '%s'\n", \
cntct->name);  
@@ -1812,8 +1848,8 @@ int should_host_notification_be_escalated(host *hst) {
 	}
 
 
-/* given a host, create a list of contacts to be notified, removing duplicates */
-int create_notification_list_from_host(nagios_macros *mac, host *hst, int options, \
int *escalated) { +/* given a host, create a list of contacts to be notified, \
removing duplicates, checking contact notification viability */ +int \
create_notification_list_from_host(nagios_macros *mac, host *hst, int options, int \
*escalated, int type) {  hostescalation *temp_he = NULL;
 	contactsmember *temp_contactsmember = NULL;
 	contact *temp_contact = NULL;
@@ -1857,7 +1893,11 @@ int create_notification_list_from_host(nagios_macros *mac, \
host *hst, int option  for(temp_contactsmember = temp_he->contacts; \
temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {  \
if((temp_contact = temp_contactsmember->contact_ptr) == NULL)  continue;
-				add_notification(mac, temp_contact);
+				/* check now if the contact can be notified */
+				if (check_contact_host_notification_viability(temp_contact, hst, type, options) \
== OK) +					add_notification(mac, temp_contact);
+				else
+					log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", \
temp_contact->name);  }
 
 			log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact groups from \
host escalation(s) to notification list.\n"); @@ -1870,7 +1910,11 @@ int \
                create_notification_list_from_host(nagios_macros *mac, host *hst, int \
                option
 				for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != \
NULL; temp_contactsmember = temp_contactsmember->next) {  if((temp_contact = \
temp_contactsmember->contact_ptr) == NULL)  continue;
-					add_notification(mac, temp_contact);
+	                                /* check now if the contact can be notified */
+	                                if \
(check_contact_host_notification_viability(temp_contact, hst, type, options) == OK) \
+	                                        add_notification(mac, temp_contact); +	     \
else +	                                        log_debug_info(DEBUGL_NOTIFICATIONS, \
2, "Not adding contact '%s'\n", temp_contact->name);  }
 				}
 			}
@@ -1887,7 +1931,11 @@ int create_notification_list_from_host(nagios_macros *mac, \
host *hst, int option  for(temp_contactsmember = hst->contacts; temp_contactsmember \
!= NULL; temp_contactsmember = temp_contactsmember->next) {  if((temp_contact = \
temp_contactsmember->contact_ptr) == NULL)  continue;
-			add_notification(mac, temp_contact);
+                        /* check now if the contact can be notified */
+                        if (check_contact_host_notification_viability(temp_contact, \
hst, type, options) == OK) +                                add_notification(mac, \
temp_contact); +                        else
+                                log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding \
contact '%s'\n", temp_contact->name);  }
 
 		log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact groups for host \
to notification list.\n"); @@ -1901,7 +1949,11 @@ int \
create_notification_list_from_host(nagios_macros *mac, host *hst, int option  \
for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; \
temp_contactsmember = temp_contactsmember->next) {  if((temp_contact = \
temp_contactsmember->contact_ptr) == NULL)  continue;
-				add_notification(mac, temp_contact);
+	                        /* check now if the contact can be notified */
+	                        if (check_contact_host_notification_viability(temp_contact, \
hst, type, options) == OK) +	                                add_notification(mac, \
temp_contact); +	                        else
+	                                log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding \
contact '%s'\n", temp_contact->name);  }
 			}
 		}
diff --git a/include/nagios.h b/include/nagios.h
index 825182f..998dc9d 100644
--- a/include/nagios.h
+++ b/include/nagios.h
@@ -544,8 +544,8 @@ int should_host_notification_be_escalated(host *);				/* checks \
if a host notifi  int host_notification(host *, int, char *, char *, int);            \
/* notify all contacts about a host (problem or recovery) */  int \
check_contact_host_notification_viability(contact *, host *, int, int);	/* checks \
viability of notifying a contact about a host */  int \
notify_contact_of_host(nagios_macros *mac, contact *, host *, int, char *, char *, \
                int, int);        	/* notify a single contact about a host */
-int create_notification_list_from_host(nagios_macros *mac, host *, int, int *);      \
                /* given a host, create list of contacts to be notified (remove \
                duplicates) */
-int create_notification_list_from_service(nagios_macros *mac, service *, int, int \
*);    		/* given a service, create list of contacts to be notified (remove \
duplicates) */ +int create_notification_list_from_host(nagios_macros *mac, host \
*,int,int *,int);         		/* given a host, create list of contacts to be notified \
(remove duplicates) */ +int create_notification_list_from_service(nagios_macros *mac, \
service *,int,int *,int);    		/* given a service, create list of contacts to be \
notified (remove duplicates) */  int add_notification(nagios_macros *mac, contact \
*);						/* adds a notification instance */  notification *find_notification(contact \
*);					/* finds a notification object */  time_t \
get_next_host_notification_time(host *, time_t);				/* calculates nex acceptable \
                re-notification time for a host */
-- 
1.7.7.1



------------------------------------------------------------------------------
RSA&reg; Conference 2012
Save &#36;700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1

_______________________________________________
Nagios-devel mailing list
Nagios-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nagios-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic