summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am4
-rw-r--r--plugins/check_nagios.c5
-rw-r--r--plugins/check_procs.c362
-rw-r--r--plugins/check_vsz.c250
4 files changed, 265 insertions, 356 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index a884b451..0692cd28 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -7,7 +7,7 @@ INCLUDES = -I.. -I$(top_srcdir)/lib @LDAPINCLUDE@ @PGINCLUDE@ @SSLINCLUDE@
7libexec_PROGRAMS = check_disk check_dummy check_http check_load \ 7libexec_PROGRAMS = check_disk check_dummy check_http check_load \
8 check_mrtg check_mrtgtraf check_nwstat check_overcr check_ping \ 8 check_mrtg check_mrtgtraf check_nwstat check_overcr check_ping \
9 check_procs check_real check_smtp check_ssh check_tcp check_time \ 9 check_procs check_real check_smtp check_ssh check_tcp check_time \
10 check_udp check_ups check_users check_vsz negate urlize \ 10 check_udp check_ups check_users negate urlize \
11 @EXTRAS@ 11 @EXTRAS@
12 12
13EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ 13EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \
@@ -68,7 +68,6 @@ check_time_LDADD = $(NETLIBS)
68check_udp_LDADD = $(NETLIBS) 68check_udp_LDADD = $(NETLIBS)
69check_ups_LDADD = $(NETLIBS) 69check_ups_LDADD = $(NETLIBS)
70check_users_LDADD = $(BASEOBJS) popen.o 70check_users_LDADD = $(BASEOBJS) popen.o
71check_vsz_LDADD = $(BASEOBJS) popen.o
72check_by_ssh_LDADD = $(NETLIBS) popen.o 71check_by_ssh_LDADD = $(NETLIBS) popen.o
73negate_LDADD = $(BASEOBJS) popen.o 72negate_LDADD = $(BASEOBJS) popen.o
74urlize_LDADD = $(BASEOBJS) popen.o 73urlize_LDADD = $(BASEOBJS) popen.o
@@ -104,7 +103,6 @@ check_time_DEPENDENCIES = check_time.c $(NETOBJS) $(DEPLIBS)
104check_udp_DEPENDENCIES = check_udp.c $(NETOBJS) $(DEPLIBS) 103check_udp_DEPENDENCIES = check_udp.c $(NETOBJS) $(DEPLIBS)
105check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS) 104check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS)
106check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS) 105check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS)
107check_vsz_DEPENDENCIES = check_vsz.c $(BASEOBJS) popen.o $(DEPLIBS)
108check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) popen.o $(DEPLIBS) 106check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) popen.o $(DEPLIBS)
109negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS) 107negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS)
110urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS) 108urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS)
diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c
index 083b5028..64a828b9 100644
--- a/plugins/check_nagios.c
+++ b/plugins/check_nagios.c
@@ -55,6 +55,9 @@ main (int argc, char **argv)
55 FILE *fp; 55 FILE *fp;
56 int procuid = 0; 56 int procuid = 0;
57 int procppid = 0; 57 int procppid = 0;
58 int procvsz = 0;
59 int procrss = 0;
60 float procpcpu = 0;
58 char procstat[8]; 61 char procstat[8];
59 char procprog[MAX_INPUT_BUFFER]; 62 char procprog[MAX_INPUT_BUFFER];
60 char *procargs; 63 char *procargs;
@@ -106,7 +109,7 @@ main (int argc, char **argv)
106 /* count the number of matching Nagios processes... */ 109 /* count the number of matching Nagios processes... */
107 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { 110 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
108 cols = sscanf (input_buffer, PS_FORMAT, PS_VARLIST); 111 cols = sscanf (input_buffer, PS_FORMAT, PS_VARLIST);
109 if ( cols >= 4 ) { 112 if ( cols >= 6 ) {
110 asprintf (&procargs, "%s", input_buffer + pos); 113 asprintf (&procargs, "%s", input_buffer + pos);
111 strip (procargs); 114 strip (procargs);
112 115
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index 29f86bed..2cf550cc 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -39,11 +39,64 @@ const char *progname = "check_procs";
39#define COPYRIGHT "1999-2002" 39#define COPYRIGHT "1999-2002"
40#define AUTHOR "Ethan Galstad" 40#define AUTHOR "Ethan Galstad"
41#define EMAIL "nagios@nagios.org" 41#define EMAIL "nagios@nagios.org"
42#define SUMMARY "Check the number of currently running processes and generates WARNING or\n\ 42#define SUMMARY "\
43CRITICAL states if the process count is outside the specified threshold\n\ 43Checks all processes and generates WARNING or CRITICAL states if the specified\n\
44ranges. The process count can be filtered by process owner, parent process\n\ 44metric is outside the required threshold ranges. The metric defaults to number\n\
45PID, current state (e.g., 'Z'), or may be the total number of running\n\ 45of processes. Search filters can be applied to limit the processes to check.\n"
46processes\n" 46
47#define OPTIONS "\
48-w <range> -c <range> [-m metric]\n\
49 [-s state] [-p ppid] [-u user] [-r rss] [-z vsz] [-P %cpu]\n\
50 [-a argument-array] [-C command] [-v]"
51
52#define LONGOPTIONS "\
53Required Arguments:\n\
54 -w, --warning=RANGE\n\
55 Generate warning state if metric is outside this range\n\
56 -c, --critical=RANGE\n\
57 Generate critical state if metric is outside this range\n\
58Optional Arguments:\n\
59 -m, --metric=TYPE\n\
60 Check thresholds against metric. Valid types:\n\
61 PROCS - number of processes (default)\n\
62 VSZ - virtual memory size\n\
63 RSS - resident set memory size\n\
64 CPU - percentage cpu\n\
65 -v, --verbose\n\
66 Extra information. Up to 3 verbosity levels\n\
67Optional Filters:\n\
68 -s, --state=STATUSFLAGS\n\
69 Only scan for processes that have, in the output of `ps`, one or\n\
70 more of the status flags you specify (for example R, Z, S, RS,\n\
71 RSZDT, plus others based on the output of your 'ps' command).\n\
72 -p, --ppid=PPID\n\
73 Only scan for children of the parent process ID indicated.\n\
74 -z, --vsz=VSZ\n\
75 Only scan for processes with vsz higher than indicated.\n\
76 -r, --rss=RSS\n\
77 Only scan for processes with rss higher than indicated.\n\
78 -P, --pcpu=PCPU\n\
79 Only scan for processes with pcpu higher than indicated.\n\
80 -u, --user=USER\n\
81 Only scan for processes with user name or ID indicated.\n\
82 -a, --argument-array=STRING\n\
83 Only scan for ARGS that match up to the length of the given STRING.\n\
84 -C, --command=COMMAND\n\
85 Only scan for exact matches to the named COMMAND.\n\
86\n\
87RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
88specified 'max:min', a warning status will be generated if the\n\
89count is inside the specified range\n"
90
91#define EXAMPLES "\
92 check_procs -w 2:2 -c 2:1024 -C portsentry\n\
93 Warning if not two processes with command name portsentry. Critical\n\
94 if < 2 or > 1024 processes\n\
95 check_procs -w 10 -a '/usr/local/bin/perl' -u root\n\
96 Warning alert if > 10 processes with command arguments containing \n\
97 '/usr/local/bin/perl' and owned by root\n\
98 check_procs -w 50000 -c 100000 --metric=VSZ\n\
99 Alert if vsz of any processes over 50K or 100K\n"
47 100
48#include "config.h" 101#include "config.h"
49#include <pwd.h> 102#include <pwd.h>
@@ -55,6 +108,7 @@ int process_arguments (int, char **);
55int validate_arguments (void); 108int validate_arguments (void);
56void print_usage (void); 109void print_usage (void);
57void print_help (void); 110void print_help (void);
111int check_thresholds (int);
58 112
59int wmax = -1; 113int wmax = -1;
60int cmax = -1; 114int cmax = -1;
@@ -68,16 +122,30 @@ int options = 0; /* bitmask of filter criteria to test against */
68#define USER 8 122#define USER 8
69#define PROG 16 123#define PROG 16
70#define ARGS 32 124#define ARGS 32
71 125#define VSZ 64
72int verbose = FALSE; 126#define RSS 128
127#define PCPU 256
128
129/* Different metrics */
130int metric = 0;
131#define METRIC_PROCS 0
132#define METRIC_VSZ 1
133#define METRIC_RSS 2
134#define METRIC_CPU 3
135char *metric_name = "";
136
137int verbose = 0;
73int uid; 138int uid;
74int ppid; 139int ppid;
140int vsz;
141int rss;
142float pcpu;
75char *statopts = ""; 143char *statopts = "";
76char *prog = ""; 144char *prog = "";
77char *args = ""; 145char *args = "";
78char *fmt = ""; 146char *fmt = "";
147char *fails = "";
79char tmp[MAX_INPUT_BUFFER]; 148char tmp[MAX_INPUT_BUFFER];
80const char *zombie = "Z";
81 149
82int 150int
83main (int argc, char **argv) 151main (int argc, char **argv)
@@ -86,24 +154,35 @@ main (int argc, char **argv)
86 154
87 int procuid = 0; 155 int procuid = 0;
88 int procppid = 0; 156 int procppid = 0;
157 int procvsz = 0;
158 int procrss = 0;
159 float procpcpu = 0;
89 char procstat[8]; 160 char procstat[8];
90 char procprog[MAX_INPUT_BUFFER]; 161 char procprog[MAX_INPUT_BUFFER];
91 char *procargs; 162 char *procargs;
92 163
164 const char *zombie = "Z";
165
93 int resultsum = 0; /* bitmask of the filter criteria met by a process */ 166 int resultsum = 0; /* bitmask of the filter criteria met by a process */
94 int found = 0; /* counter for number of lines returned in `ps` output */ 167 int found = 0; /* counter for number of lines returned in `ps` output */
95 int procs = 0; /* counter for number of processes meeting filter criteria */ 168 int procs = 0; /* counter for number of processes meeting filter criteria */
96 int pos; /* number of spaces before 'args' in `ps` output */ 169 int pos; /* number of spaces before 'args' in `ps` output */
97 int cols; /* number of columns in ps output */ 170 int cols; /* number of columns in ps output */
171 int warn = 0; /* number of processes in warn state */
172 int crit = 0; /* number of processes in crit state */
173 int i;
98 174
99 int result = STATE_UNKNOWN; 175 int result = STATE_UNKNOWN;
100 176
177 asprintf (&metric_name, "PROCS");
178 metric = METRIC_PROCS;
179
101 if (process_arguments (argc, argv) == ERROR) 180 if (process_arguments (argc, argv) == ERROR)
102 usage ("Unable to parse command line\n"); 181 usage ("Unable to parse command line\n");
103 182
104 /* run the command */ 183 if (verbose >= 2)
105 if (verbose) 184 printf ("CMD: %s\n", PS_COMMAND);
106 printf ("%s\n", PS_COMMAND); 185
107 child_process = spopen (PS_COMMAND); 186 child_process = spopen (PS_COMMAND);
108 if (child_process == NULL) { 187 if (child_process == NULL) {
109 printf ("Could not open pipe: %s\n", PS_COMMAND); 188 printf ("Could not open pipe: %s\n", PS_COMMAND);
@@ -117,18 +196,22 @@ main (int argc, char **argv)
117 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); 196 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
118 197
119 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { 198 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
199 strcpy(procprog,"");
200 asprintf(&procargs,"");
201
120 cols = sscanf (input_buffer, PS_FORMAT, PS_VARLIST); 202 cols = sscanf (input_buffer, PS_FORMAT, PS_VARLIST);
121 203
122 /* Zombie processes do not give a procprog command */ 204 /* Zombie processes do not give a procprog command */
205 /* - would they give other columns? */
123 if ( cols == 3 && strstr(procstat, zombie) ) { 206 if ( cols == 3 && strstr(procstat, zombie) ) {
124 strcpy(procprog, "");
125 cols = 4; 207 cols = 4;
126 } 208 }
127 if ( cols >= 4 ) { 209 if ( cols >= 7 ) {
128 found++; 210 found++;
129 resultsum = 0; 211 resultsum = 0;
130 asprintf (&procargs, "%s", input_buffer + pos); 212 asprintf (&procargs, "%s", input_buffer + pos);
131 strip (procargs); 213 strip (procargs);
214
132 if ((options & STAT) && (strstr (statopts, procstat))) 215 if ((options & STAT) && (strstr (statopts, procstat)))
133 resultsum |= STAT; 216 resultsum |= STAT;
134 if ((options & ARGS) && procargs && (strstr (procargs, args) == procargs)) 217 if ((options & ARGS) && procargs && (strstr (procargs, args) == procargs))
@@ -139,16 +222,43 @@ main (int argc, char **argv)
139 resultsum |= PPID; 222 resultsum |= PPID;
140 if ((options & USER) && (procuid == uid)) 223 if ((options & USER) && (procuid == uid))
141 resultsum |= USER; 224 resultsum |= USER;
142#ifdef DEBUG1 225 if ((options & VSZ) && (procvsz >= vsz))
143 if (procargs == NULL) 226 resultsum |= VSZ;
144 printf ("%d %d %d %s %s\n", procs, procuid, procppid, procstat, 227 if ((options & RSS) && (procrss >= rss))
145 procprog); 228 resultsum |= RSS;
146 else 229 if ((options & PCPU) && (procpcpu >= pcpu))
147 printf ("%d %d %d %s %s %s\n", procs, procuid, procppid, procstat, 230 resultsum |= PCPU;
148 procprog, procargs); 231
149#endif 232 if (verbose >= 3)
150 if (options == resultsum) 233 printf ("%d %d %d %d %d %.2f %s %s %s\n",
151 procs++; 234 procs, procuid, procvsz, procrss,
235 procppid, procpcpu, procstat, procprog, procargs);
236
237 /* Next line if filters not matched */
238 if (!(options == resultsum || options == ALL))
239 continue;
240
241 procs++;
242
243 if (metric == METRIC_VSZ)
244 i = check_thresholds (procvsz);
245 else if (metric == METRIC_RSS)
246 i = check_thresholds (procrss);
247 /* TODO? float thresholds for --metric=CPU */
248 else if (metric == METRIC_CPU)
249 i = check_thresholds ((int)procpcpu);
250
251 if (metric != METRIC_PROCS) {
252 if (i == STATE_WARNING) {
253 warn++;
254 asprintf (&fails, "%s%s%s", fails, (fails == "" ? "" : ", "), procprog);
255 }
256 if (i == STATE_CRITICAL) {
257 crit++;
258 asprintf (&fails, "%s%s%s", fails, (fails == "" ? "" : ", "), procprog);
259 }
260 result = max_state (result, i);
261 }
152 } 262 }
153 /* This should not happen */ 263 /* This should not happen */
154 else if (verbose) { 264 else if (verbose) {
@@ -172,65 +282,83 @@ main (int argc, char **argv)
172 result = max_state (result, STATE_WARNING); 282 result = max_state (result, STATE_WARNING);
173 } 283 }
174 284
175 if (options == ALL)
176 procs = found;
177
178 if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ 285 if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */
179 printf ("Unable to read output\n"); 286 printf ("Unable to read output\n");
180
181 return result; 287 return result;
182 } 288 }
183 289
184 if (verbose && (options & STAT)) 290 if ( result == STATE_UNKNOWN )
185 printf ("%s ", statopts); 291 result = STATE_OK;
186 if (verbose && (options & PROG)) 292
187 printf ("%s ", prog); 293 /* Needed if procs found, but none match filter */
188 if (verbose && (options & PPID)) 294 if ( metric == METRIC_PROCS ) {
189 printf ("%d ", ppid); 295 result = max_state (result, check_thresholds (procs) );
190 if (verbose && (options & USER)) 296 }
191 printf ("%d ", uid);
192 297
298 if ( result == STATE_OK ) {
299 printf ("%s OK: %d process%s",
300 metric_name, procs, ( procs != 1 ? "es" : "") );
301 } else if (result == STATE_WARNING) {
302 if ( metric == METRIC_PROCS ) {
303 printf ("PROCS WARNING: %d process%s", procs,
304 ( procs != 1 ? "es" : ""));
305 } else {
306 printf ("%s WARNING: %d warn out of %d process%s",
307 metric_name, warn, procs,
308 ( procs != 1 ? "es" : ""));
309 }
310 } else if (result == STATE_CRITICAL) {
311 if (metric == METRIC_PROCS) {
312 printf ("PROCS CRITICAL: %d process%s", procs,
313 ( procs != 1 ? "es" : ""));
314 } else {
315 printf ("%s CRITICAL: %d crit, %d warn out of %d process%s",
316 metric_name, crit, warn, procs,
317 ( procs != 1 ? "es" : ""));
318 }
319 }
320
321 if (fmt != "") {
322 printf (" with %s", fmt);
323 }
324
325 if ( verbose >= 1 && fails != "" )
326 printf (" [%s]", fails);
327
328 printf ("\n");
329 return result;
330}
331
332/* Check thresholds against value */
333int
334check_thresholds (int value)
335{
193 if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) { 336 if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) {
194 if (result == STATE_UNKNOWN) 337 return OK;
195 result = STATE_OK;
196 printf (fmt, "OK", procs);
197 return result;
198 } 338 }
199 else if (cmax >= 0 && cmin >= 0 && cmax < cmin) { 339 else if (cmax >= 0 && cmin >= 0 && cmax < cmin) {
200 if (procs > cmax && procs < cmin) { 340 if (value > cmax && value < cmin)
201 printf (fmt, "CRITICAL", procs);
202 return STATE_CRITICAL; 341 return STATE_CRITICAL;
203 }
204 } 342 }
205 else if (cmax >= 0 && procs > cmax) { 343 else if (cmax >= 0 && value > cmax) {
206 printf (fmt, "CRITICAL", procs);
207 return STATE_CRITICAL; 344 return STATE_CRITICAL;
208 } 345 }
209 else if (cmin >= 0 && procs < cmin) { 346 else if (cmin >= 0 && value < cmin) {
210 printf (fmt, "CRITICAL", procs);
211 return STATE_CRITICAL; 347 return STATE_CRITICAL;
212 } 348 }
213 349
214 if (wmax >= 0 && wmin >= 0 && wmax < wmin) { 350 if (wmax >= 0 && wmin >= 0 && wmax < wmin) {
215 if (procs > wmax && procs < wmin) { 351 if (value > wmax && value < wmin) {
216 printf (fmt, "CRITICAL", procs); 352 return STATE_WARNING;
217 return STATE_CRITICAL;
218 } 353 }
219 } 354 }
220 else if (wmax >= 0 && procs > wmax) { 355 else if (wmax >= 0 && value > wmax) {
221 printf (fmt, "WARNING", procs); 356 return STATE_WARNING;
222 return max_state (result, STATE_WARNING);
223 } 357 }
224 else if (wmin >= 0 && procs < wmin) { 358 else if (wmin >= 0 && value < wmin) {
225 printf (fmt, "WARNING", procs); 359 return STATE_WARNING;
226 return max_state (result, STATE_WARNING);
227 }
228
229 printf (fmt, "OK", procs);
230 if ( result == STATE_UNKNOWN ) {
231 result = STATE_OK;
232 } 360 }
233 return result; 361 return STATE_OK;
234} 362}
235 363
236/* process command-line arguments */ 364/* process command-line arguments */
@@ -244,10 +372,14 @@ process_arguments (int argc, char **argv)
244 static struct option long_options[] = { 372 static struct option long_options[] = {
245 {"warning", required_argument, 0, 'w'}, 373 {"warning", required_argument, 0, 'w'},
246 {"critical", required_argument, 0, 'c'}, 374 {"critical", required_argument, 0, 'c'},
375 {"metric", required_argument, 0, 'm'},
247 {"timeout", required_argument, 0, 't'}, 376 {"timeout", required_argument, 0, 't'},
248 {"status", required_argument, 0, 's'}, 377 {"status", required_argument, 0, 's'},
249 {"ppid", required_argument, 0, 'p'}, 378 {"ppid", required_argument, 0, 'p'},
250 {"command", required_argument, 0, 'C'}, 379 {"command", required_argument, 0, 'C'},
380 {"vsz", required_argument, 0, 'z'},
381 {"rss", required_argument, 0, 'r'},
382 {"pcpu", required_argument, 0, 'P'},
251 {"argument-array", required_argument, 0, 'a'}, 383 {"argument-array", required_argument, 0, 'a'},
252 {"help", no_argument, 0, 'h'}, 384 {"help", no_argument, 0, 'h'},
253 {"version", no_argument, 0, 'V'}, 385 {"version", no_argument, 0, 'V'},
@@ -260,7 +392,8 @@ process_arguments (int argc, char **argv)
260 strcpy (argv[c], "-t"); 392 strcpy (argv[c], "-t");
261 393
262 while (1) { 394 while (1) {
263 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:", long_options, &option_index); 395 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:",
396 long_options, &option_index);
264 397
265 if (c == -1 || c == EOF) 398 if (c == -1 || c == EOF)
266 break; 399 break;
@@ -368,17 +501,70 @@ process_arguments (int argc, char **argv)
368 break; 501 break;
369 case 'C': /* command */ 502 case 'C': /* command */
370 asprintf (&prog, "%s", optarg); 503 asprintf (&prog, "%s", optarg);
371 asprintf (&fmt, "%s%scommand name %s", fmt, (options ? ", " : ""), 504 asprintf (&fmt, "%s%scommand name '%s'", fmt, (options ? ", " : ""),
372 prog); 505 prog);
373 options |= PROG; 506 options |= PROG;
374 break; 507 break;
375 case 'a': /* args (full path name with args) */ 508 case 'a': /* args (full path name with args) */
376 asprintf (&args, "%s", optarg); 509 asprintf (&args, "%s", optarg);
377 asprintf (&fmt, "%s%sargs %s", fmt, (options ? ", " : ""), args); 510 asprintf (&fmt, "%s%sargs '%s'", fmt, (options ? ", " : ""), args);
378 options |= ARGS; 511 options |= ARGS;
379 break; 512 break;
513 case 'r': /* RSS */
514 if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) {
515 asprintf (&fmt, "%s%sRSS >= %d", fmt, (options ? ", " : ""), rss);
516 options |= RSS;
517 break;
518 }
519 printf ("%s: RSS must be an integer!\n\n",
520 progname);
521 print_usage ();
522 exit (STATE_UNKNOWN);
523 case 'z': /* VSZ */
524 if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) {
525 asprintf (&fmt, "%s%sVSZ >= %d", fmt, (options ? ", " : ""), vsz);
526 options |= VSZ;
527 break;
528 }
529 printf ("%s: VSZ must be an integer!\n\n",
530 progname);
531 print_usage ();
532 exit (STATE_UNKNOWN);
533 case 'P': /* PCPU */
534 /* TODO: -P 1.5.5 is accepted */
535 if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) {
536 asprintf (&fmt, "%s%sPCPU >= %.2f", fmt, (options ? ", " : ""), pcpu);
537 options |= PCPU;
538 break;
539 }
540 printf ("%s: PCPU must be a float!\n\n",
541 progname);
542 print_usage ();
543 exit (STATE_UNKNOWN);
544 case 'm':
545 asprintf (&metric_name, "%s", optarg);
546 if ( strcmp(optarg, "PROCS") == 0) {
547 metric = METRIC_PROCS;
548 break;
549 }
550 else if ( strcmp(optarg, "VSZ") == 0) {
551 metric = METRIC_VSZ;
552 break;
553 }
554 else if ( strcmp(optarg, "RSS") == 0 ) {
555 metric = METRIC_RSS;
556 break;
557 }
558 else if ( strcmp(optarg, "CPU") == 0 ) {
559 metric = METRIC_CPU;
560 break;
561 }
562 printf ("%s: metric must be one of PROCS, VSZ, RSS, CPU!\n\n",
563 progname);
564 print_usage ();
565 exit (STATE_UNKNOWN);
380 case 'v': /* command */ 566 case 'v': /* command */
381 verbose = TRUE; 567 verbose++;
382 break; 568 break;
383 } 569 }
384 } 570 }
@@ -402,7 +588,7 @@ int
402validate_arguments () 588validate_arguments ()
403{ 589{
404 590
405if (wmax >= 0 && wmin == -1) 591 if (wmax >= 0 && wmin == -1)
406 wmin = 0; 592 wmin = 0;
407 if (cmax >= 0 && cmin == -1) 593 if (cmax >= 0 && cmin == -1)
408 cmin = 0; 594 cmin = 0;
@@ -422,13 +608,8 @@ if (wmax >= 0 && wmin == -1)
422/* return ERROR; */ 608/* return ERROR; */
423/* } */ 609/* } */
424 610
425 if (options == 0) { 611 if (options == 0)
426 options = 1; 612 options = ALL;
427 asprintf (&fmt, "%%s - %%d processes running\n");
428 }
429 else {
430 asprintf (&fmt, "%%s - %%d processes running with %s\n", fmt);
431 }
432 613
433 return options; 614 return options;
434} 615}
@@ -442,37 +623,14 @@ print_help (void)
442 ("Copyright (c) %s %s <%s>\n\n%s\n", 623 ("Copyright (c) %s %s <%s>\n\n%s\n",
443 COPYRIGHT, AUTHOR, EMAIL, SUMMARY); 624 COPYRIGHT, AUTHOR, EMAIL, SUMMARY);
444 print_usage (); 625 print_usage ();
445 printf 626 printf ("\nOptions:\n" LONGOPTIONS "\nExamples:\n" EXAMPLES "\n");
446 ("\nRequired Arguments:\n" 627}
447 " -w, --warning=RANGE\n"
448 " generate warning state if process count is outside this range\n"
449 " -c, --critical=RANGE\n"
450 " generate critical state if process count is outside this range\n\n"
451 "Optional Filters:\n"
452 " -s, --state=STATUSFLAGS\n"
453 " Only scan for processes that have, in the output of `ps`, one or\n"
454 " more of the status flags you specify (for example R, Z, S, RS,\n"
455 " RSZDT, plus others based on the output of your 'ps' command).\n"
456 " -p, --ppid=PPID\n"
457 " Only scan for children of the parent process ID indicated.\n"
458 " -u, --user=USER\n"
459 " Only scan for proceses with user name or ID indicated.\n"
460 " -a, --argument-array=STRING\n"
461 " Only scan for ARGS that match up to the length of the given STRING\n"
462 " -C, --command=COMMAND\n"
463 " Only scan for exact matches to the named COMMAND.\n\n"
464 "RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n"
465 "specified 'max:min', a warning status will be generated if the\n"
466
467 "count is inside the specified range\n");}
468
469 628
470void 629void
471print_usage (void) 630print_usage (void)
472{ 631{
473 printf 632 printf ("Usage:\n" " %s %s\n"
474 ("Usage:\n" 633 " %s (-h | --help) for detailed help\n"
475 " check_procs -w <range> -c <range> [-s state] [-p ppid] [-u user]\n" 634 " %s (-V | --version) for version information\n",
476 " [-a argument-array] [-C command]\n" 635 progname, OPTIONS, progname, progname);
477 " check_procs --version\n" " check_procs --help\n");
478} 636}
diff --git a/plugins/check_vsz.c b/plugins/check_vsz.c
deleted file mode 100644
index 7a9acb2d..00000000
--- a/plugins/check_vsz.c
+++ /dev/null
@@ -1,250 +0,0 @@
1/******************************************************************************
2 *
3 * CHECK_VSZ.C
4 *
5 * Program: Process plugin for Nagios
6 * License: GPL
7 * Copyright (c) 1999,2000 Karl DeBisschop <kdebiss@alum.mit.edu>
8 *
9 * Last Modified: $Date$
10 *
11 * Description:
12 *
13 * This plugin will check for processes whose total image size exceeds
14 * the warning or critical thresholds given on the command line. With
15 * no command_name, everything that shows up on ps is evaluated.
16 * Otherwise, only jobs with the command_name given are examined.
17 * This program is particularly useful if you have to run a piece of
18 * commercial software that has a memory leak. With it you can shut
19 * down and restart the processes whenever the program threatens to
20 * take over your system.
21 *
22 * Modifications:
23 *
24 * 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu)
25 * change to getopt, use print_help
26 * 08-18-1999 Ethan Galstad (nagios@nagios.org)
27 * Changed code to use common include file
28 * Changed fclose() to pclose()
29 * 09-09-1999 Ethan Galstad (nagios@nagios.org)
30 * Changed popen()/pclose() to spopen()/spclose()
31 * 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu)
32 * set STATE_WARNING of stderr written or nonzero status returned
33 *
34 *****************************************************************************/
35
36const char *progname = "check_vsz";
37#define REVISION "$Revision$"
38#define COPYRIGHT "1999-2002"
39#define AUTHOR "Karl DeBisschop"
40#define EMAIL "karl@debisschop.net"
41#define SUMMARY "Check the image size of a running program.\n"
42
43#include "common.h"
44#include "popen.h"
45#include "utils.h"
46
47int process_arguments (int argc, char **argv);
48void print_help (const char *cmd);
49void print_usage (const char *cmd);
50
51int warn = -1;
52int crit = -1;
53char *proc = NULL;
54
55int
56main (int argc, char **argv)
57{
58 int len;
59 int result = STATE_OK;
60 int line = 0;
61 int proc_size = -1;
62 char input_buffer[MAX_INPUT_BUFFER];
63 char proc_name[MAX_INPUT_BUFFER];
64 char *message = "";
65
66 if (process_arguments (argc, argv) == ERROR) {
67 printf ("%s: failure parsing arguments\n", progname);
68 print_help (progname);
69 return STATE_UNKNOWN;
70 }
71
72 /* run the command */
73 child_process = spopen (VSZ_COMMAND);
74 if (child_process == NULL) {
75 printf ("Unable to open pipe: %s\n", VSZ_COMMAND);
76 return STATE_UNKNOWN;
77 }
78
79 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
80 if (child_stderr == NULL)
81 printf ("Could not open stderr for %s\n", VSZ_COMMAND);
82
83 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
84
85 line++;
86
87 /* skip the first line */
88 if (line == 1)
89 continue;
90
91 if (sscanf (input_buffer, VSZ_FORMAT, &proc_size, proc_name) == 2) {
92 if (proc == NULL) {
93 if (proc_size > warn) {
94 asprintf (&message, "%s %s(%d)", message, proc_name, proc_size);
95 result = max_state (result, STATE_WARNING);
96 }
97 if (proc_size > crit) {
98 result = STATE_CRITICAL;
99 }
100 }
101 else if (strstr (proc_name, proc)) {
102 asprintf (&message, "%s %d", message, proc_size);
103 if (proc_size > warn) {
104 result = max_state (result, STATE_WARNING);
105 }
106 if (proc_size > crit) {
107 result = STATE_CRITICAL;
108 }
109 }
110 }
111 }
112
113 /* If we get anything on STDERR, at least set warning */
114 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
115 result = max_state (result, STATE_WARNING);
116
117 (void) fclose (child_stderr);
118
119 /* close the pipe */
120 if (spclose (child_process))
121 result = max_state (result, STATE_WARNING);
122
123 if (result == STATE_OK)
124 printf ("ok (all VSZ<%d): %s\n", warn, message);
125 else if (result == STATE_UNKNOWN)
126 printf ("Unable to read output\n");
127 else if (result == STATE_WARNING)
128 printf ("WARNING (VSZ>%d):%s\n", warn, message);
129 else
130 printf ("CRITICAL (VSZ>%d):%s\n", crit, message);
131
132 return result;
133}
134
135
136
137
138int
139process_arguments (int argc, char **argv)
140{
141 int c;
142
143 int option_index = 0;
144 static struct option long_options[] = {
145 {"help", no_argument, 0, 'h'},
146 {"version", no_argument, 0, 'V'},
147 {"critical", required_argument, 0, 'c'},
148 {"warning", required_argument, 0, 'w'},
149 {"command", required_argument, 0, 'C'},
150 {0, 0, 0, 0}
151 };
152
153 if (argc < 2)
154 return ERROR;
155
156 while (1) {
157 c = getopt_long (argc, argv, "+hVc:w:C:", long_options, &option_index);
158
159 if (c == EOF)
160 break;
161
162 switch (c) {
163 case '?': /* help */
164 print_usage (progname);
165 exit (STATE_UNKNOWN);
166 case 'h': /* help */
167 print_help (progname);
168 exit (STATE_OK);
169 case 'V': /* version */
170 print_revision (progname, "$Revision$");
171 exit (STATE_OK);
172 case 'c': /* critical threshold */
173 if (!is_intnonneg (optarg)) {
174 printf ("%s: critical threshold must be an integer: %s\n",
175 progname, optarg);
176 print_usage (progname);
177 exit (STATE_UNKNOWN);
178 }
179 crit = atoi (optarg);
180 break;
181 case 'w': /* warning threshold */
182 if (!is_intnonneg (optarg)) {
183 printf ("%s: warning threshold must be an integer: %s\n",
184 progname, optarg);
185 print_usage (progname);
186 exit (STATE_UNKNOWN);
187 }
188 warn = atoi (optarg);
189 break;
190 case 'C': /* command name */
191 proc = optarg;
192 break;
193 }
194 }
195
196 c = optind;
197 if (warn == -1) {
198 if (!is_intnonneg (argv[c])) {
199 printf ("%s: critical threshold must be an integer: %s\n",
200 progname, argv[c]);
201 print_usage (progname);
202 exit (STATE_UNKNOWN);
203 }
204 warn = atoi (argv[c++]);
205 }
206
207 if (crit == -1) {
208 if (!is_intnonneg (argv[c])) {
209 printf ("%s: critical threshold must be an integer: %s\n",
210 progname, argv[c]);
211 print_usage (progname);
212 exit (STATE_UNKNOWN);
213 }
214 crit = atoi (argv[c++]);
215 }
216
217 if (proc == NULL)
218 proc = argv[c];
219
220 return c;
221}
222
223void
224print_usage (const char *cmd)
225{
226 printf ("Usage: %s -w <wsize> -c <csize> [-C command]\n"
227 " %s --help\n" " %s --version\n", cmd, cmd, cmd);
228}
229
230void
231print_help (const char *cmd)
232{
233 print_revision ("check_vsz", "$Revision$");
234 printf
235 ("Copyright (c) 2000 Karl DeBisschop <kdebiss@alum.mit.edu>\n\n"
236 "This plugin checks the image size of a running program and returns an\n"
237 "error if the number is above either of the thresholds given.\n\n");
238 print_usage (cmd);
239 printf
240 ("\nOptions:\n"
241 " -h, --help\n"
242 " Print detailed help\n"
243 " -V, --version\n"
244 " Print version numbers and license information\n"
245 " -w, --warning=INTEGER\n"
246 " Program image size necessary to cause a WARNING state\n"
247 " -c, --critical=INTEGER\n"
248 " Program image size necessary to cause a CRITICAL state\n"
249 " -C, --command=STRING\n" " Program to search for [optional]\n");
250}