[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
initial patch for device/file/directory stuff
From: |
Martin Pala |
Subject: |
initial patch for device/file/directory stuff |
Date: |
Wed, 23 Apr 2003 11:02:03 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3) Gecko/20030314 |
Hi,
there's initial patch for device/file and directory monitoring.
It isn't yet completed and has lot of issues, for example:
- documentation
- cervlet reports cleanup and extension
- configuration options filtering (support only appropriate subset of
options for different types of monitoring tasks)
- file/directory monitoring tasks extension ('size' test, etc.) -
current patch is concentrated on device tests
- port/test of get_fsusage() and get_device() functions for FreeBSD,
HP/UX, AIX, MACOSX (present code tested on linux and solaris only, i
don't have access to other systems)
Happy Easter :)
Martin
diff -Naur monit.20030423.base/CHANGES.txt monit.20030423/CHANGES.txt
--- monit.20030423.base/CHANGES.txt Sun Mar 9 15:25:26 2003
+++ monit.20030423/CHANGES.txt Wed Apr 23 10:47:46 2003
@@ -1,8 +1,8 @@
- CHANGES version 3.3
+ CHANGES version 4.0
This file summarizes changes made since 1.0
-Version 3.3
+Version 4.0
* This release utilize a state file to save significant process data.
This allows data to be persistent and survive a monit reload and
@@ -11,6 +11,9 @@
* Fixes of monit rc script and monit.spec
+* Support for device checks. Monit is able to watch space and inodes
+ and do custom action in the case of problem.
+
Version 3.2
diff -Naur monit.20030423.base/Makefile.in monit.20030423/Makefile.in
--- monit.20030423.base/Makefile.in Fri Feb 14 10:20:05 2003
+++ monit.20030423/Makefile.in Wed Apr 23 10:47:46 2003
@@ -68,7 +68,7 @@
YACC = @YACC@
LINKFLAGS = @LDFLAGS@
-CFLAGS = @CFLAGS@ $(DEFINES) @CPPFLAGS@ $(INCDIR)
+CFLAGS = @CFLAGS@ $(DEFINES) @CPPFLAGS@ $(INCDIR)
LEXFLAGS = -i
YACCFLAGS = -dt
diff -Naur monit.20030423.base/configure.ac monit.20030423/configure.ac
--- monit.20030423.base/configure.ac Mon Mar 10 14:13:47 2003
+++ monit.20030423/configure.ac Wed Apr 23 10:47:46 2003
@@ -7,7 +7,7 @@
AC_PREREQ([2.53])
# Init autoconf and automake
-AC_INIT([monit], [3.3], address@hidden)
+AC_INIT([monit], [4.0], address@hidden)
# Package info
AC_REVISION([$Revision: 1.23 $])
@@ -48,7 +48,7 @@
AC_HEADER_SYS_WAIT
AC_HEADER_STAT
AC_HEADER_TIME
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h string.h
strings.h sys/ioctl.h unistd.h sys/socket.h syslog.h sys/loadavg.h asm/param.h
limits.h stropts.h getopt.h sys/filio.h string.h sys/time.h errno.h])
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h string.h
strings.h sys/ioctl.h unistd.h sys/socket.h syslog.h sys/loadavg.h asm/param.h
limits.h stropts.h getopt.h sys/filio.h string.h sys/time.h errno.h sys/vfs.h
sys/statvfs.h mntent.h sys/mnttab.h])
# Check for types.
AC_TYPE_MODE_T
@@ -82,6 +82,8 @@
AC_FUNC_MALLOC
AC_FUNC_STAT
AC_FUNC_STRFTIME
+AC_CHECK_FUNCS(statfs)
+AC_CHECK_FUNCS(statvfs)
# Find the right directory to put the root-mode PID file in
AC_MSG_CHECKING([pid file location])
diff -Naur monit.20030423.base/files.c monit.20030423/files.c
--- monit.20030423.base/files.c Mon Mar 10 14:13:47 2003
+++ monit.20030423/files.c Wed Apr 23 10:47:46 2003
@@ -47,10 +47,31 @@
#include <fcntl.h>
#endif
+#ifdef HAVE_SYS_VFS_H
+# include <sys/vfs.h>
+#endif
+
+#ifdef HAVE_SYS_STATVFS_H
+# include <sys/statvfs.h>
+#endif
+
+#ifdef HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+
+#ifdef HAVE_SYS_MNTTAB_H
+# include <sys/mnttab.h>
+#endif
+
#include "monitor.h"
+#if defined HAVE_STATVFS
+#define statfs statvfs
+#endif
+
+
/**
* Utilities used for managing files used by monit.
*
@@ -370,5 +391,143 @@
return TRUE;
+}
+
+
+/**
+ * This function validates if given object is valid for filesystem
+ * informations statistics. Valid objects are file or directory that
+ * is part of requested filesystem or block special device. In the
+ * case of file or directory the result is original object, in the
+ * case of block special device mountpoint is returned. In any case,
+ * filesystem must be mounted.
+ * @param path String to store result
+ * @param path_length Defines max. length of the resulting string
+ * @param object Identifies appropriate device object
+ * @return NULL in the case of failure otherwise pointer to
+ * resulting path
+ */
+char *get_device(char *path, unsigned path_length, char *object) {
+
+ struct stat buf;
+
+ ASSERT(path && object);
+
+ if(stat(object, &buf) != 0) {
+ log("%s: Cannot stat '%s' -- %s\n", prog, object, STRERROR);
+ return NULL;
+ }
+
+ memset(path, '\0', path_length);
+
+ if(S_ISREG(buf.st_mode) || S_ISDIR(buf.st_mode)) {
+
+ return strncpy(path, object, path_length-1);
+
+ } else if(S_ISBLK(buf.st_mode)) {
+
+ FILE *mntfd;
+
+ #ifdef HAVE_MTAB
+
+ struct mntent *mnt;
+
+ if((mntfd= setmntent("/etc/mtab", "r")) == NULL) {
+ log("%s: Cannot open /etc/mtab file", prog);
+ return NULL;
+ }
+
+ /* Last match is significant */
+ while((mnt= getmntent(mntfd)) != NULL) {
+
+ if(is(object, mnt->mnt_fsname))
+ strncpy(path, mnt->mnt_dir, path_length-1);
+
+ }
+
+ endmntent(mntfd);
+
+ #elif defined HAVE_MNTTAB
+
+ struct mnttab mnt;
+
+ if((mntfd= fopen("/etc/mnttab", "r")) == NULL) {
+ log("%s: Cannot open /etc/mnttab file", prog);
+ return NULL;
+ }
+
+ /* Last match is significant */
+ while(getmntent(mntfd, &mnt) == 0) {
+
+ if(is(object, mnt.mnt_special))
+ strncpy(path, mnt.mnt_mountp, path_length-1);
+
+ }
+
+ fclose(mntfd);
+
+ #else
+
+ log("%s: Unsupported mounted filesystem information method", prog);
+ return NULL;
+
+ #endif
+
+ return path;
+
+ }
+
+ log("%s: Not file, directory or block special device: '%s'", prog, object);
+
+ return NULL;
+
+}
+
+
+/**
+ * Filesystem usage statistics
+ * @param object Identifies requested device
+ * @param buf Information structure where resulting data will be stored
+ * @return TRUE if informations were succesfully read otherwise FALSE
+ */
+int get_fsusage(char *object, DeviceInfo_T buf) {
+
+ #if (defined HAVE_STATFS) || (defined HAVE_STATVFS)
+
+ struct statfs usage;
+
+ #else
+
+ log("%s: Unsupported filesystem informations gathering method\n", prog);
+
+ return FALSE;
+
+ #endif
+
+ char path[STRLEN];
+
+ ASSERT(object);
+ ASSERT(buf);
+
+ if(!get_device(path, STRLEN, object)) {
+ log("%s: Error looking for filesystem '%s'\n", prog, object);
+ return FALSE;
+ }
+
+ if(statfs(path, &usage) != 0) {
+ log("%s: Error getting usage statistics for device '%s' -- %s\n",
+ prog, object, STRERROR);
+ return FALSE;
+ }
+
+ buf->f_bsize= usage.f_bsize;
+ buf->f_blocks= usage.f_blocks;
+ buf->f_blocksfree= usage.f_bavail;
+ buf->f_blocksfreetotal= usage.f_bfree;
+ buf->f_files= usage.f_files;
+ buf->f_filesfree= usage.f_ffree;
+
+ return TRUE;
+
}
diff -Naur monit.20030423.base/gc.c monit.20030423/gc.c
--- monit.20030423.base/gc.c Fri Mar 7 15:24:05 2003
+++ monit.20030423/gc.c Wed Apr 23 10:47:46 2003
@@ -33,6 +33,7 @@
static void _gcpcl(Checksum_T*);
static void _gcpql(Resource_T*);
static void _gcppil(ProcInfo_T*);
+static void _gcpdil(DeviceInfo_T*);
static void _gcptl(Timestamp_T*);
static void _gcpdl(Dependant_T *d);
@@ -97,6 +98,12 @@
}
+ if((*p)->devinfo) {
+
+ _gcpdil(&(*p)->devinfo);
+
+ }
+
if((*p)->timestamplist) {
_gcptl(&(*p)->timestamplist);
@@ -110,7 +117,7 @@
}
free((*p)->name);
- free((*p)->pidfile);
+ free((*p)->path);
free((*p)->group);
if((*p)->start) {
for(i= 0; (*p)->start->arg[i]; i++)
@@ -234,6 +241,16 @@
}
+
+static void _gcpdil(DeviceInfo_T *di) {
+
+ ASSERT(di);
+
+ free(*di);
+ *di= NULL;
+
+}
+
static void _gcptl(Timestamp_T *p) {
diff -Naur monit.20030423.base/http/cervlet.c monit.20030423/http/cervlet.c
--- monit.20030423.base/http/cervlet.c Fri Feb 14 09:22:33 2003
+++ monit.20030423/http/cervlet.c Wed Apr 23 10:47:46 2003
@@ -66,6 +66,10 @@
static void doGet(HttpRequest, HttpResponse);
static void doPost(HttpRequest, HttpResponse);
static void do_home(HttpRequest, HttpResponse);
+static void do_home_device(HttpRequest, HttpResponse);
+static void do_home_directory(HttpRequest, HttpResponse);
+static void do_home_file(HttpRequest, HttpResponse);
+static void do_home_process(HttpRequest, HttpResponse);
static void do_about(HttpRequest, HttpResponse);
static void not_found(HttpRequest, HttpResponse);
static void do_runtime(HttpRequest, HttpResponse);
@@ -73,7 +77,11 @@
static void handle_action(HttpRequest, HttpResponse);
static void print_status(Process_T, HttpResponse res);
static void is_monit_running(HttpRequest, HttpResponse);
-static void do_process(HttpRequest, HttpResponse, char *);
+static void do_task(HttpRequest, HttpResponse, char *);
+static void do_task_device(HttpRequest, HttpResponse, Process_T);
+static void do_task_directory(HttpRequest, HttpResponse, Process_T);
+static void do_task_file(HttpRequest, HttpResponse, Process_T);
+static void do_task_process(HttpRequest, HttpResponse, Process_T);
extern ssl_server_connection * mySSLServerConnection;
@@ -208,117 +216,32 @@
static void do_home(HttpRequest req, HttpResponse res) {
- int on= TRUE;
- struct myprocess *p;
char *uptime= get_process_uptime(Run.pidfile);
- if ( Run.doprocess ) {
- HEAD("", Run.polltime)
- out_print(res,
-"<table cellspacing=\"0\" cellpadding=\"5\" width=\"100%%\" border=\"0\">"
-" <tr bgcolor=\"#BBDDFF\">"
-" <td colspan=2 valign=\"top\" align=\"left\" bgcolor=\"#EFF7FF\"
width=\"100%%\">"
-" <br><h2 align=\"center\">Monit Process Manager</h2>"
-" <p align=\"center\">Monit is <a href='/_runtime'>running</a> on %s "
-" with <i>uptime, %s</i> and monitoring:</p><br>"
-" </td>"
-" </tr>"
-"</table>"
-"<table cellspacing=\"0\" cellpadding=\"0\" width=\"100%%\" border=\"0\">"
-" <tr valign=\"middle\" bgcolor=\"#6F6F6F\">"
-" <td><img src=\"/_pixel\" width=\"1\" height=\"1\" alt=\"\"></td>"
-" </tr>"
-"</table>"
-"<br><p> </p>"
-"<table cellspacing=0 cellpadding=3 border=0 width=\"70%\">"
-"<tr><td><h3><b>Server</b></h3></td>"
-"<td align=\"right\"><h3><b>Status</b></h3></td>"
-"<td align=\"right\"><h3><b>Uptime</b></h3></td>"
-"<td align=\"right\"><h3><b>CPU</b></h3></td>"
-"<td align=\"right\"><h3><b>Memory</b></h3></td>"
-"</tr>"
-"<tr><td> </td><td> </td></tr>", Run.localhostname, uptime);
- } else {
HEAD("", Run.polltime)
- out_print(res,
-"<table cellspacing=\"0\" cellpadding=\"5\" width=\"100%%\" border=\"0\">"
-" <tr bgcolor=\"#BBDDFF\">"
-" <td colspan=2 valign=\"top\" align=\"left\" bgcolor=\"#EFF7FF\"
width=\"100%%\">"
-" <br><h2 align=\"center\">Monit Process Manager</h2>"
-" <p align=\"center\">Monit is <a href='/_runtime'>running</a> on %s "
-" with <i>uptime, %s</i> and monitoring:</p><br>"
-" </td>"
-" </tr>"
-"</table>"
-"<table cellspacing=\"0\" cellpadding=\"0\" width=\"100%%\" border=\"0\">"
-" <tr valign=\"middle\" bgcolor=\"#6F6F6F\">"
-" <td><img src=\"/_pixel\" width=\"1\" height=\"1\" alt=\"\"></td>"
-" </tr>"
-"</table>"
-"<br><p> </p>"
-"<table cellspacing=0 cellpadding=3 border=0 width=\"70%\">"
-"<tr><td><h3><b>Server</b></h3></td>"
-"<td align=\"right\"><h3><b>Status</b></h3></td></tr>"
-"<tr><td> </td><td> </td></tr>", Run.localhostname, uptime);
- }
+ out_print(res,
+ "<table cellspacing=\"0\" cellpadding=\"5\" width=\"100%%\" border=\"0\">"
+ " <tr bgcolor=\"#BBDDFF\">"
+ " <td colspan=2 valign=\"top\" align=\"left\" bgcolor=\"#EFF7FF\"
width=\"100%%\">"
+ " <br><h2 align=\"center\">Monit Process Manager</h2>"
+ " <p align=\"center\">Monit is <a href='/_runtime'>running</a> on %s "
+ " with <i>uptime, %s</i> and monitoring:</p><br>"
+ " </td>"
+ " </tr>"
+ "</table>"
+ "<table cellspacing=\"0\" cellpadding=\"0\" width=\"100%%\" border=\"0\">"
+ " <tr valign=\"middle\" bgcolor=\"#6F6F6F\">"
+ " <td><img src=\"/_pixel\" width=\"1\" height=\"1\" alt=\"\"></td>"
+ " </tr>"
+ "</table>", Run.localhostname, uptime);
free(uptime);
-
- for (p= processlist; p; p= p->next) {
-
- int isrunning= is_process_running(p);
- char *uptime= get_process_uptime(p->pidfile);
-
- if ( Run.doprocess ) {
- ProcInfo_T pi= p->procinfo;
- if ( isrunning ) {
- out_print(res,"<tr %s><td><a href='/%s'>%s</a></td><td align=\"right\">"
- "%s</td><td align=\"right\">%s</td>"
- "<td align=\"right\">%.1f%%</td>"
- "<td align=\"right\">%.1f%% [%ldkB]</td></tr>",
- on?"bgcolor=\"#EFEFEF\"":"",
- p->name, p->name,
- p->has_checksum_error?
- "<font color='#ff0000'>Cheksum Error</font>":
- isrunning?
- "<font color=green>running</font>":
- "<font color=red>not running</font>",
- uptime,
- pi->cpu_percent/10.0,
- pi->mem_percent/10.0,pi->mem_kbyte
- );
- } else {
- out_print(res,"<tr %s><td><a href='/%s'>%s</a></td>"
- "<td align=\"right\">%s</td>"
- "<td align=\"right\">-</td>"
- "<td align=\"right\">- </td>"
- "<td align=\"right\">- [-]</td></tr>",
- on?"bgcolor=\"#EFEFEF\"":"",
- p->name, p->name,
- p->has_checksum_error?
- "<font color='#ff0000'>Cheksum Error</font>":
- "<font color=red>not running</font>"
- );
- }
- } else {
- out_print(res,"<tr %s><td><a href='/%s'>%s</a></td><td align=\"right\">"
- "%s %s</td></tr>",
- on?"bgcolor=\"#EFEFEF\"":"",
- p->name, p->name,
- p->has_checksum_error?
- "<font color='#ff0000'>Cheksum Error</font>":
- isrunning?
- "<font color=green>running</font>":
- "<font color=red>not running</font>",
- isrunning?uptime:"");
- }
-
- on= on?FALSE:TRUE;
- free(uptime);
-
- }
- out_print(res, "</table>");
+ do_home_process(req, res);
+ do_home_device(req, res);
+ do_home_file(req, res);
+ do_home_directory(req, res);
+
FOOT
}
@@ -533,7 +456,7 @@
if(action) {
- struct myprocess *p= get_process(name);
+ Process_T p= get_process(name);
if( is(action, "start") ) {
@@ -599,7 +522,7 @@
}
LOCK(Run.mutex)
- do_process(req, res, name);
+ do_task(req, res, name);
END_LOCK;
} else {
@@ -615,249 +538,37 @@
}
-static void do_process(HttpRequest req, HttpResponse res, char *name) {
+static void do_task(HttpRequest req, HttpResponse res, char *name) {
- struct myprocess *p= get_process(name);
- int run= is_process_running(p);
+ Process_T p= get_process(name);
HEAD(name, 1000)
- out_print(res,
- "<p><br><h3>Process status</h3><br>");
- out_print(res,"<table cellspacing=0 cellpadding=3 border=1 width=\"90%\">"
- "<tr><td width=\"30%\"><b>Parameter</b></td><td
width=\"70%\"><b>Value</b></td></tr>");
- out_print(res,
- "<tr><td>Name</a></td><td>%s</td></tr>", p->name);
- out_print(res,
- "<tr><td>Group</a></td><td><font color='#0000ff'>%s</font></td></tr>",
- p->group?p->group:"(not defined)");
- out_print(res,
- "<tr><td>Process id </a></td><td>%d</td></tr>", run);
- out_print(res,
- "<tr><td>Process status</a></td><td>%s %s</td></tr>",
- run?"<font color='#00ff00'>Running</font>":
- "<font color='#ff0000'>Not Running</font>",
- p->has_checksum_error?
- "<font color='#ff0000'><b>Checksum error!</b></font>":"");
- out_print(res,
- "<tr><td>Pid file</a></td><td>%s</td></tr>",
- p->pidfile);
- out_print(res,
- "<tr><td>Monitoring mode</a></td><td>%s</td></tr>",
- modenames[p->mode]);
- out_print(res,
- "<tr><td>Monitoring status</a></td><td>%s</td></tr>",
- statusnames[p->do_validate]);
- out_print(res,
- "<tr><td>Start program</a></td><td>%s</td></tr>",
- p->start?p->start->arg[0]:"(not defined)");
- out_print(res,
- "<tr><td>Stop program</a></td><td>%s</td></tr>",
- p->stop?p->stop->arg[0]:"(not defined)");
- {
- struct mychecksum *c;
- for(c= p->checksumlist; c; c= c->next)
- out_print(res, "<tr><td>Associated checksum</a></td><td>%s %s</td>"
- "</tr>", c->md5, c->file);
- }
- {
- Dependant_T d;
-
- for(d= p->dependantlist; d; d= d->next) {
- if(d->dependant != NULL) {
- out_print(res,"<tr><td>Depends on Process </a></td>"
- "<td> <a href=%s> %s </a></td></tr>",
- d->dependant, d->dependant);
- }
- }
- }
- if ( Run.doprocess ) {
- ProcInfo_T pi= p->procinfo;
-
- out_print(res,
- "<tr><td>CPU usage</a></td><td>%.1f%%</td></tr>",
- pi->cpu_percent/10.0);
- out_print(res,
- "<tr><td>Memory usage</a></td><td>%.1f%% [%ldkB]</td></tr>",
- pi->mem_percent/10.0,pi->mem_kbyte);
- }
- {
- Port_T n;
- for(n= p->portlist; n; n= n->next) {
-
- if ( n->family == AF_INET ) {
-
- if ( n->ssl != NULL ) {
-
- out_print(res,
- "<tr><td>Host:Port</a></td><td>%s:%d%s [%s via
SSL]</td></tr>",
- n->hostname, n->port, n->request?n->request:"",
- n->protocol->name);
-
- if ( n->certmd5 != NULL ) {
-
- out_print(res,
- "<tr><td>Server certificate md5
sum</a></td><td>%s</td></tr>",
- n->certmd5);
-
- }
-
-
- } else {
-
- out_print(res,
- "<tr><td>Host:Port</a></td><td>%s:%d%s [%s]</td></tr>",
- n->hostname, n->port, n->request?n->request:"",
- n->protocol->name);
-
- }
-
- } else if ( n->family == AF_UNIX ) {
-
- out_print(res,
- "<tr><td>Unix Socket</a></td><td>%s [%s]</td></tr>",
- n->pathname, n->protocol->name);
-
- }
- }
- }
- {
- struct mytimestamp *t;
- for(t= p->timestamplist; t; t= t->next)
- out_print(res,
- "<tr><td>Associated timestamp</a></td>"
- "<td>If %s %s %d second(s) then %s</td></tr>",
- t->pathname, operatornames[t->operator], t->time,
actionnames[t->action]);
- }
- {
- Resource_T q;
- for (q= p->resourcelist; q; q= q->next) {
- switch (q->resource_id) {
+ switch (p->task) {
- case RESOURCE_ID_CPU_PERCENT:
+ case TASK_DEVICE:
+ do_task_device(req, res, p);
+ break;
+
+ case TASK_DIRECTORY:
+ do_task_directory(req, res, p);
+ break;
+
+ case TASK_FILE:
+ do_task_file(req, res, p);
+ break;
+
+ case TASK_PROCESS:
+ do_task_process(req, res, p);
+ break;
- out_print(res,"<tr><td>CPU usage limit</a></td>"
- "<td>If %s %.1f%% for %d cycle(s) then %s</td></tr>",
- operatornames[q->operator],
- q->limit/10.0, q->max_cycle,
- actionnames[q->action]);
- break;
+ default:
+ break;
- case RESOURCE_ID_MEM_PERCENT:
-
- out_print(res,"<tr><td>Memory usage limit</a></td>"
- "<td>If %s %.1f%% for %d cycle(s) then %s</td></tr>",
- operatornames[q->operator],
- q->limit/10.0, q->max_cycle,
- actionnames[q->action]);
- break;
-
- case RESOURCE_ID_MEM_KBYTE:
-
- out_print(res,"<tr><td>Memory amount limit</a></td>"
- "<td>If %s %ld for %d cycle(s) then %s</td></tr>",
- operatornames[q->operator],
- q->limit, q->max_cycle,
- actionnames[q->action]);
- break;
-
- case RESOURCE_ID_LOAD1:
-
- out_print(res,"<tr><td>Load average (1min)</a></td>"
- "<td>If %s %.1f for %d cycle(s) then %s</td></tr>",
- operatornames[q->operator],
- q->limit/10.0, q->max_cycle,
- actionnames[q->action]);
- break;
-
- case RESOURCE_ID_LOAD5:
-
- out_print(res,"<tr><td>Load average (5min)</a></td>"
- "<td>If %s %.1f for %d cycle(s) then %s</td></tr>",
- operatornames[q->operator],
- q->limit/10.0, q->max_cycle,
- actionnames[q->action]);
- break;
-
- case RESOURCE_ID_LOAD15:
- out_print(res,"<tr><td>Load average (15min)</a></td>"
- "<td>If %s %.1f for %d cycle(s) then %s</td></tr>",
- operatornames[q->operator],
- q->limit/10.0, q->max_cycle,
- actionnames[q->action]);
- break;
-
- }
- }
- }
- out_print(res,
- "<tr><td>Check process</a></td><td>Every %d cycle</td></tr>",
- p->every?p->every:1);
- out_print(res,
- "<tr><td>Timeout</a></td><td>Timeout if %d restart within %d cycles"
- "</td></tr>", p->to_start, p->to_cycle);
- {
- Mail_T r;
- for(r= p->maillist; r; r= r->next) {
- out_print(res,
- "<tr bgcolor=\"#EFEFEF\"><td>Alert mail to</a></td><td>%s</td></tr>",
- r->to?r->to:"");
- out_print(res,
- "<tr><td>Alert from</a></td><td>%s</td></tr>",
- r->from?r->from:"(default)");
- out_print(res,
- "<tr><td>Alert subject</a></td><td>%s</td></tr>",
- r->subject?r->subject:"(default)");
- out_print(res,
- "<tr><td>Alert message</a></td><td>%s</td></tr>",
- r->message?r->message:"(default)");
- out_print(res,
- "<tr><td>Alert on timeout</a></td><td>%s</td></tr>",
- r->alert_on_timeout?"yes":"no");
- out_print(res,
- "<tr><td>Alert on restart</a></td><td>%s</td></tr>",
- r->alert_on_restart?"yes":"no");
- out_print(res,
- "<tr><td>Alert on checksum</a></td><td>%s</td></tr>",
- r->alert_on_checksum?"yes":"no");
- out_print(res,
- "<tr><td>Alert on exceeded resource</a></td><td>%s</td></tr>",
- r->alert_on_resource?"yes":"no");
- out_print(res,
- "<tr><td>Alert on stop</a></td><td>%s</td></tr>",
- r->alert_on_stop?"yes":"no");
- out_print(res,
- "<tr><td>Alert on timestamp</a></td><td>%s</td></tr>",
- r->alert_on_timestamp?"yes":"no");
}
- }
- out_print(res, "</table>");
- out_print(res, "<table cellspacing=16><tr nowrap><td><font size=+1>");
- /* Start program */
- if(p->start)
- out_print(res,
- "<td><form method=GET action=/%s>"
- "<input type=hidden value='start' name=action>"
- "<input type=submit value='Start program' style='font-size:
12pt'></font>"
- "</form></td>", name);
- /* Stop program */
- if(p->stop)
- out_print(res,
- "<td><form method=GET action=/%s>"
- "<input type=hidden value='stop' name=action>"
- "<input type=submit value='Stop program' style='font-size:
12pt'></font>"
- "</form></td>", name);
- if(p->start && p->stop)
- out_print(res,
- "<td><form method=GET action=/%s>"
- "<input type=hidden value='restart' name=action>"
- "<input type=submit value='Restart program' style='font-size:
12pt'></font>"
- "</form></td>", name);
- out_print(res, "</tr></table>");
FOOT
-
}
@@ -870,7 +581,7 @@
if((pid= is_process_running(p))) {
- char *uptime= get_process_uptime(p->pidfile);
+ char *uptime= get_process_uptime(p->path);
ProcInfo_T pi= p->procinfo;
if( Run.httpdssl ) {
@@ -961,3 +672,858 @@
}
+
+static void do_home_process(HttpRequest req, HttpResponse res) {
+
+ int on= TRUE;
+ int header= TRUE;
+ Process_T p;
+
+ for (p= processlist; p; p= p->next) {
+
+ int isrunning;
+ char *uptime;
+
+ if(p->task != TASK_PROCESS) continue;
+
+ if(header) {
+
+ if ( Run.doprocess ) {
+
+ out_print(res,
+ "<br><p> </p>"
+ "<table cellspacing=0 cellpadding=3 border=0 width=\"70%\">"
+ "<tr><td><h3><b>Server</b></h3></td>"
+ "<td align=\"right\"><h3><b>Status</b></h3></td>"
+ "<td align=\"right\"><h3><b>Uptime</b></h3></td>"
+ "<td align=\"right\"><h3><b>CPU</b></h3></td>"
+ "<td align=\"right\"><h3><b>Memory</b></h3></td>"
+ "</tr>"
+ "<tr><td> </td><td> </td></tr>");
+
+ } else {
+
+ out_print(res,
+ "<table cellspacing=0 cellpadding=3 border=0 width=\"70%\">"
+ "<tr><td><h3><b>Server</b></h3></td>"
+ "<td align=\"right\"><h3><b>Status</b></h3></td></tr>"
+ "<tr><td> </td><td> </td></tr>");
+
+ }
+
+ header= FALSE;
+
+ }
+
+ isrunning= is_process_running(p);
+ uptime= get_process_uptime(p->path);
+
+ if ( Run.doprocess ) {
+ ProcInfo_T pi= p->procinfo;
+ if ( isrunning ) {
+ out_print(res,"<tr %s><td><a href='/%s'>%s</a></td><td
align=\"right\">"
+ "%s</td><td align=\"right\">%s</td>"
+ "<td align=\"right\">%.1f%%</td>"
+ "<td align=\"right\">%.1f%% [%ldkB]</td></tr>",
+ on?"bgcolor=\"#EFEFEF\"":"",
+ p->name, p->name,
+ p->has_checksum_error?
+ "<font color='#ff0000'>Cheksum Error</font>":
+ isrunning?
+ "<font color=green>running</font>":
+ "<font color=red>not running</font>",
+ uptime,
+ pi->cpu_percent/10.0,
+ pi->mem_percent/10.0,pi->mem_kbyte
+ );
+ } else {
+ out_print(res,"<tr %s><td><a href='/%s'>%s</a></td>"
+ "<td align=\"right\">%s</td>"
+ "<td align=\"right\">-</td>"
+ "<td align=\"right\">- </td>"
+ "<td align=\"right\">- [-]</td></tr>",
+ on?"bgcolor=\"#EFEFEF\"":"",
+ p->name, p->name,
+ p->has_checksum_error?
+ "<font color='#ff0000'>Cheksum Error</font>":
+ "<font color=red>not running</font>"
+ );
+ }
+ } else {
+ out_print(res,"<tr %s><td><a href='/%s'>%s</a></td><td align=\"right\">"
+ "%s %s</td></tr>",
+ on?"bgcolor=\"#EFEFEF\"":"",
+ p->name, p->name,
+ p->has_checksum_error?
+ "<font color='#ff0000'>Cheksum Error</font>":
+ isrunning?
+ "<font color=green>running</font>":
+ "<font color=red>not running</font>",
+ isrunning?uptime:"");
+ }
+
+ on= on?FALSE:TRUE;
+ free(uptime);
+
+ }
+
+ out_print(res, "</table>");
+
+}
+
+
+static void do_home_device(HttpRequest req, HttpResponse res) {
+
+ int on= TRUE;
+ int header= TRUE;
+ Process_T p;
+
+ for (p= processlist; p; p= p->next) {
+
+ if( (p->task != TASK_DEVICE) || !get_fsusage(p->path, p->devinfo) )
continue;
+
+ if(header) {
+
+ out_print(res,
+ "<br><p> </p>"
+ "<table cellspacing=0 cellpadding=3 border=0 width=\"70%\">"
+ "<tr><td><h3><b>Device</b></h3></td>"
+ "<td align=\"right\"><h3><b>Space</b></h3></td>"
+ "<td align=\"right\"><h3><b>Inodes</b></h3></td>"
+ "</tr>"
+ "<tr><td> </td><td> </td></tr>");
+
+ header= FALSE;
+
+ }
+
+ out_print(res,
+ "<tr %s>"
+ "<td><a href='/%s'>%s</a></td>"
+ "<td align=\"right\">%.1f%% [%.1f MB]</td>"
+ "<td align=\"right\">%.1f%% [%d files]</td>"
+ "</tr>",
+ on?"bgcolor=\"#EFEFEF\"":"",
+ p->name, p->name,
+ (float) 100 * (p->devinfo->f_blocks - p->devinfo->f_blocksfree) /
p->devinfo->f_blocks,
+ (float) (p->devinfo->f_blocks - p->devinfo->f_blocksfree) / 1048576 *
p->devinfo->f_bsize,
+ (float) 100 * (p->devinfo->f_files - p->devinfo->f_filesfree) /
p->devinfo->f_files,
+ p->devinfo->f_files - p->devinfo->f_filesfree
+ );
+
+ on= on?FALSE:TRUE;
+
+ }
+
+ out_print(res, "</table>");
+
+}
+
+
+static void do_home_file(HttpRequest req, HttpResponse res) {
+
+ int on= TRUE;
+ int header= TRUE;
+ Process_T p;
+
+ for (p= processlist; p; p= p->next) {
+
+ if(p->task != TASK_FILE) continue;
+
+ if(header) {
+
+ out_print(res,
+ "<br><p> </p>"
+ "<table cellspacing=0 cellpadding=3 border=0 width=\"70%\">"
+ "<tr><td><h3><b>File</b></h3></td>"
+ "</tr>"
+ "<tr><td> </td><td> </td></tr>");
+
+ header= FALSE;
+
+ }
+
+ out_print(res,
+ "<tr %s>"
+ "<td><a href='/%s'>%s</a></td>"
+ "</tr>",
+ on?"bgcolor=\"#EFEFEF\"":"",
+ p->name, p->name
+ );
+
+ on= on?FALSE:TRUE;
+
+ }
+
+ out_print(res, "</table>");
+
+}
+
+
+static void do_home_directory(HttpRequest req, HttpResponse res) {
+
+ int on= TRUE;
+ int header= TRUE;
+ Process_T p;
+
+ for (p= processlist; p; p= p->next) {
+
+ if(p->task != TASK_DIRECTORY) continue;
+
+ if(header) {
+
+ out_print(res,
+ "<br><p> </p>"
+ "<table cellspacing=0 cellpadding=3 border=0 width=\"70%\">"
+ "<tr><td><h3><b>Directory</b></h3></td>"
+ "</tr>"
+ "<tr><td> </td><td> </td></tr>");
+
+ header= FALSE;
+
+ }
+
+ out_print(res,
+ "<tr %s>"
+ "<td><a href='/%s'>%s</a></td>"
+ "</tr>",
+ on?"bgcolor=\"#EFEFEF\"":"",
+ p->name, p->name
+ );
+
+ on= on?FALSE:TRUE;
+
+ }
+
+ out_print(res, "</table>");
+
+}
+
+
+static void do_task_device(HttpRequest req, HttpResponse res, Process_T p) {
+
+ out_print(res,
+ "<p><br><h3>Device status</h3><br>");
+ out_print(res,"<table cellspacing=0 cellpadding=3 border=1 width=\"90%\">"
+ "<tr><td width=\"30%\"><b>Parameter</b></td><td
width=\"70%\"><b>Value</b></td></tr>");
+ out_print(res,
+ "<tr><td>Name</a></td><td>%s</td></tr>", p->name);
+ out_print(res,
+ "<tr><td>Group</a></td><td><font color='#0000ff'>%s</font></td></tr>",
+ p->group?p->group:"(not defined)");
+ out_print(res,
+ "<tr><td>Path</a></td><td>%s</td></tr>",
+ p->path);
+ out_print(res,
+ "<tr><td>Monitoring mode</a></td><td>%s</td></tr>",
+ modenames[p->mode]);
+ out_print(res,
+ "<tr><td>Monitoring status</a></td><td>%s</td></tr>",
+ statusnames[p->do_validate]);
+ out_print(res,
+ "<tr><td>Start program</a></td><td>%s</td></tr>",
+ p->start?p->start->arg[0]:"(not defined)");
+ out_print(res,
+ "<tr><td>Stop program</a></td><td>%s</td></tr>",
+ p->stop?p->stop->arg[0]:"(not defined)");
+ {
+ Dependant_T d;
+
+ for(d= p->dependantlist; d; d= d->next) {
+ if(d->dependant != NULL) {
+ out_print(res,"<tr><td>Depends on Task </a></td>"
+ "<td> <a href=%s> %s </a></td></tr>",
+ d->dependant, d->dependant);
+ }
+ }
+ }
+
+ out_print(res,
+ "<tr><td>Check task</a></td><td>Every %d cycle</td></tr>",
+ p->every?p->every:1);
+ out_print(res,
+ "<tr><td>Timeout</a></td><td>Timeout if %d restart within %d cycles"
+ "</td></tr>", p->to_start, p->to_cycle);
+ {
+
+ Device_T dl;
+
+ if(p->devicelist && get_fsusage(p->path, p->devinfo)) {
+
+ for(dl= p->devicelist; dl; dl= dl->next) {
+
+ if(dl->resource == RESOURCE_INODE) {
+
+ out_print(res,
+ "<tr><td>Inodes usage limit</a></td><td>if %s %ld %s then
%s</td></tr>",
+ operatornames[dl->operator],
+ (dl->limit_absolute > -1)?dl->limit_absolute:dl->limit_percent,
+ (dl->limit_absolute > -1)?"":"%",
+ actionnames[dl->action]);
+
+ } else if(dl->resource == RESOURCE_SPACE) {
+
+ out_print(res,
+ "<tr><td>Space usage limit</a></td><td>if %s %ld %s then
%s</td></tr>",
+ operatornames[dl->operator],
+ (dl->limit_absolute > -1)?dl->limit_absolute:dl->limit_percent,
+ (dl->limit_absolute > -1)?"blocks":"%",
+ actionnames[dl->action]);
+
+ }
+
+ }
+
+ }
+
+ }
+ out_print(res,
+ "<tr><td>Blocks total</a></td><td>%ld [%.1f MB]</td></tr>",
+ p->devinfo->f_blocks,
+ (float) p->devinfo->f_blocks / 1048576 * p->devinfo->f_bsize);
+ out_print(res,
+ "<tr><td>Blocks free for non superuser</a></td><td><font color=green>%ld
[%.1f MB] [%.1f%%]</font></td></tr>",
+ p->devinfo->f_blocksfree,
+ (float) p->devinfo->f_blocksfree / 1048576 * p->devinfo->f_bsize,
+ (float) 100 * p->devinfo->f_blocksfree / p->devinfo->f_blocks);
+ out_print(res,
+ "<tr><td>Blocks free total</a></td><td>%ld [%.1f MB] [%.1f%%]</td></tr>",
+ p->devinfo->f_blocksfreetotal,
+ (float) p->devinfo->f_blocksfreetotal / 1048576 * p->devinfo->f_bsize,
+ (float) 100 * p->devinfo->f_blocksfreetotal / p->devinfo->f_blocks);
+ out_print(res,
+ "<tr><td>Block size</a></td><td>%ld B</td></tr>",
+ p->devinfo->f_bsize);
+ out_print(res,
+ "<tr><td>Inodes total</a></td><td>%ld</td></tr>",
+ p->devinfo->f_files);
+ out_print(res,
+ "<tr><td>Inodes free</a></td><td><font color=green>%ld
[%.1f%%]</font></td></tr>",
+ p->devinfo->f_filesfree,
+ (float) 100 * p->devinfo->f_filesfree / p->devinfo->f_files);
+ {
+ Mail_T r;
+ for(r= p->maillist; r; r= r->next) {
+ out_print(res,
+ "<tr bgcolor=\"#EFEFEF\"><td>Alert mail to</a></td><td>%s</td></tr>",
+ r->to?r->to:"");
+ out_print(res,
+ "<tr><td>Alert from</a></td><td>%s</td></tr>",
+ r->from?r->from:"(default)");
+ out_print(res,
+ "<tr><td>Alert subject</a></td><td>%s</td></tr>",
+ r->subject?r->subject:"(default)");
+ out_print(res,
+ "<tr><td>Alert message</a></td><td>%s</td></tr>",
+ r->message?r->message:"(default)");
+ out_print(res,
+ "<tr><td>Alert on timeout</a></td><td>%s</td></tr>",
+ r->alert_on_timeout?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on restart</a></td><td>%s</td></tr>",
+ r->alert_on_restart?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on checksum</a></td><td>%s</td></tr>",
+ r->alert_on_checksum?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on exceeded resource</a></td><td>%s</td></tr>",
+ r->alert_on_resource?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on stop</a></td><td>%s</td></tr>",
+ r->alert_on_stop?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on timestamp</a></td><td>%s</td></tr>",
+ r->alert_on_timestamp?"yes":"no");
+ }
+ }
+ out_print(res, "</table>");
+ out_print(res, "<table cellspacing=16><tr nowrap><td><font size=+1>");
+ /* Start program */
+ if(p->start)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='start' name=action>"
+ "<input type=submit value='Start program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ /* Stop program */
+ if(p->stop)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='stop' name=action>"
+ "<input type=submit value='Stop program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ if(p->start && p->stop)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='restart' name=action>"
+ "<input type=submit value='Restart program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ out_print(res, "</tr></table>");
+
+}
+
+
+static void do_task_directory(HttpRequest req, HttpResponse res, Process_T p) {
+
+ out_print(res,
+ "<p><br><h3>Directory status</h3><br>");
+ out_print(res,"<table cellspacing=0 cellpadding=3 border=1 width=\"90%\">"
+ "<tr><td width=\"30%\"><b>Parameter</b></td><td
width=\"70%\"><b>Value</b></td></tr>");
+ out_print(res,
+ "<tr><td>Name</a></td><td>%s</td></tr>", p->name);
+ out_print(res,
+ "<tr><td>Group</a></td><td><font color='#0000ff'>%s</font></td></tr>",
+ p->group?p->group:"(not defined)");
+ out_print(res,
+ "<tr><td>Path</a></td><td>%s</td></tr>",
+ p->path);
+ out_print(res,
+ "<tr><td>Monitoring mode</a></td><td>%s</td></tr>",
+ modenames[p->mode]);
+ out_print(res,
+ "<tr><td>Monitoring status</a></td><td>%s</td></tr>",
+ statusnames[p->do_validate]);
+ out_print(res,
+ "<tr><td>Start program</a></td><td>%s</td></tr>",
+ p->start?p->start->arg[0]:"(not defined)");
+ out_print(res,
+ "<tr><td>Stop program</a></td><td>%s</td></tr>",
+ p->stop?p->stop->arg[0]:"(not defined)");
+ {
+ Dependant_T d;
+
+ for(d= p->dependantlist; d; d= d->next) {
+ if(d->dependant != NULL) {
+ out_print(res,"<tr><td>Depends on Task </a></td>"
+ "<td> <a href=%s> %s </a></td></tr>",
+ d->dependant, d->dependant);
+ }
+ }
+ }
+ out_print(res,
+ "<tr><td>Check task</a></td><td>Every %d cycle</td></tr>",
+ p->every?p->every:1);
+ out_print(res,
+ "<tr><td>Timeout</a></td><td>Timeout if %d restart within %d cycles"
+ "</td></tr>", p->to_start, p->to_cycle);
+ {
+ Mail_T r;
+ for(r= p->maillist; r; r= r->next) {
+ out_print(res,
+ "<tr bgcolor=\"#EFEFEF\"><td>Alert mail to</a></td><td>%s</td></tr>",
+ r->to?r->to:"");
+ out_print(res,
+ "<tr><td>Alert from</a></td><td>%s</td></tr>",
+ r->from?r->from:"(default)");
+ out_print(res,
+ "<tr><td>Alert subject</a></td><td>%s</td></tr>",
+ r->subject?r->subject:"(default)");
+ out_print(res,
+ "<tr><td>Alert message</a></td><td>%s</td></tr>",
+ r->message?r->message:"(default)");
+ out_print(res,
+ "<tr><td>Alert on timeout</a></td><td>%s</td></tr>",
+ r->alert_on_timeout?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on restart</a></td><td>%s</td></tr>",
+ r->alert_on_restart?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on checksum</a></td><td>%s</td></tr>",
+ r->alert_on_checksum?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on exceeded resource</a></td><td>%s</td></tr>",
+ r->alert_on_resource?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on stop</a></td><td>%s</td></tr>",
+ r->alert_on_stop?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on timestamp</a></td><td>%s</td></tr>",
+ r->alert_on_timestamp?"yes":"no");
+ }
+ }
+ out_print(res, "</table>");
+ out_print(res, "<table cellspacing=16><tr nowrap><td><font size=+1>");
+ /* Start program */
+ if(p->start)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='start' name=action>"
+ "<input type=submit value='Start program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ /* Stop program */
+ if(p->stop)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='stop' name=action>"
+ "<input type=submit value='Stop program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ if(p->start && p->stop)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='restart' name=action>"
+ "<input type=submit value='Restart program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ out_print(res, "</tr></table>");
+
+}
+
+
+static void do_task_file(HttpRequest req, HttpResponse res, Process_T p) {
+
+ out_print(res,
+ "<p><br><h3>File status</h3><br>");
+ out_print(res,"<table cellspacing=0 cellpadding=3 border=1 width=\"90%\">"
+ "<tr><td width=\"30%\"><b>Parameter</b></td><td
width=\"70%\"><b>Value</b></td></tr>");
+ out_print(res,
+ "<tr><td>Name</a></td><td>%s</td></tr>", p->name);
+ out_print(res,
+ "<tr><td>Group</a></td><td><font color='#0000ff'>%s</font></td></tr>",
+ p->group?p->group:"(not defined)");
+ out_print(res,
+ "<tr><td>Path</a></td><td>%s</td></tr>",
+ p->path);
+ out_print(res,
+ "<tr><td>Monitoring mode</a></td><td>%s</td></tr>",
+ modenames[p->mode]);
+ out_print(res,
+ "<tr><td>Monitoring status</a></td><td>%s</td></tr>",
+ statusnames[p->do_validate]);
+ out_print(res,
+ "<tr><td>Start program</a></td><td>%s</td></tr>",
+ p->start?p->start->arg[0]:"(not defined)");
+ out_print(res,
+ "<tr><td>Stop program</a></td><td>%s</td></tr>",
+ p->stop?p->stop->arg[0]:"(not defined)");
+ {
+ struct mychecksum *c;
+ for(c= p->checksumlist; c; c= c->next)
+ out_print(res, "<tr><td>Associated checksum</a></td><td>%s %s</td>"
+ "</tr>", c->md5, c->file);
+ }
+ {
+ Dependant_T d;
+
+ for(d= p->dependantlist; d; d= d->next) {
+ if(d->dependant != NULL) {
+ out_print(res,"<tr><td>Depends on Task </a></td>"
+ "<td> <a href=%s> %s </a></td></tr>",
+ d->dependant, d->dependant);
+ }
+ }
+ }
+ {
+ struct mytimestamp *t;
+ for(t= p->timestamplist; t; t= t->next)
+ out_print(res,
+ "<tr><td>Associated timestamp</a></td>"
+ "<td>If %s %s %d second(s) then %s</td></tr>",
+ t->pathname, operatornames[t->operator], t->time,
actionnames[t->action]);
+ }
+ out_print(res,
+ "<tr><td>Check task</a></td><td>Every %d cycle</td></tr>",
+ p->every?p->every:1);
+ out_print(res,
+ "<tr><td>Timeout</a></td><td>Timeout if %d restart within %d cycles"
+ "</td></tr>", p->to_start, p->to_cycle);
+ {
+ Mail_T r;
+ for(r= p->maillist; r; r= r->next) {
+ out_print(res,
+ "<tr bgcolor=\"#EFEFEF\"><td>Alert mail to</a></td><td>%s</td></tr>",
+ r->to?r->to:"");
+ out_print(res,
+ "<tr><td>Alert from</a></td><td>%s</td></tr>",
+ r->from?r->from:"(default)");
+ out_print(res,
+ "<tr><td>Alert subject</a></td><td>%s</td></tr>",
+ r->subject?r->subject:"(default)");
+ out_print(res,
+ "<tr><td>Alert message</a></td><td>%s</td></tr>",
+ r->message?r->message:"(default)");
+ out_print(res,
+ "<tr><td>Alert on timeout</a></td><td>%s</td></tr>",
+ r->alert_on_timeout?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on restart</a></td><td>%s</td></tr>",
+ r->alert_on_restart?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on checksum</a></td><td>%s</td></tr>",
+ r->alert_on_checksum?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on exceeded resource</a></td><td>%s</td></tr>",
+ r->alert_on_resource?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on stop</a></td><td>%s</td></tr>",
+ r->alert_on_stop?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on timestamp</a></td><td>%s</td></tr>",
+ r->alert_on_timestamp?"yes":"no");
+ }
+ }
+ out_print(res, "</table>");
+ out_print(res, "<table cellspacing=16><tr nowrap><td><font size=+1>");
+ /* Start program */
+ if(p->start)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='start' name=action>"
+ "<input type=submit value='Start program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ /* Stop program */
+ if(p->stop)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='stop' name=action>"
+ "<input type=submit value='Stop program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ if(p->start && p->stop)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='restart' name=action>"
+ "<input type=submit value='Restart program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ out_print(res, "</tr></table>");
+
+}
+
+
+static void do_task_process(HttpRequest req, HttpResponse res, Process_T p) {
+
+ int run= is_process_running(p);
+
+ out_print(res,
+ "<p><br><h3>Process status</h3><br>");
+ out_print(res,"<table cellspacing=0 cellpadding=3 border=1 width=\"90%\">"
+ "<tr><td width=\"30%\"><b>Parameter</b></td><td
width=\"70%\"><b>Value</b></td></tr>");
+ out_print(res,
+ "<tr><td>Name</a></td><td>%s</td></tr>", p->name);
+ out_print(res,
+ "<tr><td>Group</a></td><td><font color='#0000ff'>%s</font></td></tr>",
+ p->group?p->group:"(not defined)");
+ out_print(res,
+ "<tr><td>Process id </a></td><td>%d</td></tr>", run);
+ out_print(res,
+ "<tr><td>Process status</a></td><td>%s %s</td></tr>",
+ run?"<font color='#00ff00'>Running</font>":
+ "<font color='#ff0000'>Not Running</font>",
+ p->has_checksum_error?
+ "<font color='#ff0000'><b>Checksum error!</b></font>":"");
+ out_print(res,
+ "<tr><td>Pid file</a></td><td>%s</td></tr>",
+ p->path);
+ out_print(res,
+ "<tr><td>Monitoring mode</a></td><td>%s</td></tr>",
+ modenames[p->mode]);
+ out_print(res,
+ "<tr><td>Monitoring status</a></td><td>%s</td></tr>",
+ statusnames[p->do_validate]);
+ out_print(res,
+ "<tr><td>Start program</a></td><td>%s</td></tr>",
+ p->start?p->start->arg[0]:"(not defined)");
+ out_print(res,
+ "<tr><td>Stop program</a></td><td>%s</td></tr>",
+ p->stop?p->stop->arg[0]:"(not defined)");
+ {
+ struct mychecksum *c;
+ for(c= p->checksumlist; c; c= c->next)
+ out_print(res, "<tr><td>Associated checksum</a></td><td>%s %s</td>"
+ "</tr>", c->md5, c->file);
+ }
+ {
+ Dependant_T d;
+
+ for(d= p->dependantlist; d; d= d->next) {
+ if(d->dependant != NULL) {
+ out_print(res,"<tr><td>Depends on Task </a></td>"
+ "<td> <a href=%s> %s </a></td></tr>",
+ d->dependant, d->dependant);
+ }
+ }
+ }
+ if ( Run.doprocess ) {
+ ProcInfo_T pi= p->procinfo;
+
+ out_print(res,
+ "<tr><td>CPU usage</a></td><td>%.1f%%</td></tr>",
+ pi->cpu_percent/10.0);
+ out_print(res,
+ "<tr><td>Memory usage</a></td><td>%.1f%% [%ldkB]</td></tr>",
+ pi->mem_percent/10.0,pi->mem_kbyte);
+ }
+ {
+ Port_T n;
+ for(n= p->portlist; n; n= n->next) {
+
+ if ( n->family == AF_INET ) {
+
+ if ( n->ssl != NULL ) {
+
+ out_print(res,
+ "<tr><td>Host:Port</a></td><td>%s:%d%s [%s via
SSL]</td></tr>",
+ n->hostname, n->port, n->request?n->request:"",
+ n->protocol->name);
+
+ if ( n->certmd5 != NULL ) {
+
+ out_print(res,
+ "<tr><td>Server certificate md5
sum</a></td><td>%s</td></tr>",
+ n->certmd5);
+
+ }
+
+
+ } else {
+
+ out_print(res,
+ "<tr><td>Host:Port</a></td><td>%s:%d%s [%s]</td></tr>",
+ n->hostname, n->port, n->request?n->request:"",
+ n->protocol->name);
+
+ }
+
+ } else if ( n->family == AF_UNIX ) {
+
+ out_print(res,
+ "<tr><td>Unix Socket</a></td><td>%s [%s]</td></tr>",
+ n->pathname, n->protocol->name);
+
+ }
+ }
+ }
+ {
+ struct mytimestamp *t;
+ for(t= p->timestamplist; t; t= t->next)
+ out_print(res,
+ "<tr><td>Associated timestamp</a></td>"
+ "<td>If %s %s %d second(s) then %s</td></tr>",
+ t->pathname, operatornames[t->operator], t->time,
actionnames[t->action]);
+ }
+ {
+ Resource_T q;
+
+ for (q= p->resourcelist; q; q= q->next) {
+ switch (q->resource_id) {
+
+ case RESOURCE_ID_CPU_PERCENT:
+
+ out_print(res,"<tr><td>CPU usage limit</a></td>"
+ "<td>If %s %.1f%% for %d cycle(s) then %s</td></tr>",
+ operatornames[q->operator],
+ q->limit/10.0, q->max_cycle,
+ actionnames[q->action]);
+ break;
+
+ case RESOURCE_ID_MEM_PERCENT:
+
+ out_print(res,"<tr><td>Memory usage limit</a></td>"
+ "<td>If %s %.1f%% for %d cycle(s) then %s</td></tr>",
+ operatornames[q->operator],
+ q->limit/10.0, q->max_cycle,
+ actionnames[q->action]);
+ break;
+
+ case RESOURCE_ID_MEM_KBYTE:
+
+ out_print(res,"<tr><td>Memory amount limit</a></td>"
+ "<td>If %s %ld for %d cycle(s) then %s</td></tr>",
+ operatornames[q->operator],
+ q->limit, q->max_cycle,
+ actionnames[q->action]);
+ break;
+
+ case RESOURCE_ID_LOAD1:
+
+ out_print(res,"<tr><td>Load average (1min)</a></td>"
+ "<td>If %s %.1f for %d cycle(s) then %s</td></tr>",
+ operatornames[q->operator],
+ q->limit/10.0, q->max_cycle,
+ actionnames[q->action]);
+ break;
+
+ case RESOURCE_ID_LOAD5:
+
+ out_print(res,"<tr><td>Load average (5min)</a></td>"
+ "<td>If %s %.1f for %d cycle(s) then %s</td></tr>",
+ operatornames[q->operator],
+ q->limit/10.0, q->max_cycle,
+ actionnames[q->action]);
+ break;
+
+ case RESOURCE_ID_LOAD15:
+ out_print(res,"<tr><td>Load average (15min)</a></td>"
+ "<td>If %s %.1f for %d cycle(s) then %s</td></tr>",
+ operatornames[q->operator],
+ q->limit/10.0, q->max_cycle,
+ actionnames[q->action]);
+ break;
+
+ }
+ }
+ }
+ out_print(res,
+ "<tr><td>Check task</a></td><td>Every %d cycle</td></tr>",
+ p->every?p->every:1);
+ out_print(res,
+ "<tr><td>Timeout</a></td><td>Timeout if %d restart within %d cycles"
+ "</td></tr>", p->to_start, p->to_cycle);
+ {
+ Mail_T r;
+ for(r= p->maillist; r; r= r->next) {
+ out_print(res,
+ "<tr bgcolor=\"#EFEFEF\"><td>Alert mail to</a></td><td>%s</td></tr>",
+ r->to?r->to:"");
+ out_print(res,
+ "<tr><td>Alert from</a></td><td>%s</td></tr>",
+ r->from?r->from:"(default)");
+ out_print(res,
+ "<tr><td>Alert subject</a></td><td>%s</td></tr>",
+ r->subject?r->subject:"(default)");
+ out_print(res,
+ "<tr><td>Alert message</a></td><td>%s</td></tr>",
+ r->message?r->message:"(default)");
+ out_print(res,
+ "<tr><td>Alert on timeout</a></td><td>%s</td></tr>",
+ r->alert_on_timeout?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on restart</a></td><td>%s</td></tr>",
+ r->alert_on_restart?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on checksum</a></td><td>%s</td></tr>",
+ r->alert_on_checksum?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on exceeded resource</a></td><td>%s</td></tr>",
+ r->alert_on_resource?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on stop</a></td><td>%s</td></tr>",
+ r->alert_on_stop?"yes":"no");
+ out_print(res,
+ "<tr><td>Alert on timestamp</a></td><td>%s</td></tr>",
+ r->alert_on_timestamp?"yes":"no");
+ }
+ }
+ out_print(res, "</table>");
+ out_print(res, "<table cellspacing=16><tr nowrap><td><font size=+1>");
+ /* Start program */
+ if(p->start)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='start' name=action>"
+ "<input type=submit value='Start program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ /* Stop program */
+ if(p->stop)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='stop' name=action>"
+ "<input type=submit value='Stop program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ if(p->start && p->stop)
+ out_print(res,
+ "<td><form method=GET action=/%s>"
+ "<input type=hidden value='restart' name=action>"
+ "<input type=submit value='Restart program' style='font-size:
12pt'></font>"
+ "</form></td>", p->name);
+ out_print(res, "</tr></table>");
+
+}
+
diff -Naur monit.20030423.base/l.l monit.20030423/l.l
--- monit.20030423.base/l.l Fri Feb 14 10:20:05 2003
+++ monit.20030423/l.l Wed Apr 23 10:47:46 2003
@@ -69,6 +69,11 @@
loadavg15 load(avg)[ ]*\([ ]*15[ ]*(m|min)?[ ]*\)
startarg start{wws}(program)?{wws}["]
stoparg stop{wws}(program)?{wws}["]
+percent ("percent"|"%")
+byte ("byte"|"b")
+kilobyte ("kilobyte"|"kb")
+megabyte ("megabyte"|"mb")
+gigabyte ("gigabyte"|"gb")
%x ARGUMENT
@@ -92,6 +97,7 @@
sum {/* EMPTY */}
restarts {/* EMPTY */}
th(a|e)n {/* EMPTY */}
+usage {/* EMPTY */}
{startarg} { BEGIN(ARGUMENT); return START; }
{stoparg} { BEGIN(ARGUMENT); return STOP; }
@@ -113,6 +119,7 @@
allow { return ALLOW; }
check { return CHECK; }
pidfile { return PIDFILE; }
+path { return PATHTOK; }
start { return START; }
stop { return STOP; }
port(number)? { return PORT; }
@@ -162,6 +169,18 @@
sslv3 { return SSLV3; }
tlsv1 { return TLSV1; }
sslauto { return SSLAUTO; }
+directory { return DIRECTORY; }
+file { return FILETOK; }
+device { return DEVICE; }
+process { return PROCESS; }
+inode(s)? { return INODE; }
+space { return SPACE; }
+
+{percent} { return PERCENT; }
+{byte} { return BYTE; }
+{kilobyte} { return KILOBYTE; }
+{megabyte} { return MEGABYTE; }
+{gigabyte} { return GIGABYTE; }
{loadavg1} { return LOADAVG1; }
{loadavg5} { return LOADAVG5; }
@@ -204,6 +223,11 @@
yylval.string= xstrdup(yytext);
return PATH;
}
+
+"/" {
+ yylval.string= xstrdup(yytext);
+ return PATH;
+ }
{noslash}/[/] {
yyerror("A path must be fully qualified");
diff -Naur monit.20030423.base/monit_process.c monit.20030423/monit_process.c
--- monit.20030423.base/monit_process.c Fri Feb 14 10:20:05 2003
+++ monit.20030423/monit_process.c Wed Apr 23 10:47:46 2003
@@ -79,6 +79,7 @@
"not equal to"};
char operatorshortnames[][3]= {">", "<", "=", "!="};
char statusnames[][STRLEN]= {"not monitored", "monitored" };
+char tasknames[][STRLEN]= {"Device Name", "Directory Name", "File Name",
"Process Name" };
int include_children= TRUE;
int num_cpus=1;
diff -Naur monit.20030423.base/monit_process.h monit.20030423/monit_process.h
--- monit.20030423.base/monit_process.h Fri Feb 14 10:20:05 2003
+++ monit.20030423/monit_process.h Wed Apr 23 10:47:46 2003
@@ -34,6 +34,7 @@
extern char operatornames[][STRLEN];
extern char operatorshortnames[][3];
extern char statusnames[][STRLEN];
+extern char tasknames[][STRLEN];
extern int num_cpus;
#define RESOURCE_ID_CPU_PERCENT 1
diff -Naur monit.20030423.base/monitor.h monit.20030423/monitor.h
--- monit.20030423.base/monitor.h Mon Mar 10 14:13:47 2003
+++ monit.20030423/monitor.h Wed Apr 23 10:47:46 2003
@@ -83,6 +83,24 @@
#define ACTION_RESTART 2
#define ACTION_STOP 3
+#define TASK_DEVICE 0
+#define TASK_DIRECTORY 1
+#define TASK_FILE 2
+#define TASK_PROCESS 3
+
+#define RESOURCE_CPU 1
+#define RESOURCE_MEM 2
+#define RESOURCE_LOAD1 4
+#define RESOURCE_LOAD5 5
+#define RESOURCE_LOAD15 6
+#define RESOURCE_INODE 7
+#define RESOURCE_SPACE 8
+
+#define UNIT_BYTE 1
+#define UNIT_KILOBYTE 1024
+#define UNIT_MEGABYTE 1048580
+#define UNIT_GIGABYTE 1073740000
+
#define MAXIMUM(x,y) ((x) > (y) ? (x) : (y))
#define is(a,b) ((a&&b)?!strcasecmp(a, b):0)
@@ -230,7 +248,7 @@
/** Defines resource data */
typedef struct myresource {
int resource_id; /**< Which value is checked */
- long int limit; /**< Limit of the resource */
+ long limit; /**< Limit of the resource */
int operator; /**< Comparison operator */
int cycle; /**< Cycle overrun counter */
int max_cycle; /**< Cycle overrun limit */
@@ -272,10 +290,33 @@
int length; /**< The length of the arguments array */
} *Command_T;
+/** Defines filesystem device data */
+typedef struct mydeviceinfo {
+ long f_bsize; /**< Transfer block size */
+ long f_blocks; /**< Total data blocks in filesystem */
+ long f_blocksfree; /**< Free blocks available to non-superuser */
+ long f_blocksfreetotal; /**< Free blocks in filesystem */
+ long f_files; /**< Total file nodes in filesystem */
+ long f_filesfree; /**< Free file nodes in filesystem */
+} *DeviceInfo_T;
+
+/** Defines filesystem device configuration */
+typedef struct mydevice {
+ int resource; /**< Whether to check inode or space */
+ int operator; /**< Comparison operator */
+ long limit_absolute; /**< Watermark - blocks */
+ int limit_percent; /**< Watermark - percent */
+ int action; /**< Action in case of failure */
+
+ struct mydevice *next;
+} *Device_T;
+
/** Defines process data */
typedef struct myprocess {
+
+ /** Common parameters */
+ int task; /**< Monitored task type */
char *name; /**< Process descriptive name */
- char *pidfile; /**< The pid file of the process */
char *group; /**< Process group name */
Command_T start; /**< The start command for the process */
Command_T stop; /**< The stop command for the process */
@@ -301,12 +342,20 @@
Resource_T resourcelist; /**< Resouce check list */
Dependant_T dependantlist; /**<Dependant process list */
Timestamp_T timestamplist; /**< Timestamp check list */
+ Device_T devicelist; /**< Device check list */
+
+ /** Runtime parameters */
+ DeviceInfo_T devinfo; /**< Data for the device check */
ProcInfo_T procinfo; /**< Data for the procfs check */
+
+ /** Context specific parameters */
+ char *path; /**< Path to the device, file, directory or process pid file */
/** For internal use */
pthread_mutex_t mutex; /**< Mutex used for action synchronization */
struct myprocess *next; /**< next process in chain */
struct myprocess *next_depend; /**< next depend process in chain */
+
} *Process_T;
@@ -392,4 +441,6 @@
int state_should_update();
void state_update();
void state_finalize();
+char *get_device(char *, unsigned, char *);
+int get_fsusage(char *, DeviceInfo_T);
#endif
diff -Naur monit.20030423.base/monitrc monit.20030423/monitrc
--- monit.20030423.base/monitrc Fri Feb 7 13:17:24 2003
+++ monit.20030423/monitrc Wed Apr 23 10:47:46 2003
@@ -233,4 +233,26 @@
# port 4001
# timeout if 2 restarts within 3 cycles
# alert address@hidden
+# depends on datafs
# group database
+#
+#
+# check device datafs path /data
+# start program = "/bin/mount /data"
+# stop program = "/bin/umount /data"
+# if space usage > 80 % then stop
+# if inode usage > 80 % then stop
+# alert address@hidden
+# group database
+#
+#
+# check device rootfs path /dev/sda1
+# if space usage > 3 GB then alert
+# if inode usage > 30000 then alert
+# alert address@hidden
+#
+#
+# check file su path /bin/su
+#
+#
+# check directory bin path /bin
diff -Naur monit.20030423.base/p.y monit.20030423/p.y
--- monit.20030423.base/p.y Fri Feb 14 09:22:33 2003
+++ monit.20030423/p.y Wed Apr 23 10:47:46 2003
@@ -61,6 +61,10 @@
#include <netdb.h>
#endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+
#include "net.h"
#include "monitor.h"
@@ -119,6 +123,14 @@
int action;
};
+ struct DeviceSet {
+ int resource;
+ int operator;
+ long limit_absolute;
+ int limit_percent;
+ int action;
+ };
+
/* yacc interface */
void yyerror(const char *);
@@ -136,24 +148,26 @@
static Process_T depend_list= NULL;
static struct IHavePrecedence ihp= {FALSE, FALSE, FALSE};
static struct MailFilter mtf= {NULL, NULL, NULL, FALSE, FALSE, FALSE,
- FALSE, FALSE, FALSE};
- static struct PortSet portset= {-1, NULL, 0, SOCK_STREAM, AF_INET, FALSE,
- SSL_VERSION_AUTO, NULL, NULL, NULL, NULL};
+ FALSE, FALSE, FALSE};
+ static struct PortSet portset= {-1, NULL, 0, SOCK_STREAM, AF_INET, FALSE,
+ SSL_VERSION_AUTO, NULL, NULL, NULL, NULL};
static struct ResourceSet resourceset= {0, 0, OPERATOR_EQUAL, 1,
- ACTION_ALERT};
+ ACTION_ALERT};
static struct TimestampSet timestampset= {NULL, OPERATOR_EQUAL, 0,
- ACTION_ALERT};
+ ACTION_ALERT};
+ static struct DeviceSet deviceset= {0, OPERATOR_EQUAL, -1, -1, ACTION_ALERT};
/* Private prototypes */
static void initialize();
static void addprocess(Process_T);
static void addmail(char *, struct MailFilter *);
- static void createprocess(char *, char *);
+ static void createprocess(int, char *, char *);
static void adddependant(char *);
static void addchecksum(char *, char *);
static void addport(struct PortSet *);
static void addresource(struct ResourceSet *);
static void addtimestamp(struct TimestampSet *);
+ static void adddevice(struct DeviceSet *);
static void *addprotocol(int);
static void addcommand(int);
static void addargument(char *);
@@ -167,11 +181,12 @@
static void reset_portset();
static void reset_resourceset();
static void reset_timestampset();
+ static void reset_deviceset();
static void check_name(char *);
static void check_timeout(int, int);
static void check_every (int);
static void check_hostname (char *);
- static void createprocinfo();
+ static void createinfo();
static char *append_hostname(char *);
static void cleanup_md5_string(char *);
static void check_depend();
@@ -187,7 +202,7 @@
%token SET LOGFILE DAEMON SYSLOG MAILSERVER HTTPD ALLOW ADDRESS INIT
%token PEMFILE ENABLE DISABLE HTTPDSSL CLIENTPEMFILE ALLOWSELFCERTIFICATION
-%token CHECK PIDFILE START STOP
+%token CHECK PIDFILE START STOP PATHTOK
%token HOST PORT TYPE UDP TCP TCPSSL PROTOCOL
%token ALERT MAILFORMAT UNIXSOCKET
%token TIMEOUT RESTART CHECKSUM EXPECT EVERY
@@ -201,6 +216,9 @@
%token GROUP REQUEST DEPENDS
%token TIMESTAMP SECOND MINUTE HOUR DAY
%token SSLAUTO SSLV2 SSLV3 TLSV1
+%token PERCENT BYTE KILOBYTE MEGABYTE GIGABYTE
+%token DIRECTORY FILETOK DEVICE PROCESS
+%token INODE SPACE
%left GREATER LESS EQUAL NOTEQUAL
@@ -250,6 +268,12 @@
resourceset.action= $<number>3;
addresource(&resourceset);
}
+ | inode {
+ adddevice(&deviceset);
+ }
+ | space {
+ adddevice(&deviceset);
+ }
;
setdaemon : SET DAEMON NUMBER {
@@ -401,9 +425,21 @@
}
;
-check : CHECK STRING PIDFILE PATH {
- createprocess($2,$4);
- check_name($2);
+check : CHECK PROCESS STRING PIDFILE PATH {
+ createprocess(TASK_PROCESS, $3,$5);
+ check_name($3);
+ }
+ | CHECK FILETOK STRING PATHTOK PATH {
+ createprocess(TASK_FILE, $3,$5);
+ check_name($3);
+ }
+ | CHECK DEVICE STRING PATHTOK PATH {
+ createprocess(TASK_DEVICE, $3,$5);
+ check_name($3);
+ }
+ | CHECK DIRECTORY STRING PATHTOK PATH {
+ createprocess(TASK_DIRECTORY, $3,$5);
+ check_name($3);
}
;
@@ -627,6 +663,48 @@
| STOP { $<number>$= ACTION_STOP; }
;
+inode : INODE operator NUMBER action {
+ deviceset.resource= RESOURCE_INODE;
+ deviceset.operator= $<number>2;
+ deviceset.limit_absolute= $3;
+ deviceset.action= $<number>4;
+ }
+ | INODE operator NUMBER PERCENT action {
+ deviceset.resource= RESOURCE_INODE;
+ deviceset.operator= $<number>2;
+ deviceset.limit_percent= $<number>3;
+ deviceset.action= $<number>5;
+ }
+ ;
+
+space : SPACE operator NUMBER unit action {
+
+ DeviceInfo_T di= NEW(di);
+
+ get_fsusage(current->path, di);
+
+ deviceset.resource= RESOURCE_SPACE;
+ deviceset.operator= $<number>2;
+ deviceset.limit_absolute= (int)( (float)$3 /
(float)di->f_bsize * (float)$<number>4 );
+ deviceset.action= $<number>5;
+
+ free(di);
+
+ }
+ | SPACE operator NUMBER PERCENT action {
+ deviceset.resource= RESOURCE_SPACE;
+ deviceset.operator= $<number>2;
+ deviceset.limit_percent= $<number>3;
+ deviceset.action= $<number>5;
+ }
+ ;
+
+unit : BYTE { $<number>$= UNIT_BYTE; }
+ | KILOBYTE { $<number>$= UNIT_KILOBYTE; }
+ | MEGABYTE { $<number>$= UNIT_MEGABYTE; }
+ | GIGABYTE { $<number>$= UNIT_GIGABYTE; }
+ ;
+
%%
@@ -680,7 +758,7 @@
/* If defined - add the last process to the process list */
if(current) {
- createprocinfo();
+ createinfo();
addprocess(current);
}
@@ -725,14 +803,14 @@
* Create a new process object and add any current objects to the
* process list.
*/
-static void createprocess(char *name, char *pidfile) {
+static void createprocess(int task, char *name, char *path) {
ASSERT(name);
- ASSERT(pidfile);
+ ASSERT(path);
if(current) {
- createprocinfo();
+ createinfo();
addprocess(current);
}
@@ -749,8 +827,9 @@
current->do_validate= TRUE;
current->mode= MODE_ACTIVE;
+ current->task= task;
current->name= name;
- current->pidfile= pidfile;
+ current->path= path;
current->group= NULL;
current->dependantlist= NULL;
@@ -768,10 +847,6 @@
ASSERT(p);
- /* if process is already running... set validate true */
- if (is_process_running(p))
- p->do_validate= TRUE;
-
n= NEW(n);
memcpy(n, p, sizeof(*p));
@@ -1026,12 +1101,37 @@
/*
- * Adds procfs check data to current process procinfo
+ * Add a new device to the current tasks device list
*/
-static void createprocinfo() {
+static void adddevice(struct DeviceSet *ds) {
+
+ Device_T d= NEW(d);
+
+ ASSERT(ds);
+
+ d->resource= ds->resource;
+ d->operator= ds->operator;
+ d->limit_absolute= ds->limit_absolute;
+ d->limit_percent= ds->limit_percent;
+ d->action= ds->action;
+
+ d->next= current->devicelist;
+ current->devicelist= d;
+
+ reset_deviceset();
+
+}
+
+/*
+ * Adds runtime info to current process
+ */
+static void createinfo() {
+
+ DeviceInfo_T di= NEW(di);
ProcInfo_T pi= NEW(pi);
+ current->devinfo=di;
current->procinfo=pi;
}
@@ -1130,7 +1230,7 @@
/*
- * Reset the pidfil if changed
+ * Reset the pidfile if changed
*/
static void setpidfile(char *pidfile) {
@@ -1306,6 +1406,20 @@
}
+
+/*
+ * Reset the Device set to default values
+ */
+static void reset_deviceset() {
+
+ deviceset.resource= 0;
+ deviceset.operator= OPERATOR_EQUAL;
+ deviceset.limit_absolute= -1;
+ deviceset.limit_percent= -1;
+ deviceset.action= ACTION_ALERT;
+
+}
+
/* ---------------------------------------------------------------- Checkers */
diff -Naur monit.20030423.base/status.c monit.20030423/status.c
--- monit.20030423.base/status.c Fri Feb 14 10:20:05 2003
+++ monit.20030423/status.c Wed Apr 23 10:47:46 2003
@@ -163,7 +163,7 @@
if((pid= is_process_running(p))) {
- char *uptime= get_process_uptime(p->pidfile);
+ char *uptime= get_process_uptime(p->path);
fprintf(stdout, "Process '%s' is running with pid [%d] Uptime: %s "
"Monitoring status: %s\n",
diff -Naur monit.20030423.base/util.c monit.20030423/util.c
--- monit.20030423.base/util.c Fri Mar 7 15:24:42 2003
+++ monit.20030423/util.c Wed Apr 23 10:47:46 2003
@@ -447,13 +447,17 @@
Resource_T q;
Checksum_T c;
Timestamp_T t;
+ Device_T dl;
Dependant_T d;
ASSERT(p);
- printf("%-21s = %s\n", "Process Name", p->name);
+ printf("%-21s = %s\n", tasknames[p->task], p->name);
printf(" %-20s = %s\n", "Group", is_str_defined(p->group));
- printf(" %-20s = %s\n", "Pid file", p->pidfile);
+ if(p->task == TASK_PROCESS)
+ printf(" %-20s = %s\n", "Pid file", p->path);
+ else
+ printf(" %-20s = %s\n", "Path", p->path);
printf(" %-20s = %s\n", "Monitoring mode", modenames[p->mode]);
if(p->start)
printf(" %-20s = %s\n", "Start program", is_str_defined(p->start->arg[0]));
@@ -470,12 +474,8 @@
if(d->dependant != NULL)
printf(" %-20s = %s\n", "Depends on Process", d->dependant);
- if(! p->portlist) {
+ if(p->portlist) {
- printf(" %-20s = (not defined)\n", "Host:Port");
-
- } else {
-
for(n= p->portlist; n; n= n->next) {
if(n->family == AF_INET) {
@@ -486,13 +486,8 @@
n->hostname, n->port, n->request?n->request:"",
n->protocol->name);
- if(n->certmd5 != NULL) {
-
- printf(" %-20s = %s\n",
- "Server cert md5 sum",
- n->certmd5);
-
- }
+ if(n->certmd5 != NULL)
+ printf(" %-20s = %s\n", "Server cert md5 sum", n->certmd5);
} else {
@@ -524,12 +519,30 @@
}
- if(! p->resourcelist) {
+ for(dl= p->devicelist; dl; dl= dl->next) {
+
+ if(dl->resource == RESOURCE_INODE) {
- printf(" %-20s = (not defined)\n", "Resource Limits");
+ printf(" %-20s = if %s %ld %s then %s\n",
+ "Inodes usage limit",
+ operatornames[dl->operator],
+ (dl->limit_absolute > -1)?dl->limit_absolute:dl->limit_percent,
+ (dl->limit_absolute > -1)?"":"%",
+ actionnames[dl->action]);
+
+ } else if(dl->resource == RESOURCE_SPACE) {
+
+ printf(" %-20s = if %s %ld %s then %s\n",
+ "Space usage limit",
+ operatornames[dl->operator],
+ (dl->limit_absolute > -1)?dl->limit_absolute:dl->limit_percent,
+ (dl->limit_absolute > -1)?"blocks":"%",
+ actionnames[dl->action]);
- }
+ }
+ }
+
for(q= p->resourcelist; q; q= q->next) {
switch(q->resource_id) {
@@ -586,25 +599,12 @@
}
if(p->def_every)
-
printf(" %-20s = Check process every %d cycles\n", "Every", p->every);
- else {
-
- printf(" %-20s = (not defined)\n", "Every");
-
- }
- if(p->def_timeout) {
-
+ if(p->def_timeout)
printf(" %-20s = Do timeout if %d restart within %d cycles\n",
"Timeout", p->to_start, p->to_cycle);
-
- } else {
-
- printf(" %-20s = (not defined)\n", "Timeout");
-
- }
for(r= p->maillist; r; r= r->next) {
@@ -721,7 +721,7 @@
errno= 0;
- if((pid= get_pid(p->pidfile))) {
+ if((pid= get_pid(p->path))) {
if((kill_return= getpgid(pid)) > 0 || errno == EPERM)
diff -Naur monit.20030423.base/validate.c monit.20030423/validate.c
--- monit.20030423.base/validate.c Fri Mar 7 15:24:42 2003
+++ monit.20030423/validate.c Wed Apr 23 10:47:46 2003
@@ -57,6 +57,7 @@
static int check_checksum(Process_T);
static int checksum_helper(Process_T, char *, char *);
static int check_timestamp(Process_T, Timestamp_T, char *);
+static int check_device(Process_T, Device_T, char *);
static void connection_timeout(int);
static void reset_resource_counter(Process_T);
static void vlog(char * report, int n, Process_T p, char *m,...);
@@ -124,6 +125,7 @@
Port_T pp;
Resource_T pr;
Timestamp_T tl;
+ Device_T td;
pid_t pid= -1;
sigset_t ns,os;
char report[STRLEN];
@@ -145,82 +147,138 @@
sigaddset(&ns, SIGTERM);
pthread_sigmask(SIG_BLOCK, &ns, &os);
- /* Test for running process */
- if(!(pid= is_process_running(p))) {
- /* Reset the proc info object to prevent false data in the first run */
- memset(p->procinfo, 0, sizeof *(p->procinfo));
+ /** Context specific task actions */
+ switch(p->task) {
+
+ case TASK_PROCESS:
+
+ /* Test for running process */
+ if(!(pid= is_process_running(p))) {
+
+ /* Reset the proc info object to prevent false data in the first run */
+ memset(p->procinfo, 0, sizeof *(p->procinfo));
- do_start(p, "Reason: Process is not running.");
- goto reinstall;
+ do_start(p, "Reason: Process is not running.");
+ goto reinstall;
- } else {
+ } else {
- if(Run.debug) {
+ if(Run.debug) {
- log("'%s' is running with pid %d\n", p->name, (int)pid);
+ log("'%s' is running with pid %d\n", p->name, (int)pid);
- }
+ }
- }
+ }
- if(Run.doprocess) {
+ if(Run.doprocess) {
- if(update_process_data(p, pid)) {
+ if(update_process_data(p, pid)) {
- if(! check_process_state(p, report)) {
+ if(! check_process_state(p, report)) {
- smtp_alert_resource(p, "Reason: %s\n", report);
+ smtp_alert_resource(p, "Reason: %s\n", report);
- } else {
+ } else {
- if(Run.debug) {
+ if(Run.debug) {
- log("'%s' check_process_state() passed.\n", p->name);
+ log("'%s' check_process_state() passed.\n", p->name);
- }
+ }
- }
+ }
- for(pr= p->resourcelist; pr; pr= pr->next) {
+ for(pr= p->resourcelist; pr; pr= pr->next) {
- if(!check_resources(p, pr, report)) {
+ if(!check_resources(p, pr, report)) {
- switch(pr->action) {
- case ACTION_ALERT:
+ switch(pr->action) {
+ case ACTION_ALERT:
if(p->def_timeout) p->nstart++;
smtp_alert_resource(p, "Reason: %s\n", report);
/* We are also interested in other alerts/stops/restarts! */
pr->cycle=0;
break;
- case ACTION_STOP:
+ case ACTION_STOP:
do_stop(p, "Reason: %s\n", report);
reset_resource_counter(p);
goto reinstall;
- case ACTION_RESTART:
+ case ACTION_RESTART:
do_restart(p, "Reason: %s\n", report);
reset_resource_counter(p);
goto reinstall;
- default:
+ default:
log("'%s' Unknow resource failure action.\n", p->name);
break;
+ }
+
}
+
+ }
+
+ } else {
- }
+ log("'%s' failed to get process data\n", p->name);
}
-
- } else {
- log("'%s' failed to get process data\n", p->name);
+ }
+
+ /* Test each host:port and protocol in the process's portlist */
+ for(pp= p->portlist; pp; pp= pp->next) {
+
+ if(!check_connection(p, pp, report)) {
+
+ do_restart(p, "Reason: %s\n", report);
+ goto reinstall;
+ }
+
}
+ break;
+
+ case TASK_DEVICE:
+
+ /* Test devices */
+ if(p->devicelist && get_fsusage(p->path, p->devinfo)) {
+
+ for(td= p->devicelist; td; td= td->next) {
+
+ if(!check_device(p, td, report)) {
+
+ switch(td->action) {
+ case ACTION_ALERT:
+ smtp_alert_resource(p, "Reason: %s\n", report);
+ break;
+
+ case ACTION_STOP:
+ do_stop(p, "Reason: %s\n", report);
+ goto reinstall;
+
+ default:
+ log("'%s' Unknow device failure action.\n", p->name);
+ break;
+ }
+
+ }
+
+ }
+
+ }
+ break;
+
+ default:
+ break;
}
+
+ /** Common task actions */
for(tl= p->timestamplist; tl; tl= tl->next) {
if(!check_timestamp(p, tl, report)) {
@@ -249,18 +307,6 @@
}
- /* Test each host:port and protocol in the process's portlist */
- for(pp= p->portlist; pp; pp= pp->next) {
-
- if(!check_connection(p, pp, report)) {
-
- do_restart(p, "Reason: %s\n", report);
- goto reinstall;
-
- }
-
- }
-
reinstall:
/* Remove the SIGTERM block */
@@ -980,6 +1026,118 @@
}
+
+/**
+ * Returns TRUE if the device test succeeded
+ * otherwise FALSE.
+ */
+static int check_device(Process_T t, Device_T td, char *report) {
+
+ ASSERT(t);
+ ASSERT(td);
+
+ if( (td->limit_percent < 0) && (td->limit_absolute < 0) ) {
+
+ log("'%s' error: device limit not set\n", t->name);
+ return FALSE;
+
+ }
+
+ switch(td->resource) {
+
+ case RESOURCE_INODE:
+
+ if(td->limit_percent >= 0) {
+
+ if(compare_value(td->operator, 100 * (t->devinfo->f_files -
t->devinfo->f_filesfree) / t->devinfo->f_files, td->limit_percent)) {
+
+ vlog(report, STRLEN, t,
+ "inode usage %d%% matches resource limit [inode usage%s%d%%]",
+ 100 * (t->devinfo->f_files - t->devinfo->f_filesfree) /
t->devinfo->f_files,
+ operatorshortnames[td->operator],
+ td->limit_percent);
+
+ return FALSE;
+
+ }
+
+ } else {
+
+ if(compare_value(td->operator, t->devinfo->f_files -
t->devinfo->f_filesfree, td->limit_absolute)) {
+
+ vlog(report, STRLEN, t,
+ "inode usage %d matches resource limit [inode usage%s%d]",
+ t->devinfo->f_files - t->devinfo->f_filesfree,
+ operatorshortnames[td->operator],
+ td->limit_absolute);
+
+ return FALSE;
+
+ }
+
+ }
+
+ if(Run.debug) {
+
+ log("'%s' inode usage check passed [current inode usage=%.1f%%]\n",
+ t->name,
+ (float) 100 * (t->devinfo->f_files - t->devinfo->f_filesfree) /
t->devinfo->f_files);
+
+ }
+
+ return TRUE;
+
+ case RESOURCE_SPACE:
+
+ if(td->limit_percent >= 0) {
+
+ if(compare_value(td->operator, 100 * (t->devinfo->f_blocks -
t->devinfo->f_blocksfree) / t->devinfo->f_blocks, td->limit_percent)) {
+
+ vlog(report, STRLEN, t,
+ "space usage %d%% matches resource limit [space usage%s%d%%]",
+ 100 * (t->devinfo->f_blocks - t->devinfo->f_blocksfree) /
t->devinfo->f_blocks,
+ operatorshortnames[td->operator],
+ td->limit_percent);
+
+ return FALSE;
+
+ }
+
+ } else {
+
+ if(compare_value(td->operator, t->devinfo->f_blocks -
t->devinfo->f_blocksfree, td->limit_absolute)) {
+
+ vlog(report, STRLEN, t,
+ "space usage %d blocks matches resource limit [space usage%s%d
blocks]",
+ t->devinfo->f_blocks - t->devinfo->f_blocksfree,
+ operatorshortnames[td->operator],
+ td->limit_absolute);
+
+ return FALSE;
+
+ }
+
+ }
+
+ if(Run.debug) {
+
+ log("'%s' space usage check passed [current space usage=%.1f%%]\n",
+ t->name,
+ (float) 100 * (t->devinfo->f_blocks - t->devinfo->f_blocksfree) /
t->devinfo->f_blocks);
+
+ }
+
+ return TRUE;
+
+ default:
+
+ log("'%s' error: unknow resource type: [%d]\n", t->name, td->resource);
+ return FALSE;
+
+ }
+
+}
+
/**
* Signal handler for connection timeout
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- initial patch for device/file/directory stuff,
Martin Pala <=