Hello, I use a "check host" statement in which multiple ports are monitored. The alerts are passed on to an external script which uses the environment variables that monit sets. In some cases where multiple "failed" and "succeeded" events are raised, the value for MONIT_DESCRIPTION is wrong, namely that of a different event. The existing code always seems to use Event_get_message() for the first entry in the eventlist, even if the event itself is not the first on that list.
The attached patch fixes this for me, although it is quiet invasive as it modifies the "spawn" prototype. Perhaps someone sees a more elegant solution? The patch is against SVN revision 205 on "trunk". Here is an example snippet for monitrc to illustrate the situation: check host appserver with address 192.168.1.1 start program = "/home/marco/bin/appserver --workdir /home/marco/testsuite/appserver --daemon" stop program = "/home/marco/bin/appserver --workdir /home/marco/testsuite/appserver --quit" if failed port 9080 protocol http with timeout 5 seconds then exec "/home/marco/src/test-monit/bin/my_alert 'Failed for port 9080'" else if succeeded then exec "/home/marco/src/test-monit/bin/my_alert 'Succeeded for port 9080'" if failed port 9081 protocol http with timeout 5 seconds then exec "/home/marco/src/test-monit/bin/my_alert 'Failed for port 9081'" else if succeeded then exec "/home/marco/src/test-monit/bin/my_alert 'Succeeded for port 9081'" if failed port 9082 protocol http with timeout 5 seconds then exec "/home/marco/src/test-monit/bin/my_alert 'Failed for port 9082'" else if succeeded then exec "/home/marco/src/test-monit/bin/my_alert 'Succeeded for port 9082'" If say ports 9080 and 9081 fail for some time, and then 9080 is again available you might get the following entries in the call of my_alert for port 9081: MONIT_DESCRIPTION=connection succeeded to INET[192.168.1.1:9080] via TCP MONIT_EVENT=Connection failed argv[1]='Failed for port 9081' Note that this "bug" (if that's what it is) only manifests itself in the setting of MONIT_DESCRIPTION when an external program is called, and can be worked around by using multiple "check host" statements. -- Marco Roeland
commit 7f35086c2027400f9f5262a49fc8b79006e37781 Author: Marco Roeland <marco.roel...@xs4all.nl> Date: Fri Jul 23 11:09:54 2010 +0200 Pass correct MONIT_DESCRIPTION env variable for external program In case of multiple simultaneous events for a service the value passed to external programs for MONIT_DESCRIPTION was that for the first encountered event and so not always the value for the correct event. Fix this by passing the event in the spawn function call. diff --git a/control.c b/control.c index 5514363..bfa1479 100644 --- a/control.c +++ b/control.c @@ -334,7 +334,7 @@ static void do_start(Service_T s) { if (s->start && (s->type!=TYPE_PROCESS || !Util_isProcessRunning(s))) { LogInfo("'%s' start: %s\n", s->name, s->start->arg[0]); - spawn(s, s->start, "Started"); + spawn(s, s->start, NULL, "Started"); /* We only wait for a process type, other service types does not have a pid file to watch */ if (s->type == TYPE_PROCESS) wait_start(s); @@ -364,7 +364,7 @@ static int do_stop(Service_T s) { if (s->stop && (s->type!=TYPE_PROCESS || Util_isProcessRunning(s))) { LogInfo("'%s' stop: %s\n", s->name, s->stop->arg[0]); - spawn(s, s->stop, "Stopped"); + spawn(s, s->stop, NULL, "Stopped"); if (s->type == TYPE_PROCESS) { /* Only wait for process service types */ if (!wait_stop(s)) diff --git a/event.c b/event.c index 9620c07..e60a1f5 100644 --- a/event.c +++ b/event.c @@ -709,7 +709,7 @@ static void handle_action(Event_T E, Action_T A) { return; } else if (A->id == ACTION_EXEC) { LogInfo("'%s' exec: %s\n", s->name, A->exec->arg[0]); - spawn(s, A->exec, Event_get_description(E)); + spawn(s, A->exec, E, Event_get_description(E)); return; } else { if (s->actionratelist && (A->id == ACTION_START || A->id == ACTION_RESTART)) diff --git a/monitor.h b/monitor.h index 62cea95..4523019 100644 --- a/monitor.h +++ b/monitor.h @@ -905,7 +905,7 @@ int control_service_string(const char *, const char *); int control_service_daemon(const char *, const char *); void setup_dependants(); void reset_depend(); -void spawn(Service_T, Command_T, const char *); +void spawn(Service_T, Command_T, Event_T, const char *); int status(char *); int log_init(); void LogEmergency(const char *, ...); diff --git a/spawn.c b/spawn.c index b8a4945..f3fb01c 100644 --- a/spawn.c +++ b/spawn.c @@ -114,7 +114,7 @@ typedef struct En { static void put_monit_environment(Environment_T e); static void free_monit_environment(Environment_T *e); static void push_monit_environment(const char *env, Environment_T *list); -static void set_monit_environment(Service_T s, const char *event, Environment_T *e); +static void set_monit_environment(Service_T s, Event_T E, const char *event, Environment_T *e); /* ------------------------------------------------------------------ Public */ @@ -128,7 +128,7 @@ static void set_monit_environment(Service_T s, const char *event, Environment_T * @param E An optional event string, specifying why this function was * called. May be NULL. */ -void spawn(Service_T S, Command_T C, const char *E) { +void spawn(Service_T S, Command_T C, Event_T E, const char *event) { pid_t pid; sigset_t mask; @@ -152,7 +152,7 @@ void spawn(Service_T S, Command_T C, const char *E) { sigaddset(&mask, SIGCHLD); pthread_sigmask(SIG_BLOCK, &mask, &save); - set_monit_environment(S, E, &environment); + set_monit_environment(S, E, event, &environment); pid= fork(); if(pid < 0) { @@ -260,6 +260,7 @@ void spawn(Service_T S, Command_T C, const char *E) { * executed may use such variable for various purposes. */ static void set_monit_environment(Service_T s, + Event_T E, const char *event, Environment_T *e) { @@ -281,7 +282,7 @@ static void set_monit_environment(Service_T s, push_monit_environment(buf, e); if (s->eventlist) { - snprintf(buf, STRLEN, "MONIT_DESCRIPTION=%s", s->eventlist->message); + snprintf(buf, STRLEN, "MONIT_DESCRIPTION=%s", E ? Event_get_message(E) : s->eventlist->message); push_monit_environment(buf, e); }
_______________________________________________ monit-dev mailing list monit-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/monit-dev