summaryrefslogtreecommitdiffstats
path: root/plugins/check_procs.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_procs.c')
-rw-r--r--plugins/check_procs.c843
1 files changed, 422 insertions, 421 deletions
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index 1d78ccee..69b424dc 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -1,41 +1,41 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_procs plugin 3 * Monitoring check_procs plugin
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 2000-2024 Monitoring Plugins Development Team 6 * Copyright (c) 2000-2024 Monitoring Plugins Development Team
7* 7 *
8* Description: 8 * Description:
9* 9 *
10* This file contains the check_procs plugin 10 * This file contains the check_procs plugin
11* 11 *
12* Checks all processes and generates WARNING or CRITICAL states if the 12 * Checks all processes and generates WARNING or CRITICAL states if the
13* specified metric is outside the required threshold ranges. The metric 13 * specified metric is outside the required threshold ranges. The metric
14* defaults to number of processes. Search filters can be applied to limit 14 * defaults to number of processes. Search filters can be applied to limit
15* the processes to check. 15 * the processes to check.
16* 16 *
17* The parent process, check_procs itself and any child process of 17 * The parent process, check_procs itself and any child process of
18* check_procs (ps) are excluded from any checks to prevent false positives. 18 * check_procs (ps) are excluded from any checks to prevent false positives.
19* 19 *
20* 20 *
21* This program is free software: you can redistribute it and/or modify 21 * This program is free software: you can redistribute it and/or modify
22* it under the terms of the GNU General Public License as published by 22 * it under the terms of the GNU General Public License as published by
23* the Free Software Foundation, either version 3 of the License, or 23 * the Free Software Foundation, either version 3 of the License, or
24* (at your option) any later version. 24 * (at your option) any later version.
25* 25 *
26* This program is distributed in the hope that it will be useful, 26 * This program is distributed in the hope that it will be useful,
27* but WITHOUT ANY WARRANTY; without even the implied warranty of 27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29* GNU General Public License for more details. 29 * GNU General Public License for more details.
30* 30 *
31* You should have received a copy of the GNU General Public License 31 * You should have received a copy of the GNU General Public License
32* along with this program. If not, see <http://www.gnu.org/licenses/>. 32 * along with this program. If not, see <http://www.gnu.org/licenses/>.
33* 33 *
34* 34 *
35*****************************************************************************/ 35 *****************************************************************************/
36 36
37const char *progname = "check_procs"; 37const char *progname = "check_procs";
38const char *program_name = "check_procs"; /* Required for coreutils libs */ 38const char *program_name = "check_procs"; /* Required for coreutils libs */
39const char *copyright = "2000-2024"; 39const char *copyright = "2000-2024";
40const char *email = "devel@monitoring-plugins.org"; 40const char *email = "devel@monitoring-plugins.org";
41 41
@@ -48,35 +48,36 @@ const char *email = "devel@monitoring-plugins.org";
48#include <errno.h> 48#include <errno.h>
49 49
50#ifdef HAVE_SYS_STAT_H 50#ifdef HAVE_SYS_STAT_H
51#include <sys/stat.h> 51# include <sys/stat.h>
52#endif 52#endif
53 53
54static int process_arguments (int /*argc*/, char ** /*argv*/); 54static int process_arguments(int /*argc*/, char ** /*argv*/);
55static int validate_arguments (void); 55static int validate_arguments(void);
56static int convert_to_seconds (char * /*etime*/); 56static int convert_to_seconds(char * /*etime*/);
57static void print_help (void); 57static void print_help(void);
58void print_usage (void); 58void print_usage(void);
59 59
60static char *warning_range = NULL; 60static char *warning_range = NULL;
61static char *critical_range = NULL; 61static char *critical_range = NULL;
62static thresholds *procs_thresholds = NULL; 62static thresholds *procs_thresholds = NULL;
63 63
64static int options = 0; /* bitmask of filter criteria to test against */ 64static int options = 0; /* bitmask of filter criteria to test against */
65#define ALL 1 65#define ALL 1
66#define STAT 2 66#define STAT 2
67#define PPID 4 67#define PPID 4
68#define USER 8 68#define USER 8
69#define PROG 16 69#define PROG 16
70#define ARGS 32 70#define ARGS 32
71#define VSZ 64 71#define VSZ 64
72#define RSS 128 72#define RSS 128
73#define PCPU 256 73#define PCPU 256
74#define ELAPSED 512 74#define ELAPSED 512
75#define EREG_ARGS 1024 75#define EREG_ARGS 1024
76#define EXCLUDE_PROGS 2048 76#define EXCLUDE_PROGS 2048
77 77
78#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads: 78#define KTHREAD_PARENT \
79 ppid of procs are compared to pid of this proc*/ 79 "kthreadd" /* the parent process of kernel threads: \
80 ppid of procs are compared to pid of this proc*/
80 81
81/* Different metrics */ 82/* Different metrics */
82char *metric_name; 83char *metric_name;
@@ -109,8 +110,7 @@ static char tmp[MAX_INPUT_BUFFER];
109static int kthread_filter = 0; 110static int kthread_filter = 0;
110static int usepid = 0; /* whether to test for pid or /proc/pid/exe */ 111static int usepid = 0; /* whether to test for pid or /proc/pid/exe */
111 112
112static int 113static int stat_exe(const pid_t pid, struct stat *buf) {
113stat_exe (const pid_t pid, struct stat *buf) {
114 char *path; 114 char *path;
115 int ret; 115 int ret;
116 xasprintf(&path, "/proc/%d/exe", pid); 116 xasprintf(&path, "/proc/%d/exe", pid);
@@ -119,10 +119,7 @@ stat_exe (const pid_t pid, struct stat *buf) {
119 return ret; 119 return ret;
120} 120}
121 121
122 122int main(int argc, char **argv) {
123int
124main (int argc, char **argv)
125{
126 char *input_buffer; 123 char *input_buffer;
127 char *input_line; 124 char *input_line;
128 char *procprog; 125 char *procprog;
@@ -141,16 +138,16 @@ main (int argc, char **argv)
141 int procseconds = 0; 138 int procseconds = 0;
142 float procpcpu = 0; 139 float procpcpu = 0;
143 char procstat[8]; 140 char procstat[8];
144 char procetime[MAX_INPUT_BUFFER] = { '\0' }; 141 char procetime[MAX_INPUT_BUFFER] = {'\0'};
145 char *procargs; 142 char *procargs;
146 143
147 const char *zombie = "Z"; 144 const char *zombie = "Z";
148 145
149 int resultsum = 0; /* bitmask of the filter criteria met by a process */ 146 int resultsum = 0; /* bitmask of the filter criteria met by a process */
150 int found = 0; /* counter for number of lines returned in `ps` output */ 147 int found = 0; /* counter for number of lines returned in `ps` output */
151 int procs = 0; /* counter for number of processes meeting filter criteria */ 148 int procs = 0; /* counter for number of processes meeting filter criteria */
152 int pos; /* number of spaces before 'args' in `ps` output */ 149 int pos; /* number of spaces before 'args' in `ps` output */
153 int cols; /* number of columns in ps output */ 150 int cols; /* number of columns in ps output */
154 int expected_cols = PS_COLS - 1; 151 int expected_cols = PS_COLS - 1;
155 int warn = 0; /* number of processes in warn state */ 152 int warn = 0; /* number of processes in warn state */
156 int crit = 0; /* number of processes in crit state */ 153 int crit = 0; /* number of processes in crit state */
@@ -159,22 +156,23 @@ main (int argc, char **argv)
159 int ret = 0; 156 int ret = 0;
160 output chld_out, chld_err; 157 output chld_out, chld_err;
161 158
162 setlocale (LC_ALL, ""); 159 setlocale(LC_ALL, "");
163 bindtextdomain (PACKAGE, LOCALEDIR); 160 bindtextdomain(PACKAGE, LOCALEDIR);
164 textdomain (PACKAGE); 161 textdomain(PACKAGE);
165 setlocale(LC_NUMERIC, "POSIX"); 162 setlocale(LC_NUMERIC, "POSIX");
166 163
167 input_buffer = malloc (MAX_INPUT_BUFFER); 164 input_buffer = malloc(MAX_INPUT_BUFFER);
168 procprog = malloc (MAX_INPUT_BUFFER); 165 procprog = malloc(MAX_INPUT_BUFFER);
169 166
170 xasprintf (&metric_name, "PROCS"); 167 xasprintf(&metric_name, "PROCS");
171 metric = METRIC_PROCS; 168 metric = METRIC_PROCS;
172 169
173 /* Parse extra opts if any */ 170 /* Parse extra opts if any */
174 argv=np_extra_opts (&argc, argv, progname); 171 argv = np_extra_opts(&argc, argv, progname);
175 172
176 if (process_arguments (argc, argv) == ERROR) 173 if (process_arguments(argc, argv) == ERROR) {
177 usage4 (_("Could not parse arguments")); 174 usage4(_("Could not parse arguments"));
175 }
178 176
179 /* find ourself */ 177 /* find ourself */
180 mypid = getpid(); 178 mypid = getpid();
@@ -189,44 +187,46 @@ main (int argc, char **argv)
189 } 187 }
190 188
191 /* Set signal handling and alarm timeout */ 189 /* Set signal handling and alarm timeout */
192 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { 190 if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
193 die (STATE_UNKNOWN, _("Cannot catch SIGALRM")); 191 die(STATE_UNKNOWN, _("Cannot catch SIGALRM"));
194 } 192 }
195 (void) alarm ((unsigned) timeout_interval); 193 (void)alarm((unsigned)timeout_interval);
196 194
197 if (verbose >= 2) 195 if (verbose >= 2) {
198 printf (_("CMD: %s\n"), PS_COMMAND); 196 printf(_("CMD: %s\n"), PS_COMMAND);
197 }
199 198
200 if (input_filename == NULL) { 199 if (input_filename == NULL) {
201 result = cmd_run( PS_COMMAND, &chld_out, &chld_err, 0); 200 result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0);
202 if (chld_err.lines > 0) { 201 if (chld_err.lines > 0) {
203 printf ("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); 202 printf("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]);
204 exit(STATE_WARNING); 203 exit(STATE_WARNING);
205 } 204 }
206 } else { 205 } else {
207 result = cmd_file_read( input_filename, &chld_out, 0); 206 result = cmd_file_read(input_filename, &chld_out, 0);
208 } 207 }
209 208
210 /* flush first line: j starts at 1 */ 209 /* flush first line: j starts at 1 */
211 for (size_t j = 1; j < chld_out.lines; j++) { 210 for (size_t j = 1; j < chld_out.lines; j++) {
212 input_line = chld_out.line[j]; 211 input_line = chld_out.line[j];
213 212
214 if (verbose >= 3) 213 if (verbose >= 3) {
215 printf ("%s", input_line); 214 printf("%s", input_line);
215 }
216 216
217 strcpy (procprog, ""); 217 strcpy(procprog, "");
218 xasprintf (&procargs, "%s", ""); 218 xasprintf(&procargs, "%s", "");
219 219
220 cols = sscanf (input_line, PS_FORMAT, PS_VARLIST); 220 cols = sscanf(input_line, PS_FORMAT, PS_VARLIST);
221 221
222 /* Zombie processes do not give a procprog command */ 222 /* Zombie processes do not give a procprog command */
223 if ( cols < expected_cols && strstr(procstat, zombie) ) { 223 if (cols < expected_cols && strstr(procstat, zombie)) {
224 cols = expected_cols; 224 cols = expected_cols;
225 } 225 }
226 if ( cols >= expected_cols ) { 226 if (cols >= expected_cols) {
227 resultsum = 0; 227 resultsum = 0;
228 xasprintf (&procargs, "%s", input_line + pos); 228 xasprintf(&procargs, "%s", input_line + pos);
229 strip (procargs); 229 strip(procargs);
230 230
231 /* Some ps return full pathname for command. This removes path */ 231 /* Some ps return full pathname for command. This removes path */
232 strcpy(procprog, base_name(procprog)); 232 strcpy(procprog, base_name(procprog));
@@ -234,52 +234,53 @@ main (int argc, char **argv)
234 /* we need to convert the elapsed time to seconds */ 234 /* we need to convert the elapsed time to seconds */
235 procseconds = convert_to_seconds(procetime); 235 procseconds = convert_to_seconds(procetime);
236 236
237 if (verbose >= 3) 237 if (verbose >= 3) {
238 printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", 238 printf("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procs, procuid, procvsz,
239 procs, procuid, procvsz, procrss, 239 procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs);
240 procpid, procppid, procpcpu, procstat, 240 }
241 procetime, procprog, procargs);
242 241
243 /* Ignore self */ 242 /* Ignore self */
244 if ((usepid && mypid == procpid) || 243 if ((usepid && mypid == procpid) ||
245 ( ((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || 244 (((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) ||
246 (ret == -1 && errno == ENOENT)) 245 (ret == -1 && errno == ENOENT))) {
247 ) { 246 if (verbose >= 3) {
248 if (verbose >= 3) 247 printf("not considering - is myself or gone\n");
249 printf("not considering - is myself or gone\n"); 248 }
250 continue; 249 continue;
251 } 250 }
252 /* Ignore parent*/ 251 /* Ignore parent*/
253 else if (myppid == procpid) { 252 else if (myppid == procpid) {
254 if (verbose >= 3) 253 if (verbose >= 3) {
255 printf("not considering - is parent\n"); 254 printf("not considering - is parent\n");
255 }
256 continue; 256 continue;
257 } 257 }
258 258
259 /* Ignore our own children */ 259 /* Ignore our own children */
260 if (procppid == mypid) { 260 if (procppid == mypid) {
261 if (verbose >= 3) 261 if (verbose >= 3) {
262 printf("not considering - is our child\n"); 262 printf("not considering - is our child\n");
263 }
263 continue; 264 continue;
264 } 265 }
265 266
266 /* Ignore excluded processes by name */ 267 /* Ignore excluded processes by name */
267 if(options & EXCLUDE_PROGS) { 268 if (options & EXCLUDE_PROGS) {
268 int found = 0; 269 int found = 0;
269 int i = 0; 270 int i = 0;
270 271
271 for(i=0; i < (exclude_progs_counter); i++) { 272 for (i = 0; i < (exclude_progs_counter); i++) {
272 if(!strcmp(procprog, exclude_progs_arr[i])) { 273 if (!strcmp(procprog, exclude_progs_arr[i])) {
273 found = 1; 274 found = 1;
274 } 275 }
275 } 276 }
276 if(found == 0) { 277 if (found == 0) {
277 resultsum |= EXCLUDE_PROGS; 278 resultsum |= EXCLUDE_PROGS;
278 } else 279 } else {
279 { 280 if (verbose >= 3) {
280 if(verbose >= 3) 281 printf("excluding - by ignorelist\n");
281 printf("excluding - by ignorelist\n"); 282 }
282 } 283 }
283 } 284 }
284 285
285 /* filter kernel threads (children of KTHREAD_PARENT)*/ 286 /* filter kernel threads (children of KTHREAD_PARENT)*/
@@ -287,69 +288,81 @@ main (int argc, char **argv)
287 sorry for not doing that, but I've no other OSes to test :-( */ 288 sorry for not doing that, but I've no other OSes to test :-( */
288 if (kthread_filter == 1) { 289 if (kthread_filter == 1) {
289 /* get pid KTHREAD_PARENT */ 290 /* get pid KTHREAD_PARENT */
290 if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) ) 291 if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) {
291 kthread_ppid = procpid; 292 kthread_ppid = procpid;
293 }
292 294
293 if (kthread_ppid == procppid) { 295 if (kthread_ppid == procppid) {
294 if (verbose >= 2) 296 if (verbose >= 2) {
295 printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); 297 printf("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs);
298 }
296 continue; 299 continue;
297 } 300 }
298 } 301 }
299 302
300 if ((options & STAT) && (strstr (procstat, statopts))) 303 if ((options & STAT) && (strstr(procstat, statopts))) {
301 resultsum |= STAT; 304 resultsum |= STAT;
302 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) 305 }
306 if ((options & ARGS) && procargs && (strstr(procargs, args) != NULL)) {
303 resultsum |= ARGS; 307 resultsum |= ARGS;
304 if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t) 0, NULL, 0) == 0)) 308 }
309 if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t)0, NULL, 0) == 0)) {
305 resultsum |= EREG_ARGS; 310 resultsum |= EREG_ARGS;
306 if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0)) 311 }
312 if ((options & PROG) && procprog && (strcmp(prog, procprog) == 0)) {
307 resultsum |= PROG; 313 resultsum |= PROG;
308 if ((options & PPID) && (procppid == ppid)) 314 }
315 if ((options & PPID) && (procppid == ppid)) {
309 resultsum |= PPID; 316 resultsum |= PPID;
310 if ((options & USER) && (procuid == uid)) 317 }
318 if ((options & USER) && (procuid == uid)) {
311 resultsum |= USER; 319 resultsum |= USER;
312 if ((options & VSZ) && (procvsz >= vsz)) 320 }
321 if ((options & VSZ) && (procvsz >= vsz)) {
313 resultsum |= VSZ; 322 resultsum |= VSZ;
314 if ((options & RSS) && (procrss >= rss)) 323 }
324 if ((options & RSS) && (procrss >= rss)) {
315 resultsum |= RSS; 325 resultsum |= RSS;
316 if ((options & PCPU) && (procpcpu >= pcpu)) 326 }
327 if ((options & PCPU) && (procpcpu >= pcpu)) {
317 resultsum |= PCPU; 328 resultsum |= PCPU;
329 }
318 330
319 found++; 331 found++;
320 332
321 /* Next line if filters not matched */ 333 /* Next line if filters not matched */
322 if (!(options == resultsum || options == ALL)) 334 if (!(options == resultsum || options == ALL)) {
323 continue; 335 continue;
336 }
324 337
325 procs++; 338 procs++;
326 if (verbose >= 2) { 339 if (verbose >= 2) {
327 printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", 340 printf("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procuid, procvsz,
328 procuid, procvsz, procrss, 341 procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs);
329 procpid, procppid, procpcpu, procstat,
330 procetime, procprog, procargs);
331 } 342 }
332 343
333 if (metric == METRIC_VSZ) 344 if (metric == METRIC_VSZ) {
334 i = get_status ((double)procvsz, procs_thresholds); 345 i = get_status((double)procvsz, procs_thresholds);
335 else if (metric == METRIC_RSS) 346 } else if (metric == METRIC_RSS) {
336 i = get_status ((double)procrss, procs_thresholds); 347 i = get_status((double)procrss, procs_thresholds);
348 }
337 /* TODO? float thresholds for --metric=CPU */ 349 /* TODO? float thresholds for --metric=CPU */
338 else if (metric == METRIC_CPU) 350 else if (metric == METRIC_CPU) {
339 i = get_status (procpcpu, procs_thresholds); 351 i = get_status(procpcpu, procs_thresholds);
340 else if (metric == METRIC_ELAPSED) 352 } else if (metric == METRIC_ELAPSED) {
341 i = get_status ((double)procseconds, procs_thresholds); 353 i = get_status((double)procseconds, procs_thresholds);
354 }
342 355
343 if (metric != METRIC_PROCS) { 356 if (metric != METRIC_PROCS) {
344 if (i == STATE_WARNING) { 357 if (i == STATE_WARNING) {
345 warn++; 358 warn++;
346 xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); 359 xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog);
347 result = max_state (result, i); 360 result = max_state(result, i);
348 } 361 }
349 if (i == STATE_CRITICAL) { 362 if (i == STATE_CRITICAL) {
350 crit++; 363 crit++;
351 xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); 364 xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog);
352 result = max_state (result, i); 365 result = max_state(result, i);
353 } 366 }
354 } 367 }
355 } 368 }
@@ -359,58 +372,55 @@ main (int argc, char **argv)
359 } 372 }
360 } 373 }
361 374
362 if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ 375 if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */
363 printf (_("Unable to read output\n")); 376 printf(_("Unable to read output\n"));
364 return STATE_UNKNOWN; 377 return STATE_UNKNOWN;
365 } 378 }
366 379
367 if ( result == STATE_UNKNOWN ) 380 if (result == STATE_UNKNOWN) {
368 result = STATE_OK; 381 result = STATE_OK;
382 }
369 383
370 /* Needed if procs found, but none match filter */ 384 /* Needed if procs found, but none match filter */
371 if ( metric == METRIC_PROCS ) { 385 if (metric == METRIC_PROCS) {
372 result = max_state (result, get_status ((double)procs, procs_thresholds) ); 386 result = max_state(result, get_status((double)procs, procs_thresholds));
373 } 387 }
374 388
375 if ( result == STATE_OK ) { 389 if (result == STATE_OK) {
376 printf ("%s %s: ", metric_name, _("OK")); 390 printf("%s %s: ", metric_name, _("OK"));
377 } else if (result == STATE_WARNING) { 391 } else if (result == STATE_WARNING) {
378 printf ("%s %s: ", metric_name, _("WARNING")); 392 printf("%s %s: ", metric_name, _("WARNING"));
379 if ( metric != METRIC_PROCS ) { 393 if (metric != METRIC_PROCS) {
380 printf (_("%d warn out of "), warn); 394 printf(_("%d warn out of "), warn);
381 } 395 }
382 } else if (result == STATE_CRITICAL) { 396 } else if (result == STATE_CRITICAL) {
383 printf ("%s %s: ", metric_name, _("CRITICAL")); 397 printf("%s %s: ", metric_name, _("CRITICAL"));
384 if (metric != METRIC_PROCS) { 398 if (metric != METRIC_PROCS) {
385 printf (_("%d crit, %d warn out of "), crit, warn); 399 printf(_("%d crit, %d warn out of "), crit, warn);
386 } 400 }
387 } 401 }
388 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); 402 printf(ngettext("%d process", "%d processes", (unsigned long)procs), procs);
389 403
390 if (strcmp(fmt,"") != 0) { 404 if (strcmp(fmt, "") != 0) {
391 printf (_(" with %s"), fmt); 405 printf(_(" with %s"), fmt);
392 } 406 }
393 407
394 if ( verbose >= 1 && strcmp(fails,"") ) 408 if (verbose >= 1 && strcmp(fails, "")) {
395 printf (" [%s]", fails); 409 printf(" [%s]", fails);
410 }
396 411
397 if (metric == METRIC_PROCS) 412 if (metric == METRIC_PROCS) {
398 printf (" | procs=%d;%s;%s;0;", procs, 413 printf(" | procs=%d;%s;%s;0;", procs, warning_range ? warning_range : "", critical_range ? critical_range : "");
399 warning_range ? warning_range : "", 414 } else {
400 critical_range ? critical_range : ""); 415 printf(" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit);
401 else 416 }
402 printf (" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit);
403 417
404 printf ("\n"); 418 printf("\n");
405 return result; 419 return result;
406} 420}
407 421
408
409
410/* process command-line arguments */ 422/* process command-line arguments */
411int 423int process_arguments(int argc, char **argv) {
412process_arguments (int argc, char **argv)
413{
414 int c = 1; 424 int c = 1;
415 char *user; 425 char *user;
416 struct passwd *pw; 426 struct passwd *pw;
@@ -419,260 +429,262 @@ process_arguments (int argc, char **argv)
419 int cflags = REG_NOSUB | REG_EXTENDED; 429 int cflags = REG_NOSUB | REG_EXTENDED;
420 char errbuf[MAX_INPUT_BUFFER]; 430 char errbuf[MAX_INPUT_BUFFER];
421 char *temp_string; 431 char *temp_string;
422 int i=0; 432 int i = 0;
423 static struct option longopts[] = { 433 static struct option longopts[] = {{"warning", required_argument, 0, 'w'},
424 {"warning", required_argument, 0, 'w'}, 434 {"critical", required_argument, 0, 'c'},
425 {"critical", required_argument, 0, 'c'}, 435 {"metric", required_argument, 0, 'm'},
426 {"metric", required_argument, 0, 'm'}, 436 {"timeout", required_argument, 0, 't'},
427 {"timeout", required_argument, 0, 't'}, 437 {"status", required_argument, 0, 's'},
428 {"status", required_argument, 0, 's'}, 438 {"ppid", required_argument, 0, 'p'},
429 {"ppid", required_argument, 0, 'p'}, 439 {"user", required_argument, 0, 'u'},
430 {"user", required_argument, 0, 'u'}, 440 {"command", required_argument, 0, 'C'},
431 {"command", required_argument, 0, 'C'}, 441 {"vsz", required_argument, 0, 'z'},
432 {"vsz", required_argument, 0, 'z'}, 442 {"rss", required_argument, 0, 'r'},
433 {"rss", required_argument, 0, 'r'}, 443 {"pcpu", required_argument, 0, 'P'},
434 {"pcpu", required_argument, 0, 'P'}, 444 {"elapsed", required_argument, 0, 'e'},
435 {"elapsed", required_argument, 0, 'e'}, 445 {"argument-array", required_argument, 0, 'a'},
436 {"argument-array", required_argument, 0, 'a'}, 446 {"help", no_argument, 0, 'h'},
437 {"help", no_argument, 0, 'h'}, 447 {"version", no_argument, 0, 'V'},
438 {"version", no_argument, 0, 'V'}, 448 {"verbose", no_argument, 0, 'v'},
439 {"verbose", no_argument, 0, 'v'}, 449 {"ereg-argument-array", required_argument, 0, CHAR_MAX + 1},
440 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, 450 {"input-file", required_argument, 0, CHAR_MAX + 2},
441 {"input-file", required_argument, 0, CHAR_MAX+2}, 451 {"no-kthreads", required_argument, 0, 'k'},
442 {"no-kthreads", required_argument, 0, 'k'}, 452 {"traditional-filter", no_argument, 0, 'T'},
443 {"traditional-filter", no_argument, 0, 'T'}, 453 {"exclude-process", required_argument, 0, 'X'},
444 {"exclude-process", required_argument, 0, 'X'}, 454 {0, 0, 0, 0}};
445 {0, 0, 0, 0} 455
446 }; 456 for (c = 1; c < argc; c++) {
447 457 if (strcmp("-to", argv[c]) == 0) {
448 for (c = 1; c < argc; c++) 458 strcpy(argv[c], "-t");
449 if (strcmp ("-to", argv[c]) == 0) 459 }
450 strcpy (argv[c], "-t"); 460 }
451 461
452 while (1) { 462 while (1) {
453 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", 463 c = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option);
454 longopts, &option);
455 464
456 if (c == -1 || c == EOF) 465 if (c == -1 || c == EOF) {
457 break; 466 break;
467 }
458 468
459 switch (c) { 469 switch (c) {
460 case '?': /* help */ 470 case '?': /* help */
461 usage5 (); 471 usage5();
462 case 'h': /* help */ 472 case 'h': /* help */
463 print_help (); 473 print_help();
464 exit (STATE_UNKNOWN); 474 exit(STATE_UNKNOWN);
465 case 'V': /* version */ 475 case 'V': /* version */
466 print_revision (progname, NP_VERSION); 476 print_revision(progname, NP_VERSION);
467 exit (STATE_UNKNOWN); 477 exit(STATE_UNKNOWN);
468 case 't': /* timeout period */ 478 case 't': /* timeout period */
469 if (!is_integer (optarg)) 479 if (!is_integer(optarg)) {
470 usage2 (_("Timeout interval must be a positive integer"), optarg); 480 usage2(_("Timeout interval must be a positive integer"), optarg);
471 else 481 } else {
472 timeout_interval = atoi (optarg); 482 timeout_interval = atoi(optarg);
483 }
473 break; 484 break;
474 case 'c': /* critical threshold */ 485 case 'c': /* critical threshold */
475 critical_range = optarg; 486 critical_range = optarg;
476 break; 487 break;
477 case 'w': /* warning threshold */ 488 case 'w': /* warning threshold */
478 warning_range = optarg; 489 warning_range = optarg;
479 break; 490 break;
480 case 'p': /* process id */ 491 case 'p': /* process id */
481 if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) { 492 if (sscanf(optarg, "%d%[^0-9]", &ppid, tmp) == 1) {
482 xasprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid); 493 xasprintf(&fmt, "%s%sPPID = %d", (fmt ? fmt : ""), (options ? ", " : ""), ppid);
483 options |= PPID; 494 options |= PPID;
484 break; 495 break;
485 } 496 }
486 usage4 (_("Parent Process ID must be an integer!")); 497 usage4(_("Parent Process ID must be an integer!"));
487 case 's': /* status */ 498 case 's': /* status */
488 if (statopts) 499 if (statopts) {
489 break; 500 break;
490 else 501 } else {
491 statopts = optarg; 502 statopts = optarg;
492 xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); 503 }
504 xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
493 options |= STAT; 505 options |= STAT;
494 break; 506 break;
495 case 'u': /* user or user id */ 507 case 'u': /* user or user id */
496 if (is_integer (optarg)) { 508 if (is_integer(optarg)) {
497 uid = atoi (optarg); 509 uid = atoi(optarg);
498 pw = getpwuid ((uid_t) uid); 510 pw = getpwuid((uid_t)uid);
499 /* check to be sure user exists */ 511 /* check to be sure user exists */
500 if (pw == NULL) 512 if (pw == NULL) {
501 usage2 (_("UID was not found"), optarg); 513 usage2(_("UID was not found"), optarg);
502 } 514 }
503 else { 515 } else {
504 pw = getpwnam (optarg); 516 pw = getpwnam(optarg);
505 /* check to be sure user exists */ 517 /* check to be sure user exists */
506 if (pw == NULL) 518 if (pw == NULL) {
507 usage2 (_("User name was not found"), optarg); 519 usage2(_("User name was not found"), optarg);
520 }
508 /* then get uid */ 521 /* then get uid */
509 uid = pw->pw_uid; 522 uid = pw->pw_uid;
510 } 523 }
511 user = pw->pw_name; 524 user = pw->pw_name;
512 xasprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), 525 xasprintf(&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), uid, user);
513 uid, user);
514 options |= USER; 526 options |= USER;
515 break; 527 break;
516 case 'C': /* command */ 528 case 'C': /* command */
517 /* TODO: allow this to be passed in with --metric */ 529 /* TODO: allow this to be passed in with --metric */
518 if (prog) 530 if (prog) {
519 break; 531 break;
520 else 532 } else {
521 prog = optarg; 533 prog = optarg;
522 xasprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), 534 }
523 prog); 535 xasprintf(&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), prog);
524 options |= PROG; 536 options |= PROG;
525 break; 537 break;
526 case 'X': 538 case 'X':
527 if(exclude_progs) 539 if (exclude_progs) {
528 break; 540 break;
529 else 541 } else {
530 exclude_progs = optarg; 542 exclude_progs = optarg;
531 xasprintf (&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), 543 }
532 exclude_progs); 544 xasprintf(&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), exclude_progs);
533 char *p = strtok(exclude_progs, ","); 545 char *p = strtok(exclude_progs, ",");
534 546
535 while(p){ 547 while (p) {
536 exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char*) * ++exclude_progs_counter); 548 exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char *) * ++exclude_progs_counter);
537 exclude_progs_arr[exclude_progs_counter-1] = p; 549 exclude_progs_arr[exclude_progs_counter - 1] = p;
538 p = strtok(NULL, ","); 550 p = strtok(NULL, ",");
539 } 551 }
540 552
541 options |= EXCLUDE_PROGS; 553 options |= EXCLUDE_PROGS;
542 break; 554 break;
543 case 'a': /* args (full path name with args) */ 555 case 'a': /* args (full path name with args) */
544 /* TODO: allow this to be passed in with --metric */ 556 /* TODO: allow this to be passed in with --metric */
545 if (args) 557 if (args) {
546 break; 558 break;
547 else 559 } else {
548 args = optarg; 560 args = optarg;
549 xasprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); 561 }
562 xasprintf(&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args);
550 options |= ARGS; 563 options |= ARGS;
551 break; 564 break;
552 case CHAR_MAX+1: 565 case CHAR_MAX + 1:
553 err = regcomp(&re_args, optarg, cflags); 566 err = regcomp(&re_args, optarg, cflags);
554 if (err != 0) { 567 if (err != 0) {
555 regerror (err, &re_args, errbuf, MAX_INPUT_BUFFER); 568 regerror(err, &re_args, errbuf, MAX_INPUT_BUFFER);
556 die (STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); 569 die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf);
557 } 570 }
558 /* Strip off any | within the regex optarg */ 571 /* Strip off any | within the regex optarg */
559 temp_string = strdup(optarg); 572 temp_string = strdup(optarg);
560 while(temp_string[i]!='\0'){ 573 while (temp_string[i] != '\0') {
561 if(temp_string[i]=='|') 574 if (temp_string[i] == '|') {
562 temp_string[i]=','; 575 temp_string[i] = ',';
576 }
563 i++; 577 i++;
564 } 578 }
565 xasprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); 579 xasprintf(&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string);
566 options |= EREG_ARGS; 580 options |= EREG_ARGS;
567 break; 581 break;
568 case 'r': /* RSS */ 582 case 'r': /* RSS */
569 if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) { 583 if (sscanf(optarg, "%d%[^0-9]", &rss, tmp) == 1) {
570 xasprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); 584 xasprintf(&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss);
571 options |= RSS; 585 options |= RSS;
572 break; 586 break;
573 } 587 }
574 usage4 (_("RSS must be an integer!")); 588 usage4(_("RSS must be an integer!"));
575 case 'z': /* VSZ */ 589 case 'z': /* VSZ */
576 if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) { 590 if (sscanf(optarg, "%d%[^0-9]", &vsz, tmp) == 1) {
577 xasprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz); 591 xasprintf(&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz);
578 options |= VSZ; 592 options |= VSZ;
579 break; 593 break;
580 } 594 }
581 usage4 (_("VSZ must be an integer!")); 595 usage4(_("VSZ must be an integer!"));
582 case 'P': /* PCPU */ 596 case 'P': /* PCPU */
583 /* TODO: -P 1.5.5 is accepted */ 597 /* TODO: -P 1.5.5 is accepted */
584 if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) { 598 if (sscanf(optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) {
585 xasprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu); 599 xasprintf(&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu);
586 options |= PCPU; 600 options |= PCPU;
587 break; 601 break;
588 } 602 }
589 usage4 (_("PCPU must be a float!")); 603 usage4(_("PCPU must be a float!"));
590 case 'm': 604 case 'm':
591 xasprintf (&metric_name, "%s", optarg); 605 xasprintf(&metric_name, "%s", optarg);
592 if ( strcmp(optarg, "PROCS") == 0) { 606 if (strcmp(optarg, "PROCS") == 0) {
593 metric = METRIC_PROCS; 607 metric = METRIC_PROCS;
594 break; 608 break;
595 } 609 } else if (strcmp(optarg, "VSZ") == 0) {
596 else if ( strcmp(optarg, "VSZ") == 0) {
597 metric = METRIC_VSZ; 610 metric = METRIC_VSZ;
598 break; 611 break;
599 } 612 } else if (strcmp(optarg, "RSS") == 0) {
600 else if ( strcmp(optarg, "RSS") == 0 ) {
601 metric = METRIC_RSS; 613 metric = METRIC_RSS;
602 break; 614 break;
603 } 615 } else if (strcmp(optarg, "CPU") == 0) {
604 else if ( strcmp(optarg, "CPU") == 0 ) {
605 metric = METRIC_CPU; 616 metric = METRIC_CPU;
606 break; 617 break;
607 } 618 } else if (strcmp(optarg, "ELAPSED") == 0) {
608 else if ( strcmp(optarg, "ELAPSED") == 0) {
609 metric = METRIC_ELAPSED; 619 metric = METRIC_ELAPSED;
610 break; 620 break;
611 } 621 }
612 622
613 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); 623 usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
614 case 'k': /* linux kernel thread filter */ 624 case 'k': /* linux kernel thread filter */
615 kthread_filter = 1; 625 kthread_filter = 1;
616 break; 626 break;
617 case 'v': /* command */ 627 case 'v': /* command */
618 verbose++; 628 verbose++;
619 break; 629 break;
620 case 'T': 630 case 'T':
621 usepid = 1; 631 usepid = 1;
622 break; 632 break;
623 case CHAR_MAX+2: 633 case CHAR_MAX + 2:
624 input_filename = optarg; 634 input_filename = optarg;
625 break; 635 break;
626 } 636 }
627 } 637 }
628 638
629 c = optind; 639 c = optind;
630 if ((! warning_range) && argv[c]) 640 if ((!warning_range) && argv[c]) {
631 warning_range = argv[c++]; 641 warning_range = argv[c++];
632 if ((! critical_range) && argv[c]) 642 }
643 if ((!critical_range) && argv[c]) {
633 critical_range = argv[c++]; 644 critical_range = argv[c++];
645 }
634 if (statopts == NULL && argv[c]) { 646 if (statopts == NULL && argv[c]) {
635 xasprintf (&statopts, "%s", argv[c++]); 647 xasprintf(&statopts, "%s", argv[c++]);
636 xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); 648 xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
637 options |= STAT; 649 options |= STAT;
638 } 650 }
639 651
640 /* this will abort in case of invalid ranges */ 652 /* this will abort in case of invalid ranges */
641 set_thresholds (&procs_thresholds, warning_range, critical_range); 653 set_thresholds(&procs_thresholds, warning_range, critical_range);
642 654
643 return validate_arguments (); 655 return validate_arguments();
644} 656}
645 657
646 658int validate_arguments() {
647 659 if (options == 0) {
648int
649validate_arguments ()
650{
651 if (options == 0)
652 options = ALL; 660 options = ALL;
661 }
653 662
654 if (statopts==NULL) 663 if (statopts == NULL) {
655 statopts = strdup(""); 664 statopts = strdup("");
665 }
656 666
657 if (prog==NULL) 667 if (prog == NULL) {
658 prog = strdup(""); 668 prog = strdup("");
669 }
659 670
660 if (args==NULL) 671 if (args == NULL) {
661 args = strdup(""); 672 args = strdup("");
673 }
662 674
663 if (fmt==NULL) 675 if (fmt == NULL) {
664 fmt = strdup(""); 676 fmt = strdup("");
677 }
665 678
666 if (fails==NULL) 679 if (fails == NULL) {
667 fails = strdup(""); 680 fails = strdup("");
681 }
668 682
669 return options; 683 return options;
670} 684}
671 685
672
673/* convert the elapsed time to seconds */ 686/* convert the elapsed time to seconds */
674int 687int convert_to_seconds(char *etime) {
675convert_to_seconds(char *etime) {
676 688
677 char *ptr; 689 char *ptr;
678 int total; 690 int total;
@@ -704,8 +716,7 @@ convert_to_seconds(char *etime) {
704 } 716 }
705 717
706 if (hyphcnt > 0) { 718 if (hyphcnt > 0) {
707 sscanf(etime, "%d-%d:%d:%d", 719 sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds);
708 &days, &hours, &minutes, &seconds);
709 /* linux 2.6.5/2.6.6 reporting some processes with infinite 720 /* linux 2.6.5/2.6.6 reporting some processes with infinite
710 * elapsed times for some reason */ 721 * elapsed times for some reason */
711 if (days == 49710) { 722 if (days == 49710) {
@@ -713,135 +724,125 @@ convert_to_seconds(char *etime) {
713 } 724 }
714 } else { 725 } else {
715 if (coloncnt == 2) { 726 if (coloncnt == 2) {
716 sscanf(etime, "%d:%d:%d", 727 sscanf(etime, "%d:%d:%d", &hours, &minutes, &seconds);
717 &hours, &minutes, &seconds);
718 } else if (coloncnt == 1) { 728 } else if (coloncnt == 1) {
719 sscanf(etime, "%d:%d", 729 sscanf(etime, "%d:%d", &minutes, &seconds);
720 &minutes, &seconds);
721 } 730 }
722 } 731 }
723 732
724 total = (days * 86400) + 733 total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds;
725 (hours * 3600) +
726 (minutes * 60) +
727 seconds;
728 734
729 if (verbose >= 3 && metric == METRIC_ELAPSED) { 735 if (verbose >= 3 && metric == METRIC_ELAPSED) {
730 printf("seconds: %d\n", total); 736 printf("seconds: %d\n", total);
731 } 737 }
732 return total; 738 return total;
733} 739}
734 740
741void print_help(void) {
742 print_revision(progname, NP_VERSION);
735 743
736void 744 printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
737print_help (void) 745 printf(COPYRIGHT, copyright, email);
738{
739 print_revision (progname, NP_VERSION);
740
741 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
742 printf (COPYRIGHT, copyright, email);
743 746
744 printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); 747 printf("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified"));
745 printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number")); 748 printf("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number"));
746 printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check.")); 749 printf("%s\n", _("of processes. Search filters can be applied to limit the processes to check."));
747 750
748 printf ("\n\n"); 751 printf("\n\n");
749 752
750 printf ("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)")); 753 printf("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)"));
751 printf ("%s\n", _("are excluded from any checks to prevent false positives.")); 754 printf("%s\n", _("are excluded from any checks to prevent false positives."));
752 755
753 printf ("\n\n"); 756 printf("\n\n");
754 757
755 print_usage (); 758 print_usage();
756 759
757 printf (UT_HELP_VRSN); 760 printf(UT_HELP_VRSN);
758 printf (UT_EXTRA_OPTS); 761 printf(UT_EXTRA_OPTS);
759 printf (" %s\n", "-w, --warning=RANGE"); 762 printf(" %s\n", "-w, --warning=RANGE");
760 printf (" %s\n", _("Generate warning state if metric is outside this range")); 763 printf(" %s\n", _("Generate warning state if metric is outside this range"));
761 printf (" %s\n", "-c, --critical=RANGE"); 764 printf(" %s\n", "-c, --critical=RANGE");
762 printf (" %s\n", _("Generate critical state if metric is outside this range")); 765 printf(" %s\n", _("Generate critical state if metric is outside this range"));
763 printf (" %s\n", "-m, --metric=TYPE"); 766 printf(" %s\n", "-m, --metric=TYPE");
764 printf (" %s\n", _("Check thresholds against metric. Valid types:")); 767 printf(" %s\n", _("Check thresholds against metric. Valid types:"));
765 printf (" %s\n", _("PROCS - number of processes (default)")); 768 printf(" %s\n", _("PROCS - number of processes (default)"));
766 printf (" %s\n", _("VSZ - virtual memory size")); 769 printf(" %s\n", _("VSZ - virtual memory size"));
767 printf (" %s\n", _("RSS - resident set memory size")); 770 printf(" %s\n", _("RSS - resident set memory size"));
768 printf (" %s\n", _("CPU - percentage CPU")); 771 printf(" %s\n", _("CPU - percentage CPU"));
769/* only linux etime is support currently */ 772/* only linux etime is support currently */
770#if defined( __linux__ ) 773#if defined(__linux__)
771 printf (" %s\n", _("ELAPSED - time elapsed in seconds")); 774 printf(" %s\n", _("ELAPSED - time elapsed in seconds"));
772#endif /* defined(__linux__) */ 775#endif /* defined(__linux__) */
773 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 776 printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
774 777
775 printf (" %s\n", "-v, --verbose"); 778 printf(" %s\n", "-v, --verbose");
776 printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); 779 printf(" %s\n", _("Extra information. Up to 3 verbosity levels"));
777 780
778 printf (" %s\n", "-T, --traditional"); 781 printf(" %s\n", "-T, --traditional");
779 printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); 782 printf(" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe"));
780 783
781 printf ("\n"); 784 printf("\n");
782 printf ("%s\n", "Filters:"); 785 printf("%s\n", "Filters:");
783 printf (" %s\n", "-s, --state=STATUSFLAGS"); 786 printf(" %s\n", "-s, --state=STATUSFLAGS");
784 printf (" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); 787 printf(" %s\n", _("Only scan for processes that have, in the output of `ps`, one or"));
785 printf (" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); 788 printf(" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,"));
786 printf (" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); 789 printf(" %s\n", _("RSZDT, plus others based on the output of your 'ps' command)."));
787 printf (" %s\n", "-p, --ppid=PPID"); 790 printf(" %s\n", "-p, --ppid=PPID");
788 printf (" %s\n", _("Only scan for children of the parent process ID indicated.")); 791 printf(" %s\n", _("Only scan for children of the parent process ID indicated."));
789 printf (" %s\n", "-z, --vsz=VSZ"); 792 printf(" %s\n", "-z, --vsz=VSZ");
790 printf (" %s\n", _("Only scan for processes with VSZ higher than indicated.")); 793 printf(" %s\n", _("Only scan for processes with VSZ higher than indicated."));
791 printf (" %s\n", "-r, --rss=RSS"); 794 printf(" %s\n", "-r, --rss=RSS");
792 printf (" %s\n", _("Only scan for processes with RSS higher than indicated.")); 795 printf(" %s\n", _("Only scan for processes with RSS higher than indicated."));
793 printf (" %s\n", "-P, --pcpu=PCPU"); 796 printf(" %s\n", "-P, --pcpu=PCPU");
794 printf (" %s\n", _("Only scan for processes with PCPU higher than indicated.")); 797 printf(" %s\n", _("Only scan for processes with PCPU higher than indicated."));
795 printf (" %s\n", "-u, --user=USER"); 798 printf(" %s\n", "-u, --user=USER");
796 printf (" %s\n", _("Only scan for processes with user name or ID indicated.")); 799 printf(" %s\n", _("Only scan for processes with user name or ID indicated."));
797 printf (" %s\n", "-a, --argument-array=STRING"); 800 printf(" %s\n", "-a, --argument-array=STRING");
798 printf (" %s\n", _("Only scan for processes with args that contain STRING.")); 801 printf(" %s\n", _("Only scan for processes with args that contain STRING."));
799 printf (" %s\n", "--ereg-argument-array=STRING"); 802 printf(" %s\n", "--ereg-argument-array=STRING");
800 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); 803 printf(" %s\n", _("Only scan for processes with args that contain the regex STRING."));
801 printf (" %s\n", "-C, --command=COMMAND"); 804 printf(" %s\n", "-C, --command=COMMAND");
802 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); 805 printf(" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
803 printf (" %s\n", "-X, --exclude-process"); 806 printf(" %s\n", "-X, --exclude-process");
804 printf (" %s\n", _("Exclude processes which match this comma separated list")); 807 printf(" %s\n", _("Exclude processes which match this comma separated list"));
805 printf (" %s\n", "-k, --no-kthreads"); 808 printf(" %s\n", "-k, --no-kthreads");
806 printf (" %s\n", _("Only scan for non kernel threads (works on Linux only).")); 809 printf(" %s\n", _("Only scan for non kernel threads (works on Linux only)."));
807 810
808 printf(_("\n\ 811 printf(_("\n\
809RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ 812RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
810specified 'max:min', a warning status will be generated if the\n\ 813specified 'max:min', a warning status will be generated if the\n\
811count is inside the specified range\n\n")); 814count is inside the specified range\n\n"));
812 815
813 printf(_("\ 816 printf(_("\
814This plugin checks the number of currently running processes and\n\ 817This plugin checks the number of currently running processes and\n\
815generates WARNING or CRITICAL states if the process count is outside\n\ 818generates WARNING or CRITICAL states if the process count is outside\n\
816the specified threshold ranges. The process count can be filtered by\n\ 819the specified threshold ranges. The process count can be filtered by\n\
817process owner, parent process PID, current state (e.g., 'Z'), or may\n\ 820process owner, parent process PID, current state (e.g., 'Z'), or may\n\
818be the total number of running processes\n\n")); 821be the total number of running processes\n\n"));
819 822
820 printf ("%s\n", _("Examples:")); 823 printf("%s\n", _("Examples:"));
821 printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); 824 printf(" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry");
822 printf (" %s\n", _("Warning if not two processes with command name portsentry.")); 825 printf(" %s\n", _("Warning if not two processes with command name portsentry."));
823 printf (" %s\n\n", _("Critical if < 2 or > 1024 processes")); 826 printf(" %s\n\n", _("Critical if < 2 or > 1024 processes"));
824 printf (" %s\n", "check_procs -c 1: -C sshd"); 827 printf(" %s\n", "check_procs -c 1: -C sshd");
825 printf (" %s\n", _("Critical if not at least 1 process with command sshd")); 828 printf(" %s\n", _("Critical if not at least 1 process with command sshd"));
826 printf (" %s\n", "check_procs -w 1024 -c 1: -C sshd"); 829 printf(" %s\n", "check_procs -w 1024 -c 1: -C sshd");
827 printf (" %s\n", _("Warning if > 1024 processes with command name sshd.")); 830 printf(" %s\n", _("Warning if > 1024 processes with command name sshd."));
828 printf (" %s\n\n", _("Critical if < 1 processes with command name sshd.")); 831 printf(" %s\n\n", _("Critical if < 1 processes with command name sshd."));
829 printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); 832 printf(" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root");
830 printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing")); 833 printf(" %s\n", _("Warning alert if > 10 processes with command arguments containing"));
831 printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); 834 printf(" %s\n\n", _("'/usr/local/bin/perl' and owned by root"));
832 printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); 835 printf(" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ");
833 printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); 836 printf(" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K"));
834 printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); 837 printf(" %s\n", "check_procs -w 10 -c 20 --metric=CPU");
835 printf (" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); 838 printf(" %s\n", _("Alert if CPU of any processes over 10%% or 20%%"));
836 839
837 printf (UT_SUPPORT); 840 printf(UT_SUPPORT);
838} 841}
839 842
840void 843void print_usage(void) {
841print_usage (void) 844 printf("%s\n", _("Usage:"));
842{ 845 printf("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
843 printf ("%s\n", _("Usage:")); 846 printf(" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
844 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); 847 printf(" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n");
845 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
846 printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n");
847} 848}