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.friedr...@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
>From 34d71eb4a947051cc0a1251745b8829245cd2e7d Mon Sep 17 00:00:00 2001
From: Michael Friedrich <michael.friedr...@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® Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Nagios-users mailing list
Nagios-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nagios-users
::: Please include Nagios version, plugin version (-v) and OS when reporting
any issue.
::: Messages without supporting info will risk being sent to /dev/null