diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/Makefile.am | 4 | ||||
-rw-r--r-- | plugins/check_nagios.c | 5 | ||||
-rw-r--r-- | plugins/check_procs.c | 362 | ||||
-rw-r--r-- | plugins/check_vsz.c | 250 |
4 files changed, 265 insertions, 356 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index a884b45..0692cd2 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am | |||
@@ -7,7 +7,7 @@ INCLUDES = -I.. -I$(top_srcdir)/lib @LDAPINCLUDE@ @PGINCLUDE@ @SSLINCLUDE@ | |||
7 | libexec_PROGRAMS = check_disk check_dummy check_http check_load \ | 7 | libexec_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 | ||
13 | EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ | 13 | EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ |
@@ -68,7 +68,6 @@ check_time_LDADD = $(NETLIBS) | |||
68 | check_udp_LDADD = $(NETLIBS) | 68 | check_udp_LDADD = $(NETLIBS) |
69 | check_ups_LDADD = $(NETLIBS) | 69 | check_ups_LDADD = $(NETLIBS) |
70 | check_users_LDADD = $(BASEOBJS) popen.o | 70 | check_users_LDADD = $(BASEOBJS) popen.o |
71 | check_vsz_LDADD = $(BASEOBJS) popen.o | ||
72 | check_by_ssh_LDADD = $(NETLIBS) popen.o | 71 | check_by_ssh_LDADD = $(NETLIBS) popen.o |
73 | negate_LDADD = $(BASEOBJS) popen.o | 72 | negate_LDADD = $(BASEOBJS) popen.o |
74 | urlize_LDADD = $(BASEOBJS) popen.o | 73 | urlize_LDADD = $(BASEOBJS) popen.o |
@@ -104,7 +103,6 @@ check_time_DEPENDENCIES = check_time.c $(NETOBJS) $(DEPLIBS) | |||
104 | check_udp_DEPENDENCIES = check_udp.c $(NETOBJS) $(DEPLIBS) | 103 | check_udp_DEPENDENCIES = check_udp.c $(NETOBJS) $(DEPLIBS) |
105 | check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS) | 104 | check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS) |
106 | check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS) | 105 | check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS) |
107 | check_vsz_DEPENDENCIES = check_vsz.c $(BASEOBJS) popen.o $(DEPLIBS) | ||
108 | check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) popen.o $(DEPLIBS) | 106 | check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) popen.o $(DEPLIBS) |
109 | negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS) | 107 | negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS) |
110 | urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS) | 108 | urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS) |
diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c index 083b502..64a828b 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 29f86be..2cf550c 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 "\ |
43 | CRITICAL states if the process count is outside the specified threshold\n\ | 43 | Checks all processes and generates WARNING or CRITICAL states if the specified\n\ |
44 | ranges. The process count can be filtered by process owner, parent process\n\ | 44 | metric is outside the required threshold ranges. The metric defaults to number\n\ |
45 | PID, current state (e.g., 'Z'), or may be the total number of running\n\ | 45 | of processes. Search filters can be applied to limit the processes to check.\n" |
46 | processes\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 "\ | ||
53 | Required 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\ | ||
58 | Optional 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\ | ||
67 | Optional 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\ | ||
87 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ | ||
88 | specified 'max:min', a warning status will be generated if the\n\ | ||
89 | count 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 **); | |||
55 | int validate_arguments (void); | 108 | int validate_arguments (void); |
56 | void print_usage (void); | 109 | void print_usage (void); |
57 | void print_help (void); | 110 | void print_help (void); |
111 | int check_thresholds (int); | ||
58 | 112 | ||
59 | int wmax = -1; | 113 | int wmax = -1; |
60 | int cmax = -1; | 114 | int 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 | |
72 | int verbose = FALSE; | 126 | #define RSS 128 |
127 | #define PCPU 256 | ||
128 | |||
129 | /* Different metrics */ | ||
130 | int metric = 0; | ||
131 | #define METRIC_PROCS 0 | ||
132 | #define METRIC_VSZ 1 | ||
133 | #define METRIC_RSS 2 | ||
134 | #define METRIC_CPU 3 | ||
135 | char *metric_name = ""; | ||
136 | |||
137 | int verbose = 0; | ||
73 | int uid; | 138 | int uid; |
74 | int ppid; | 139 | int ppid; |
140 | int vsz; | ||
141 | int rss; | ||
142 | float pcpu; | ||
75 | char *statopts = ""; | 143 | char *statopts = ""; |
76 | char *prog = ""; | 144 | char *prog = ""; |
77 | char *args = ""; | 145 | char *args = ""; |
78 | char *fmt = ""; | 146 | char *fmt = ""; |
147 | char *fails = ""; | ||
79 | char tmp[MAX_INPUT_BUFFER]; | 148 | char tmp[MAX_INPUT_BUFFER]; |
80 | const char *zombie = "Z"; | ||
81 | 149 | ||
82 | int | 150 | int |
83 | main (int argc, char **argv) | 151 | main (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 */ | ||
333 | int | ||
334 | check_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 | |||
402 | validate_arguments () | 588 | validate_arguments () |
403 | { | 589 | { |
404 | 590 | ||
405 | if (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 | ||
470 | void | 629 | void |
471 | print_usage (void) | 630 | print_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 7a9acb2..0000000 --- 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 | |||
36 | const 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 | |||
47 | int process_arguments (int argc, char **argv); | ||
48 | void print_help (const char *cmd); | ||
49 | void print_usage (const char *cmd); | ||
50 | |||
51 | int warn = -1; | ||
52 | int crit = -1; | ||
53 | char *proc = NULL; | ||
54 | |||
55 | int | ||
56 | main (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 | |||
138 | int | ||
139 | process_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 | |||
223 | void | ||
224 | print_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 | |||
230 | void | ||
231 | print_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 | } | ||