summaryrefslogtreecommitdiffstats
path: root/src/zabbix_server
diff options
context:
space:
mode:
authorsasha <sasha@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2008-05-27 08:24:17 +0000
committersasha <sasha@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2008-05-27 08:24:17 +0000
commitc0bfb062b8ac422278fbd5b299ecbef51203011b (patch)
tree0d21b48a18b42a9fafeb19236cff97f50436bc3a /src/zabbix_server
parent1528814bf6b442cc01211b9f0b3f2adaadf970f4 (diff)
downloadzabbix-c0bfb062b8ac422278fbd5b299ecbef51203011b.tar.gz
zabbix-c0bfb062b8ac422278fbd5b299ecbef51203011b.tar.xz
zabbix-c0bfb062b8ac422278fbd5b299ecbef51203011b.zip
- [DEV-173] added support of notification escalations on server side
git-svn-id: svn://svn.zabbix.com/trunk@5725 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'src/zabbix_server')
-rw-r--r--src/zabbix_server/Makefile.am4
-rw-r--r--src/zabbix_server/actions.c34
-rw-r--r--src/zabbix_server/actions.h1
-rw-r--r--src/zabbix_server/alerter/alerter.c118
-rw-r--r--src/zabbix_server/escalator/Makefile.am5
-rw-r--r--src/zabbix_server/escalator/escalator.c679
-rw-r--r--src/zabbix_server/escalator/escalator.h27
-rw-r--r--src/zabbix_server/events.c4
-rw-r--r--src/zabbix_server/events.h1
-rw-r--r--src/zabbix_server/operations.c59
-rw-r--r--src/zabbix_server/operations.h6
-rw-r--r--src/zabbix_server/server.c18
12 files changed, 850 insertions, 106 deletions
diff --git a/src/zabbix_server/Makefile.am b/src/zabbix_server/Makefile.am
index 9e2874fb..e9313db1 100644
--- a/src/zabbix_server/Makefile.am
+++ b/src/zabbix_server/Makefile.am
@@ -12,7 +12,8 @@ SUBDIRS = \
timer \
trapper \
utils \
- watchdog
+ watchdog \
+ escalator
sbin_PROGRAMS = zabbix_server
@@ -40,6 +41,7 @@ zabbix_server_LDADD = \
utils/libzbxutils.a \
httppoller/libzbxhttppoller.a \
watchdog/libzbxwatchdog.a \
+ escalator/libzbxescalator.a \
$(top_srcdir)/src/libs/zbxsysinfo/libzbxserversysinfo.a \
$(top_srcdir)/src/libs/zbxsysinfo/$(ARCH)/libspecsysinfo.a \
$(top_srcdir)/src/libs/zbxsysinfo/common/libcommonsysinfo.a \
diff --git a/src/zabbix_server/actions.c b/src/zabbix_server/actions.c
index 565f3d07..103402d1 100644
--- a/src/zabbix_server/actions.c
+++ b/src/zabbix_server/actions.c
@@ -65,7 +65,7 @@
* Comments: *
* *
******************************************************************************/
-static int check_action_condition(DB_EVENT *event, DB_CONDITION *condition)
+int check_action_condition(DB_EVENT *event, DB_CONDITION *condition)
{
DB_RESULT result;
DB_ROW row;
@@ -333,6 +333,25 @@ static int check_action_condition(DB_EVENT *event, DB_CONDITION *condition)
condition->conditionid);
}
}
+ else if(event->source == EVENT_SOURCE_TRIGGERS && condition->conditiontype == CONDITION_TYPE_EVENT_ACKNOWLEDGED)
+ {
+ result = DBselect("select count(*) from acknowledges where eventid=" ZBX_FS_UI64,
+ event->eventid);
+
+ value_int = (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0]) && 0 != atoi(row[0])) ? 1 : 0;
+
+ DBfree_result(result);
+
+zabbix_log(LOG_LEVEL_ERR, "----- operator:%d value:%s:%d=%d", condition->operator, condition->value, atoi(condition->value), value_int);
+ if(condition->operator == CONDITION_OPERATOR_EQUAL) {
+ if (value_int == atoi(condition->value))
+ ret = SUCCEED;
+ } else {
+ zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
+ condition->operator,
+ condition->conditionid);
+ }
+ }
else if(event->source == EVENT_SOURCE_DISCOVERY &&
event->object == EVENT_OBJECT_DSERVICE &&
condition->conditiontype == CONDITION_TYPE_DVALUE)
@@ -730,12 +749,12 @@ void execute_operations(DB_EVENT *event, DB_ACTION *action)
switch(operation.operationtype)
{
- case OPERATION_TYPE_MESSAGE:
+/* case OPERATION_TYPE_MESSAGE:
op_notify_user(event,action,&operation);
break;
case OPERATION_TYPE_COMMAND:
op_run_commands(event,&operation);
- break;
+ break;*/
case OPERATION_TYPE_HOST_ADD:
op_host_add(event);
break;
@@ -807,12 +826,17 @@ void process_actions(DB_EVENT *event)
{
zabbix_log( LOG_LEVEL_DEBUG, "Conditions match our event. Execute operations.");
- execute_operations(event, &action);
-
+ if (event->source == EVENT_SOURCE_TRIGGERS && event->object == EVENT_OBJECT_TRIGGER)
+ DBstart_escalation(action.actionid, event->objectid, event->eventid);
+ else
+ execute_operations(event, &action);
}
else
{
zabbix_log( LOG_LEVEL_DEBUG, "Conditions do not match our event. Do not execute operations.");
+
+ if (event->source == EVENT_SOURCE_TRIGGERS && event->object == EVENT_OBJECT_TRIGGER)
+ DBstop_escalation(action.actionid, event->objectid);
}
}
DBfree_result(result);
diff --git a/src/zabbix_server/actions.h b/src/zabbix_server/actions.h
index eb2ab1f5..cdda16c1 100644
--- a/src/zabbix_server/actions.h
+++ b/src/zabbix_server/actions.h
@@ -24,6 +24,7 @@
#include "common.h"
#include "db.h"
+int check_action_condition(DB_EVENT *event, DB_CONDITION *condition);
void process_actions(DB_EVENT *event);
#endif
diff --git a/src/zabbix_server/alerter/alerter.c b/src/zabbix_server/alerter/alerter.c
index 196f3601..26f0920f 100644
--- a/src/zabbix_server/alerter/alerter.c
+++ b/src/zabbix_server/alerter/alerter.c
@@ -66,22 +66,22 @@ int execute_action(DB_ALERT *alert,DB_MEDIATYPE *mediatype, char *error, int max
zabbix_log( LOG_LEVEL_DEBUG, "In execute_action(%s)",
mediatype->smtp_server);
- if(mediatype->type==ALERT_TYPE_EMAIL)
+ if(mediatype->type==MEDIA_TYPE_EMAIL)
{
res = send_email(mediatype->smtp_server,mediatype->smtp_helo,mediatype->smtp_email,alert->sendto,alert->subject,
alert->message, error, max_error_len);
}
#if defined (HAVE_JABBER)
- else if(mediatype->type==ALERT_TYPE_JABBER)
+ else if(mediatype->type==MEDIA_TYPE_JABBER)
{
res = send_jabber(mediatype->username, mediatype->passwd, alert->sendto, alert->message, error, max_error_len);
}
#endif /* HAVE_JABBER */
- else if(mediatype->type==ALERT_TYPE_SMS)
+ else if(mediatype->type==MEDIA_TYPE_SMS)
{
res = send_sms(mediatype->gsm_modem,alert->sendto,alert->message, error, max_error_len);
}
- else if(mediatype->type==ALERT_TYPE_EXEC)
+ else if(mediatype->type==MEDIA_TYPE_EXEC)
{
/* if(-1 == execl(CONFIG_ALERT_SCRIPTS_PATH,mediatype->exec_path,alert->sendto,alert->subject,alert->message))*/
zabbix_log( LOG_LEVEL_DEBUG, "Before execl([%s],[%s])",
@@ -175,68 +175,67 @@ int execute_action(DB_ALERT *alert,DB_MEDIATYPE *mediatype, char *error, int max
******************************************************************************/
int main_alerter_loop()
{
- char error[MAX_STRING_LEN];
- char error_esc[MAX_STRING_LEN];
-
- int res, now;
-
- struct sigaction phan;
-
- DB_RESULT result;
- DB_ROW row;
- DB_ALERT alert;
- DB_MEDIATYPE mediatype;
-
- for(;;)
- {
- zbx_setproctitle("connecting to the database");
-
- DBconnect(ZBX_DB_CONNECT_NORMAL);
-
- now = time(NULL);
-
- result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid,mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path,mt.gsm_modem,mt.username,mt.passwd,a.retries from alerts a,media_type mt where a.status=%d and a.mediatypeid=mt.mediatypeid" DB_NODE " order by a.clock",
- ALERT_STATUS_NOT_SENT,
- DBnode_local("mt.mediatypeid"));
-
- while((row=DBfetch(result)))
- {
+ char error[MAX_STRING_LEN], *error_esc;
+ int res, now;
+ struct sigaction phan;
+ DB_RESULT result;
+ DB_ROW row;
+ DB_ALERT alert;
+ DB_MEDIATYPE mediatype;
+
+ phan.sa_handler = child_signal_handler;
+ sigemptyset(&phan.sa_mask);
+ phan.sa_flags = 0;
+ sigaction(SIGALRM, &phan, NULL);
+
+ zbx_setproctitle("connecting to the database");
+
+ DBconnect(ZBX_DB_CONNECT_NORMAL);
+
+ for (;;) {
+ now = time(NULL);
+
+ result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid"
+ ",mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path"
+ ",mt.gsm_modem,mt.username,mt.passwd,a.retries from alerts a,media_type mt"
+ " where a.status=%d and a.mediatypeid=mt.mediatypeid and a.alerttype=%d" DB_NODE
+ " order by a.clock",
+ ALERT_STATUS_NOT_SENT,
+ ALERT_TYPE_MESSAGE,
+ DBnode_local("mt.mediatypeid"));
+
+ while (NULL != (row = DBfetch(result))) {
res = FAIL;
- ZBX_STR2UINT64(alert.alertid,row[0]);
- alert.mediatypeid=atoi(row[1]);
- alert.sendto=row[2];
- alert.subject=row[3];
- alert.message=row[4];
- alert.status=atoi(row[5]);
-
- ZBX_STR2UINT64(mediatype.mediatypeid,row[6]);
- mediatype.type=atoi(row[7]);
- mediatype.description=row[8];
- mediatype.smtp_server=row[9];
- mediatype.smtp_helo=row[10];
- mediatype.smtp_email=row[11];
- mediatype.exec_path=row[12];
+ ZBX_STR2UINT64(alert.alertid, row[0]);
+ alert.mediatypeid = atoi(row[1]);
+ alert.sendto = row[2];
+ alert.subject = row[3];
+ alert.message = row[4];
+ alert.status = atoi(row[5]);
- mediatype.gsm_modem=row[13];
- mediatype.username=row[14];
- mediatype.passwd=row[15];
+ ZBX_STR2UINT64(mediatype.mediatypeid, row[6]);
+ mediatype.type = atoi(row[7]);
+ mediatype.description = row[8];
+ mediatype.smtp_server = row[9];
+ mediatype.smtp_helo = row[10];
+ mediatype.smtp_email = row[11];
+ mediatype.exec_path = row[12];
- alert.retries=atoi(row[16]);
+ mediatype.gsm_modem = row[13];
+ mediatype.username = row[14];
+ mediatype.passwd = row[15];
- phan.sa_handler = child_signal_handler;
- sigemptyset(&phan.sa_mask);
- phan.sa_flags = 0;
- sigaction(SIGALRM, &phan, NULL);
+ alert.retries = atoi(row[16]);
/* Hardcoded value */
/* SMS uses its own timeouts */
alarm(40);
*error = '\0';
- res = execute_action(&alert,&mediatype,error,sizeof(error));
+ res = execute_action(&alert, &mediatype, error, sizeof(error));
alarm(0);
- if(res==SUCCEED)
+ if (res == SUCCEED)
{
zabbix_log( LOG_LEVEL_DEBUG, "Alert ID [" ZBX_FS_UI64 "] was sent successfully",
alert.alertid);
@@ -250,7 +249,7 @@ int main_alerter_loop()
alert.alertid);
zabbix_syslog("Error sending alert ID [" ZBX_FS_UI64 "]",
alert.alertid);
- DBescape_string(error,error_esc,MAX_STRING_LEN);
+ error_esc = DBdyn_escape_string(error);
alert.retries++;
if(alert.retries < ALERT_MAX_RETRIES)
@@ -268,16 +267,19 @@ int main_alerter_loop()
error_esc,
alert.alertid);
}
+
+ zbx_free(error_esc);
}
}
DBfree_result(result);
- DBclose();
-
zbx_setproctitle("sender [sleeping for %d seconds]",
- CONFIG_SENDER_FREQUENCY);
+ CONFIG_SENDER_FREQUENCY);
sleep(CONFIG_SENDER_FREQUENCY);
}
+
+ /* Never reached */
+ DBclose();
}
diff --git a/src/zabbix_server/escalator/Makefile.am b/src/zabbix_server/escalator/Makefile.am
new file mode 100644
index 00000000..27204d6b
--- /dev/null
+++ b/src/zabbix_server/escalator/Makefile.am
@@ -0,0 +1,5 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libzbxescalator.a
+
+libzbxescalator_a_SOURCES = escalator.c escalator.h
diff --git a/src/zabbix_server/escalator/escalator.c b/src/zabbix_server/escalator/escalator.c
new file mode 100644
index 00000000..81b730d9
--- /dev/null
+++ b/src/zabbix_server/escalator/escalator.c
@@ -0,0 +1,679 @@
+/*
+** ZABBIX
+** Copyright (C) 2000-2005 SIA Zabbix
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**/
+
+#include "common.h"
+#include "db.h"
+#include "log.h"
+#include "zlog.h"
+#include "daemon.h"
+#include "zbxserver.h"
+
+#include "escalator.h"
+#include "../operations.h"
+#include "../events.h"
+#include "../actions.h"
+
+#define CONFIG_ESCALATOR_FREQUENCY 5
+
+#define ZBX_USER_MSG struct zxb_user_msg_t
+ZBX_USER_MSG
+{
+ zbx_uint64_t userid;
+ char *subject;
+ char *message;
+ void *next;
+};
+
+static void add_user_msg(DB_OPERATION *operation, ZBX_USER_MSG **user_msg, char *subject, char *message)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ ZBX_USER_MSG *p;
+ zbx_uint64_t userid;
+
+ switch (operation->object) {
+ case OPERATION_OBJECT_USER:
+ case OPERATION_OBJECT_GROUP:
+ /* user group disabled ? */
+ result = DBselect("select ug.userid from users_groups ug,usrgrp g"
+ " WHERE ug.%s=" ZBX_FS_UI64 " AND g.usrgrpid=ug.usrgrpid AND g.users_status=%d",
+ operation->object == OPERATION_OBJECT_USER ? "userid" : "usrgrpid",
+ operation->objectid,
+ GROUP_STATUS_ACTIVE);
+
+ while (NULL != (row = DBfetch(result))) {
+ userid = zbx_atoui64(row[0]);
+
+ p = *user_msg;
+ while (NULL != p) {
+ if (p->userid == userid && 0 == strcmp(p->subject, subject)
+ && 0 == strcmp(p->message, message))
+ break;
+
+ p = p->next;
+ }
+
+ if (NULL == p) {
+ p = zbx_malloc(p, sizeof(ZBX_USER_MSG));
+
+ p->userid = userid;
+ p->subject = strdup(subject);
+ p->message = strdup(message);
+ p->next = *user_msg;
+
+ *user_msg = p;
+
+ }
+ }
+
+ DBfree_result(result);
+ break;
+ default:
+ zabbix_log(LOG_LEVEL_WARNING, "Unknown object type [%d] for operationid [" ZBX_FS_UI64 "]",
+ operation->object,
+ operation->operationid);
+ zabbix_syslog("Unknown object type [%d] for operationid [" ZBX_FS_UI64 "]",
+ operation->object,
+ operation->operationid);
+ break;
+ }
+}
+
+static void add_command_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action, char *command)
+{
+ zbx_uint64_t alertid;
+ int now;
+ char *command_esc = NULL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In add_command_alert()");
+/* zabbix_log(LOG_LEVEL_DEBUG,"----- COMMAND\n\tcommand: %s", command);*/
+
+ alertid = DBget_maxid("alerts", "alertid");
+ now = time(NULL);
+ command_esc = DBdyn_escape_string(command);
+
+ DBexecute("insert into alerts (alertid,actionid,eventid,clock,message,status,alerttype,esc_step)"
+ " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,'%s',%d,%d,%d)",
+ alertid,
+ action->actionid,
+ event->eventid,
+ now,
+ command_esc,
+ ALERT_STATUS_NOT_SENT,
+ ALERT_TYPE_COMMAND,
+ escalation->esc_step);
+
+ op_run_commands(command);
+
+ zbx_free(command_esc);
+}
+
+static void add_message_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action, zbx_uint64_t userid, char *subject, char *message)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ zbx_uint64_t alertid, mediatypeid;
+ int now, severity, medias = 0;
+ char *sendto_esc = NULL;
+ char *subject_esc = NULL;
+ char *message_esc = NULL;
+ char *error_esc = NULL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In add_message_alert()");
+/* zabbix_log(LOG_LEVEL_DEBUG,"MESSAGE\n\tuserid : " ZBX_FS_UI64 "\n\tsubject: %s\n\tmessage: %s", userid, subject, message);*/
+
+ now = time(NULL);
+ subject_esc = DBdyn_escape_string(subject);
+ message_esc = DBdyn_escape_string(message);
+
+ result = DBselect("select mediatypeid,sendto,severity,period from media"
+ " where active=%d and userid=" ZBX_FS_UI64,
+ MEDIA_STATUS_ACTIVE,
+ userid);
+
+ while (NULL != (row = DBfetch(result))) {
+ medias = 1;
+
+ mediatypeid = zbx_atoui64(row[0]);
+ severity = atoi(row[2]);
+
+ zabbix_log( LOG_LEVEL_DEBUG, "Trigger severity [%d] Media severity [%d] Period [%s]",
+ event->trigger_priority,
+ severity,
+ row[3]);
+
+ if (((1 << event->trigger_priority) & severity) == 0) {
+ zabbix_log( LOG_LEVEL_DEBUG, "Won't send message (severity)");
+ continue;
+ }
+
+ if (check_time_period(row[3], (time_t)NULL) == 0) {
+ zabbix_log( LOG_LEVEL_DEBUG, "Won't send message (period)");
+ continue;
+ }
+
+ alertid = DBget_maxid("alerts", "alertid");
+ sendto_esc = DBdyn_escape_string(row[1]);
+
+ DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock"
+ ",mediatypeid,sendto,subject,message,status,alerttype,esc_step)"
+ " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d"
+ "," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d)",
+ alertid,
+ action->actionid,
+ event->eventid,
+ userid,
+ now,
+ mediatypeid,
+ sendto_esc,
+ subject_esc,
+ message_esc,
+ ALERT_STATUS_NOT_SENT,
+ ALERT_TYPE_MESSAGE,
+ escalation->esc_step);
+
+ zbx_free(sendto_esc);
+ }
+
+ DBfree_result(result);
+
+ if (0 == medias) {
+ alertid = DBget_maxid("alerts", "alertid");
+ error_esc = DBdyn_escape_string("No media defined");
+
+ DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock"
+ ",subject,message,status,alerttype,error,esc_step)"
+ " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d"
+ ",'%s','%s',%d,%d,'%s',%d)",
+ alertid,
+ action->actionid,
+ event->eventid,
+ userid,
+ now,
+ subject_esc,
+ message_esc,
+ ALERT_STATUS_FAILED,
+ ALERT_TYPE_MESSAGE,
+ error_esc,
+ escalation->esc_step);
+
+ zbx_free(error_esc);
+ }
+
+ zbx_free(subject_esc);
+ zbx_free(message_esc);
+}
+
+/******************************************************************************
+ * *
+ * Function: check_operation_conditions *
+ * *
+ * Purpose: *
+ * *
+ * Parameters: event - event to check *
+ * actionid - action ID for matching *
+ * *
+ * Return value: SUCCEED - matches, FAIL - otherwise *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+static int check_operation_conditions(DB_EVENT *event, DB_OPERATION *operation)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ DB_CONDITION condition;
+
+ /* SUCCEED required for ACTION_EVAL_TYPE_AND_OR */
+ int ret = SUCCEED;
+ int old_type = -1;
+ int cond;
+ int num = 0;
+ int exit = 0;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In check_opeartion_conditions (operationid:" ZBX_FS_UI64 ")",
+ operation->operationid);
+
+ result = DBselect("select conditiontype,operator,value from opconditions where operationid=" ZBX_FS_UI64 " order by conditiontype",
+ operation->operationid);
+
+ while (NULL != (row = DBfetch(result)) && (0 == exit)) {
+ num++;
+
+ memset(&condition, 0, sizeof(condition));
+ condition.conditiontype = atoi(row[0]);
+ condition.operator = atoi(row[1]);
+ condition.value = row[2];
+
+ switch (operation->evaltype) {
+ case ACTION_EVAL_TYPE_AND_OR:
+ if (old_type == condition.conditiontype) { /* OR conditions */
+ if (SUCCEED == check_action_condition(event, &condition))
+ ret = SUCCEED;
+ } else { /* AND conditions */
+ /* Break if PREVIOUS AND condition is FALSE */
+ if (ret == FAIL)
+ exit = 1;
+ else if (FAIL == check_action_condition(event, &condition))
+ ret = FAIL;
+ }
+
+ old_type = condition.conditiontype;
+ break;
+ case ACTION_EVAL_TYPE_AND:
+ cond = check_action_condition(event, &condition);
+ /* Break if any of AND conditions is FALSE */
+ if(cond == FAIL) {
+ ret = FAIL;
+ exit = 1;
+ } else
+ ret = SUCCEED;
+ break;
+ case ACTION_EVAL_TYPE_OR:
+ cond = check_action_condition(event, &condition);
+ /* Break if any of OR conditions is TRUE */
+ if (cond == SUCCEED) {
+ ret = SUCCEED;
+ exit = 1;
+ } else
+ ret = FAIL;
+ break;
+ default:
+ ret = FAIL;
+ exit = 1;
+ break;
+
+ }
+
+ }
+ DBfree_result(result);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End check_opeartion_conditions():%s",
+ FAIL == ret ? "FALSE" : "TRUE");
+
+ return ret;
+}
+
+static void execute_operations(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ DB_OPERATION operation;
+ int esc_period = 0, operations = 0;
+ ZBX_USER_MSG *user_msg = NULL, *p;
+ char *shortdata, *longdata;
+
+ if (0 == action->esc_period)
+ result = DBselect("select operationid,operationtype,object,objectid,default_msg,shortdata,longdata"
+ ",esc_period,evaltype from operations where actionid=" ZBX_FS_UI64,
+ action->actionid);
+ else {
+ escalation->esc_step++;
+
+ result = DBselect("select operationid,operationtype,object,objectid,default_msg,shortdata,longdata"
+ ",esc_period,evaltype from operations where actionid=" ZBX_FS_UI64
+ " and esc_step_from<=%d and (esc_step_to=0 or esc_step_to>=%d)",
+ action->actionid,
+ escalation->esc_step,
+ escalation->esc_step);
+ }
+
+ while (NULL != (row = DBfetch(result))) {
+ memset(&operation, 0, sizeof(operation));
+ operation.operationid = zbx_atoui64(row[0]);
+ operation.actionid = action->actionid;
+ operation.operationtype = atoi(row[1]);
+ operation.object = atoi(row[2]);
+ operation.objectid = zbx_atoui64(row[3]);
+ operation.default_msg = atoi(row[4]);
+ operation.shortdata = strdup(row[5]);
+ operation.longdata = strdup(row[6]);
+ operation.esc_period = atoi(row[7]);
+ operation.evaltype = atoi(row[8]);
+
+ if (SUCCEED == check_operation_conditions(event, &operation)) {
+ zabbix_log(LOG_LEVEL_DEBUG, "Conditions match our event. Execute operation.");
+
+ substitute_macros(event, action, &operation.shortdata);
+ substitute_macros(event, action, &operation.longdata);
+
+ if (0 == esc_period || esc_period > operation.esc_period)
+ esc_period = operation.esc_period;
+
+ switch (operation.operationtype) {
+ case OPERATION_TYPE_MESSAGE:
+ if (0 == operation.default_msg) {
+ shortdata = operation.shortdata;
+ longdata = operation.longdata;
+ } else {
+ shortdata = action->shortdata;
+ longdata = action->longdata;
+ }
+
+ add_user_msg(&operation, &user_msg, shortdata, longdata);
+ break;
+ case OPERATION_TYPE_COMMAND:
+ add_command_alert(escalation, event, action, operation.longdata);
+ break;
+ default:
+ break;
+ }
+ } else
+ zabbix_log(LOG_LEVEL_DEBUG, "Conditions do not match our event. Do not execute operation.");
+
+ zbx_free(operation.shortdata);
+ zbx_free(operation.longdata);
+
+ operations = 1;
+ }
+
+ DBfree_result(result);
+
+ while (NULL != user_msg) {
+ p = user_msg;
+ user_msg = user_msg->next;
+
+ add_message_alert(escalation, event, action, p->userid, p->subject, p->message);
+
+ zbx_free(p->subject);
+ zbx_free(p->message);
+ zbx_free(p);
+ }
+
+ if (0 == action->esc_period)
+ escalation->status = ESCALATION_STATUS_COMPLETED;
+ else {
+ if (0 == operations) {
+ result = DBselect("select operationid from operations where actionid=" ZBX_FS_UI64 " and esc_step_from>%d",
+ action->actionid,
+ escalation->esc_step);
+
+ if (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0]))
+ operations = 1;
+
+ DBfree_result(result);
+ }
+
+ if (1 == operations) {
+ esc_period = (0 != esc_period) ? esc_period : action->esc_period;
+ escalation->nextcheck = time(NULL) + esc_period;
+ } else
+ escalation->status = ESCALATION_STATUS_COMPLETED;
+ }
+}
+
+static void process_recovery_msg(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ zbx_uint64_t userid;
+
+ if (1 == action->recovery_msg) {
+ result = DBselect("select distinct userid from alerts where actionid=" ZBX_FS_UI64 " and eventid=" ZBX_FS_UI64,
+ action->actionid,
+ event->eventid);
+
+ while (NULL != (row = DBfetch(result))) {
+ userid = zbx_atoui64(row[0]);
+
+ add_message_alert(escalation, event, action, userid, action->shortdata, action->longdata);
+ }
+
+ DBfree_result(result);
+ } else {
+ zabbix_log(LOG_LEVEL_DEBUG, "Escalation stopped: recovery message not defined",
+ escalation->actionid);
+ DBremove_escalation(escalation->escalationid);
+ }
+
+ escalation->status = ESCALATION_STATUS_COMPLETED;
+}
+
+static void execute_escalation(DB_ESCALATION *escalation, DB_EVENT *event)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ DB_ACTION action;
+
+ switch (escalation->status) {
+ case ESCALATION_STATUS_ACTIVE:
+ result = DBselect("select actionid,eventsource,esc_period,shortdata,longdata"
+ " from actions where actionid=" ZBX_FS_UI64,
+ escalation->actionid);
+ break;
+ case ESCALATION_STATUS_RECOVERY:
+ result = DBselect("select actionid,eventsource,esc_period,r_shortdata,r_longdata,recovery_msg"
+ " from actions where actionid=" ZBX_FS_UI64,
+ escalation->actionid);
+ break;
+ default:
+ /* Never reached */
+ return;
+ }
+
+ if (NULL != (row = DBfetch(result))) {
+ memset(&action, 0, sizeof(action));
+ action.actionid = zbx_atoui64(row[0]);
+ action.eventsource = atoi(row[1]);
+ action.esc_period = atoi(row[2]);
+ action.shortdata = strdup(row[3]);
+ action.longdata = strdup(row[4]);
+ action.recovery_msg = atoi(row[5]);
+
+ substitute_macros(event, &action, &action.shortdata);
+ substitute_macros(event, &action, &action.longdata);
+
+ switch (escalation->status) {
+ case ESCALATION_STATUS_ACTIVE:
+ execute_operations(escalation, event, &action);
+ break;
+ case ESCALATION_STATUS_RECOVERY:
+ process_recovery_msg(escalation, event, &action);
+ break;
+ default:
+ break;
+ }
+
+ zbx_free(action.shortdata);
+ zbx_free(action.longdata);
+ } else {
+ zabbix_log(LOG_LEVEL_DEBUG, "Escalation canceled: action [" ZBX_FS_UI64 "] not found",
+ escalation->actionid);
+ DBremove_escalation(escalation->escalationid);
+ }
+
+ DBfree_result(result);
+}
+
+static void process_escalations(int now)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ DB_ESCALATION escalation;
+ DB_EVENT event;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In process_escalations()");
+
+ result = DBselect("select e.escalationid,e.actionid,e.esc_step,e.status,ev.eventid"
+ ",ev.source,ev.object,ev.objectid,ev.clock,ev.value,ev.acknowledged"
+ " from escalations e,events ev where e.eventid=ev.eventid"
+ " and e.status in (%d,%d) and e.nextcheck<=%d" DB_NODE,
+ ESCALATION_STATUS_ACTIVE,
+ ESCALATION_STATUS_RECOVERY,
+ now,
+ DBnode_local("escalationid"));
+
+ while (NULL != (row = DBfetch(result))) {
+ memset(&escalation, 0, sizeof(escalation));
+ escalation.escalationid = zbx_atoui64(row[0]);
+ escalation.actionid = zbx_atoui64(row[1]);
+ escalation.esc_step = atoi(row[2]);
+ escalation.status = atoi(row[3]);
+ escalation.nextcheck = 0;
+
+ memset(&event, 0, sizeof(event));
+ event.eventid = zbx_atoui64(row[4]);
+ event.source = atoi(row[5]);
+ event.object = atoi(row[6]);
+ event.objectid = zbx_atoui64(row[7]);
+ event.clock = atoi(row[8]);
+ event.value = atoi(row[9]);
+ event.acknowledged = atoi(row[10]);
+
+ add_trigger_info(&event);
+
+ DBbegin();
+
+ execute_escalation(&escalation, &event);
+
+ if (escalation.status == ESCALATION_STATUS_COMPLETED)
+ DBremove_escalation(escalation.escalationid);
+ else
+ DBexecute("update escalations set esc_step=%d,nextcheck=%d where escalationid=" ZBX_FS_UI64,
+ escalation.esc_step,
+ escalation.nextcheck,
+ escalation.escalationid);
+
+ DBcommit();
+ }
+
+ DBfree_result(result);
+}
+
+/******************************************************************************
+ * *
+ * Function: get_minnextcheck *
+ * *
+ * Purpose: calculate when we have to process earliest escalations *
+ * *
+ * Parameters: now - current timestamp *
+ * *
+ * Return value: timestamp of earliest check or -1 if not found *
+ * *
+ * Author: Aleksander Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+static int get_minnextcheck()
+{
+ DB_RESULT result;
+ DB_ROW row;
+ int res;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In get_minnextcheck()");
+
+ result = DBselect("select count(*),min(nextcheck) from escalations where status in (%d,%d)" DB_NODE,
+ ESCALATION_STATUS_ACTIVE,
+ ESCALATION_STATUS_RECOVERY,
+ DBnode_local("escalationid"));
+
+ if (NULL == (row = DBfetch(result)) || DBis_null(row[0]) == SUCCEED || DBis_null(row[1]) == SUCCEED)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "No items to update for minnextcheck.");
+ res = FAIL;
+ }
+ else
+ {
+ if (atoi(row[0]) == 0)
+ {
+ res = FAIL;
+ }
+ else
+ {
+ res = atoi(row[1]);
+ }
+ }
+ DBfree_result(result);
+
+ return res;
+}
+
+/******************************************************************************
+ * *
+ * Function: main_escalator_loop *
+ * *
+ * Purpose: periodically check table escalations and generate alerts *
+ * *
+ * Parameters: *
+ * *
+ * Return value: *
+ * *
+ * Author: Aleksander Vladishev *
+ * *
+ * Comments: never returns *
+ * *
+ ******************************************************************************/
+int main_escalator_loop()
+{
+ int now, nextcheck, sleeptime;
+ double sec;
+ struct sigaction phan;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In main_escalator_loop()");
+
+ phan.sa_handler = child_signal_handler;
+ sigemptyset(&phan.sa_mask);
+ phan.sa_flags = 0;
+ sigaction(SIGALRM, &phan, NULL);
+
+ zbx_setproctitle("escalator [connecting to the database]");
+
+ DBconnect(ZBX_DB_CONNECT_NORMAL);
+
+ for (;;) {
+ now = time(NULL);
+ sec = zbx_time();
+
+ zbx_setproctitle("escalator [processing escalations]");
+
+ process_escalations(now);
+
+ sec = zbx_time() - sec;
+
+ nextcheck = get_minnextcheck();
+
+ if (FAIL == nextcheck)
+ sleeptime = CONFIG_ESCALATOR_FREQUENCY;
+ else {
+ sleeptime = nextcheck - time(NULL);
+ if (sleeptime < 0)
+ sleeptime = 0;
+ else if (sleeptime > CONFIG_ESCALATOR_FREQUENCY)
+ sleeptime = CONFIG_ESCALATOR_FREQUENCY;
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "Escalator spent " ZBX_FS_DBL " seconds while processing escalation items."
+ " Nextcheck after %d sec.",
+ sec,
+ sleeptime);
+
+ if (sleeptime > 0) {
+ zbx_setproctitle("escalator [sleeping for %d seconds]",
+ sleeptime);
+
+ sleep(sleeptime);
+ }
+ }
+
+ /* Never reached */
+ DBclose();
+}
diff --git a/src/zabbix_server/escalator/escalator.h b/src/zabbix_server/escalator/escalator.h
new file mode 100644
index 00000000..aeb70d4c
--- /dev/null
+++ b/src/zabbix_server/escalator/escalator.h
@@ -0,0 +1,27 @@
+/*
+** ZABBIX
+** Copyright (C) 2000-2005 SIA Zabbix
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**/
+
+#ifndef ZABBIX_ESCALATOR_H
+#define ZABBIX_ESCALATOR_H
+
+#include "db.h"
+
+int main_escalator_loop();
+
+#endif
diff --git a/src/zabbix_server/events.c b/src/zabbix_server/events.c
index c29bed27..2d0dfa5e 100644
--- a/src/zabbix_server/events.c
+++ b/src/zabbix_server/events.c
@@ -62,7 +62,7 @@
* Comments: use 'free_trigger_info' function to clear allocated memory *
* *
******************************************************************************/
-static void add_trigger_info(DB_EVENT *event)
+void add_trigger_info(DB_EVENT *event)
{
DB_RESULT result;
DB_ROW row;
@@ -189,10 +189,12 @@ int process_event(DB_EVENT *event)
event->eventid, ALERT_STATUS_NOT_SENT);
}*/
+/* zabbix_set_log_level(LOG_LEVEL_DEBUG);*/
if(event->skip_actions == 0)
{
process_actions(event);
}
+/* zabbix_set_log_level(LOG_LEVEL_CRIT);*/
if(TRIGGER_VALUE_TRUE == event->value)
{
diff --git a/src/zabbix_server/events.h b/src/zabbix_server/events.h
index b56d9f77..80e15946 100644
--- a/src/zabbix_server/events.h
+++ b/src/zabbix_server/events.h
@@ -24,6 +24,7 @@
#include "common.h"
#include "db.h"
+void add_trigger_info(DB_EVENT *event);
int process_event(DB_EVENT *event);
#endif
diff --git a/src/zabbix_server/operations.c b/src/zabbix_server/operations.c
index 173a337b..f16c49b5 100644
--- a/src/zabbix_server/operations.c
+++ b/src/zabbix_server/operations.c
@@ -58,7 +58,7 @@
* Comments: Cannot use action->userid as it may also be groupid *
* *
******************************************************************************/
-static void send_to_user_medias(DB_EVENT *event,DB_OPERATION *operation, zbx_uint64_t userid)
+/*static void send_to_user_medias(DB_EVENT *event,DB_OPERATION *operation, zbx_uint64_t userid)
{
DB_MEDIA media;
DB_RESULT result;
@@ -101,7 +101,7 @@ static void send_to_user_medias(DB_EVENT *event,DB_OPERATION *operation, zbx_uin
zabbix_log(LOG_LEVEL_DEBUG, "End send_to_user_medias()");
}
-
+*/
/******************************************************************************
* *
* Function: check_user_active *
@@ -117,7 +117,7 @@ static void send_to_user_medias(DB_EVENT *event,DB_OPERATION *operation, zbx_uin
* Comments: *
* *
******************************************************************************/
-int check_user_active(zbx_uint64_t userid){
+/*int check_user_active(zbx_uint64_t userid){
DB_RESULT result;
DB_ROW row;
int rtrn = SUCCEED;
@@ -132,7 +132,7 @@ int check_user_active(zbx_uint64_t userid){
return rtrn;
}
-
+*/
/******************************************************************************
* *
* Function: op_notify_user *
@@ -149,7 +149,7 @@ return rtrn;
* Comments: action->recipient specifies user or group *
* *
******************************************************************************/
-void op_notify_user(DB_EVENT *event, DB_ACTION *action, DB_OPERATION *operation)
+/*void op_notify_user(DB_EVENT *event, DB_ACTION *action, DB_OPERATION *operation)
{
DB_RESULT result;
DB_ROW row;
@@ -186,7 +186,7 @@ void op_notify_user(DB_EVENT *event, DB_ACTION *action, DB_OPERATION *operation)
}
zabbix_log(LOG_LEVEL_DEBUG, "End send_to_user()");
}
-
+*/
/******************************************************************************
* *
@@ -354,44 +354,33 @@ static int get_next_command(char** command_list, char** alias, int* is_group, ch
* Comments: commands devided with newline *
* *
******************************************************************************/
-void op_run_commands(DB_EVENT *event, DB_OPERATION *operation)
+void op_run_commands(char *cmd_list)
{
- DB_RESULT result;
+ DB_RESULT result;
DB_ROW row;
+ char *alias, *command;
+ int is_group;
- char *cmd_list = NULL;
- char *alias = NULL;
- char *command = NULL;
- int is_group = 0;
+ assert(cmd_list);
- assert(event);
- assert(operation);
+ zabbix_log(LOG_LEVEL_DEBUG, "In run_commands()");
- zabbix_log( LOG_LEVEL_DEBUG, "In run_commands(operationid:" ZBX_FS_UI64 ")",
- operation->operationid);
+ while (1 != get_next_command(&cmd_list, &alias, &is_group, &command)) {
+ if (!alias || *alias == '\0' || !command || *command == '\0')
+ continue;
- cmd_list = operation->longdata;
- while(get_next_command(&cmd_list,&alias,&is_group,&command)!=1)
- {
- if(!alias || !command) continue;
- if(alias == '\0' || command == '\0') continue;
- if(is_group)
- {
- result = DBselect("select distinct h.host from hosts_groups hg,hosts h, groups g where hg.hostid=h.hostid and hg.groupid=g.groupid and g.name='%s'" DB_NODE,
- alias,
- DBnode_local("h.hostid"));
- while((row=DBfetch(result)))
- {
+ if (is_group) {
+ result = DBselect("select distinct h.host from hosts_groups hg,hosts h,groups g"
+ " where hg.hostid=h.hostid and hg.groupid=g.groupid and g.name='%s'" DB_NODE,
+ alias,
+ DBnode_local("h.hostid"));
+
+ while (NULL != (row = DBfetch(result)))
run_remote_command(row[0], command);
- }
-
+
DBfree_result(result);
- }
- else
- {
+ } else
run_remote_command(alias, command);
- }
-/* DBadd_alert(action->actionid,trigger->triggerid, userid, media.mediatypeid,media.sendto,action->subject,action->scripts); */ /* TODO !!! Add alert for remote commands !!! */
}
zabbix_log( LOG_LEVEL_DEBUG, "End run_commands()");
}
diff --git a/src/zabbix_server/operations.h b/src/zabbix_server/operations.h
index c4c14b3d..24b23f41 100644
--- a/src/zabbix_server/operations.h
+++ b/src/zabbix_server/operations.h
@@ -30,8 +30,8 @@ void op_group_add(DB_EVENT *event, DB_ACTION *action, DB_OPERATION *operation);
void op_group_del(DB_EVENT *event, DB_ACTION *action, DB_OPERATION *operation);
void op_host_add(DB_EVENT *event);
void op_host_del(DB_EVENT *event);
-void op_run_commands(DB_EVENT *event, DB_OPERATION *operation);
-int check_user_active(zbx_uint64_t userid);
-void op_notify_user(DB_EVENT *event, DB_ACTION *action, DB_OPERATION *operation);
+void op_run_commands(char *cmd_list);
+/*int check_user_active(zbx_uint64_t userid);
+void op_notify_user(DB_EVENT *event, DB_ACTION *action, DB_OPERATION *operation);*/
#endif
diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c
index 9059f828..272bdf8d 100644
--- a/src/zabbix_server/server.c
+++ b/src/zabbix_server/server.c
@@ -47,6 +47,7 @@
#include "nodewatcher/nodewatcher.h"
#include "watchdog/watchdog.h"
#include "utils/nodechange.h"
+#include "escalator/escalator.h"
#define LISTENQ 1024
@@ -126,6 +127,7 @@ int CONFIG_HTTPPOLLER_FORKS = 5;
int CONFIG_TIMER_FORKS = 1;
int CONFIG_TRAPPERD_FORKS = 5;
int CONFIG_UNREACHABLE_POLLER_FORKS = 1;
+int CONFIG_ESCALATOR_FORKS = 1;
int CONFIG_LISTEN_PORT = 10051;
char *CONFIG_LISTEN_IP = NULL;
@@ -1073,7 +1075,7 @@ int MAIN_ZABBIX_ENTRY(void)
#endif
threads = calloc(1+CONFIG_POLLER_FORKS+CONFIG_TRAPPERD_FORKS+CONFIG_PINGER_FORKS+CONFIG_ALERTER_FORKS
+CONFIG_HOUSEKEEPER_FORKS+CONFIG_TIMER_FORKS+CONFIG_UNREACHABLE_POLLER_FORKS
- +CONFIG_NODEWATCHER_FORKS+CONFIG_HTTPPOLLER_FORKS+CONFIG_DISCOVERER_FORKS,
+ +CONFIG_NODEWATCHER_FORKS+CONFIG_HTTPPOLLER_FORKS+CONFIG_DISCOVERER_FORKS+CONFIG_ESCALATOR_FORKS,
sizeof(pid_t));
if(CONFIG_TRAPPERD_FORKS > 0)
@@ -1086,7 +1088,7 @@ int MAIN_ZABBIX_ENTRY(void)
}
for( i=1;
- i<=CONFIG_POLLER_FORKS+CONFIG_TRAPPERD_FORKS+CONFIG_PINGER_FORKS+CONFIG_ALERTER_FORKS+CONFIG_HOUSEKEEPER_FORKS+CONFIG_TIMER_FORKS+CONFIG_UNREACHABLE_POLLER_FORKS+CONFIG_NODEWATCHER_FORKS+CONFIG_HTTPPOLLER_FORKS+CONFIG_DISCOVERER_FORKS+CONFIG_DBSYNCER_FORKS;
+ i<=CONFIG_POLLER_FORKS+CONFIG_TRAPPERD_FORKS+CONFIG_PINGER_FORKS+CONFIG_ALERTER_FORKS+CONFIG_HOUSEKEEPER_FORKS+CONFIG_TIMER_FORKS+CONFIG_UNREACHABLE_POLLER_FORKS+CONFIG_NODEWATCHER_FORKS+CONFIG_HTTPPOLLER_FORKS+CONFIG_DISCOVERER_FORKS+CONFIG_DBSYNCER_FORKS+CONFIG_ESCALATOR_FORKS;
i++)
{
if((pid = zbx_fork()) == 0)
@@ -1223,6 +1225,16 @@ int MAIN_ZABBIX_ENTRY(void)
main_dbsyncer_loop();
}
+ else if (server_num <= CONFIG_POLLER_FORKS + CONFIG_TRAPPERD_FORKS + CONFIG_PINGER_FORKS + CONFIG_ALERTER_FORKS
+ + CONFIG_HOUSEKEEPER_FORKS + CONFIG_TIMER_FORKS + CONFIG_UNREACHABLE_POLLER_FORKS
+ + CONFIG_NODEWATCHER_FORKS + CONFIG_HTTPPOLLER_FORKS + CONFIG_DISCOVERER_FORKS + CONFIG_DBSYNCER_FORKS
+ + CONFIG_ESCALATOR_FORKS)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "server #%d started [Escalator]",
+ server_num);
+
+ main_escalator_loop();
+ }
return SUCCEED;
}
@@ -1235,7 +1247,7 @@ void zbx_on_exit()
if(threads != NULL)
{
- for(i = 1; i <= CONFIG_POLLER_FORKS+CONFIG_TRAPPERD_FORKS+CONFIG_PINGER_FORKS+CONFIG_ALERTER_FORKS+CONFIG_HOUSEKEEPER_FORKS+CONFIG_TIMER_FORKS+CONFIG_UNREACHABLE_POLLER_FORKS+CONFIG_NODEWATCHER_FORKS+CONFIG_HTTPPOLLER_FORKS+CONFIG_DISCOVERER_FORKS+CONFIG_DBSYNCER_FORKS; i++)
+ for(i = 1; i <= CONFIG_POLLER_FORKS+CONFIG_TRAPPERD_FORKS+CONFIG_PINGER_FORKS+CONFIG_ALERTER_FORKS+CONFIG_HOUSEKEEPER_FORKS+CONFIG_TIMER_FORKS+CONFIG_UNREACHABLE_POLLER_FORKS+CONFIG_NODEWATCHER_FORKS+CONFIG_HTTPPOLLER_FORKS+CONFIG_DISCOVERER_FORKS+CONFIG_DBSYNCER_FORKS+CONFIG_ESCALATOR_FORKS; i++)
{
if(threads[i]) {
kill(threads[i],SIGTERM);