1 /******************************************************************************
2 *
3 * Nagios check_procs plugin
4 *
5 * License: GPL
6 * Copyright (c) 1999-2006 nagios-plugins team
7 *
8 * Last Modified: $Date$
9 *
10 * Description:
11 *
12 * This file contains the check_procs plugin
13 *
14 * License Information:
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * $Id$
31 *
32 ******************************************************************************/
34 const char *progname = "check_procs";
35 const char *revision = "$Revision$";
36 const char *copyright = "2000-2006";
37 const char *email = "nagiosplug-devel@lists.sourceforge.net";
39 #include "common.h"
40 #include "popen.h"
41 #include "utils.h"
43 #include <pwd.h>
45 int process_arguments (int, char **);
46 int validate_arguments (void);
47 int check_thresholds (int);
48 int convert_to_seconds (char *);
49 void print_help (void);
50 void print_usage (void);
52 int wmax = -1;
53 int cmax = -1;
54 int wmin = -1;
55 int cmin = -1;
57 int options = 0; /* bitmask of filter criteria to test against */
58 #define ALL 1
59 #define STAT 2
60 #define PPID 4
61 #define USER 8
62 #define PROG 16
63 #define ARGS 32
64 #define VSZ 64
65 #define RSS 128
66 #define PCPU 256
67 #define ELAPSED 512
68 /* Different metrics */
69 char *metric_name;
70 enum metric {
71 METRIC_PROCS,
72 METRIC_VSZ,
73 METRIC_RSS,
74 METRIC_CPU,
75 METRIC_ELAPSED
76 };
77 enum metric metric = METRIC_PROCS;
79 int verbose = 0;
80 int uid;
81 pid_t ppid;
82 int vsz;
83 int rss;
84 float pcpu;
85 char *statopts;
86 char *prog;
87 char *args;
88 char *fmt;
89 char *fails;
90 char tmp[MAX_INPUT_BUFFER];
94 int
95 main (int argc, char **argv)
96 {
97 char *input_buffer;
98 char *input_line;
99 char *procprog;
101 pid_t mypid = 0;
102 int procuid = 0;
103 pid_t procpid = 0;
104 pid_t procppid = 0;
105 int procvsz = 0;
106 int procrss = 0;
107 int procseconds = 0;
108 float procpcpu = 0;
109 char procstat[8];
110 char procetime[MAX_INPUT_BUFFER] = { '\0' };
111 char *procargs;
113 const char *zombie = "Z";
115 int resultsum = 0; /* bitmask of the filter criteria met by a process */
116 int found = 0; /* counter for number of lines returned in `ps` output */
117 int procs = 0; /* counter for number of processes meeting filter criteria */
118 int pos; /* number of spaces before 'args' in `ps` output */
119 int cols; /* number of columns in ps output */
120 int expected_cols = PS_COLS - 1;
121 int warn = 0; /* number of processes in warn state */
122 int crit = 0; /* number of processes in crit state */
123 int i = 0;
124 int result = STATE_UNKNOWN;
126 setlocale (LC_ALL, "");
127 bindtextdomain (PACKAGE, LOCALEDIR);
128 textdomain (PACKAGE);
129 setlocale(LC_NUMERIC, "POSIX");
131 input_buffer = malloc (MAX_INPUT_BUFFER);
132 procprog = malloc (MAX_INPUT_BUFFER);
134 asprintf (&metric_name, "PROCS");
135 metric = METRIC_PROCS;
137 if (process_arguments (argc, argv) == ERROR)
138 usage4 (_("Could not parse arguments"));
140 /* get our pid */
141 mypid = getpid();
143 /* Set signal handling and alarm timeout */
144 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
145 usage4 (_("Cannot catch SIGALRM"));
146 }
147 alarm (timeout_interval);
149 if (verbose >= 2)
150 printf (_("CMD: %s\n"), PS_COMMAND);
152 child_process = spopen (PS_COMMAND);
153 if (child_process == NULL) {
154 printf (_("Could not open pipe: %s\n"), PS_COMMAND);
155 return STATE_UNKNOWN;
156 }
158 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
159 if (child_stderr == NULL)
160 printf (_("Could not open stderr for %s\n"), PS_COMMAND);
162 /* flush first line */
163 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
164 while ( input_buffer[strlen(input_buffer)-1] != '\n' )
165 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
167 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
168 asprintf (&input_line, "%s", input_buffer);
169 while ( input_buffer[strlen(input_buffer)-1] != '\n' ) {
170 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
171 asprintf (&input_line, "%s%s", input_line, input_buffer);
172 }
174 if (verbose >= 3)
175 printf ("%s", input_line);
177 strcpy (procprog, "");
178 asprintf (&procargs, "%s", "");
180 cols = sscanf (input_line, PS_FORMAT, PS_VARLIST);
182 /* Zombie processes do not give a procprog command */
183 if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) {
184 cols = expected_cols;
185 }
186 if ( cols >= expected_cols ) {
187 resultsum = 0;
188 asprintf (&procargs, "%s", input_line + pos);
189 strip (procargs);
191 /* Some ps return full pathname for command. This removes path */
192 procprog = base_name(procprog);
194 /* we need to convert the elapsed time to seconds */
195 procseconds = convert_to_seconds(procetime);
197 if (verbose >= 3)
198 printf ("%d %d %d %d %d %d %.2f %s %s %s %s\n",
199 procs, procuid, procvsz, procrss,
200 procpid, procppid, procpcpu, procstat,
201 procetime, procprog, procargs);
203 /* Ignore self */
204 if (mypid == procpid) continue;
206 if ((options & STAT) && (strstr (statopts, procstat)))
207 resultsum |= STAT;
208 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
209 resultsum |= ARGS;
210 if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0))
211 resultsum |= PROG;
212 if ((options & PPID) && (procppid == ppid))
213 resultsum |= PPID;
214 if ((options & USER) && (procuid == uid))
215 resultsum |= USER;
216 if ((options & VSZ) && (procvsz >= vsz))
217 resultsum |= VSZ;
218 if ((options & RSS) && (procrss >= rss))
219 resultsum |= RSS;
220 if ((options & PCPU) && (procpcpu >= pcpu))
221 resultsum |= PCPU;
223 found++;
225 /* Next line if filters not matched */
226 if (!(options == resultsum || options == ALL))
227 continue;
229 procs++;
231 if (metric == METRIC_VSZ)
232 i = check_thresholds (procvsz);
233 else if (metric == METRIC_RSS)
234 i = check_thresholds (procrss);
235 /* TODO? float thresholds for --metric=CPU */
236 else if (metric == METRIC_CPU)
237 i = check_thresholds ((int)procpcpu);
238 else if (metric == METRIC_ELAPSED)
239 i = check_thresholds (procseconds);
241 if (metric != METRIC_PROCS) {
242 if (i == STATE_WARNING) {
243 warn++;
244 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
245 result = max_state (result, i);
246 }
247 if (i == STATE_CRITICAL) {
248 crit++;
249 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
250 result = max_state (result, i);
251 }
252 }
253 }
254 /* This should not happen */
255 else if (verbose) {
256 printf(_("Not parseable: %s"), input_buffer);
257 }
258 }
260 /* If we get anything on STDERR, at least set warning */
261 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
262 if (verbose)
263 printf ("STDERR: %s", input_buffer);
264 result = max_state (result, STATE_WARNING);
265 printf (_("System call sent warnings to stderr\n"));
266 }
268 (void) fclose (child_stderr);
270 /* close the pipe */
271 if (spclose (child_process)) {
272 printf (_("System call returned nonzero status\n"));
273 result = max_state (result, STATE_WARNING);
274 }
276 if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */
277 printf (_("Unable to read output\n"));
278 return result;
279 }
281 if ( result == STATE_UNKNOWN )
282 result = STATE_OK;
284 /* Needed if procs found, but none match filter */
285 if ( metric == METRIC_PROCS ) {
286 result = max_state (result, check_thresholds (procs) );
287 }
289 if ( result == STATE_OK ) {
290 printf ("%s %s: ", metric_name, _("OK"));
291 } else if (result == STATE_WARNING) {
292 printf ("%s %s: ", metric_name, _("WARNING"));
293 if ( metric != METRIC_PROCS ) {
294 printf (_("%d warn out of "), warn);
295 }
296 } else if (result == STATE_CRITICAL) {
297 printf ("%s %s: ", metric_name, _("CRITICAL"));
298 if (metric != METRIC_PROCS) {
299 printf (_("%d crit, %d warn out of "), crit, warn);
300 }
301 }
302 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs);
304 if (strcmp(fmt,"") != 0) {
305 printf (_(" with %s"), fmt);
306 }
308 if ( verbose >= 1 && strcmp(fails,"") )
309 printf (" [%s]", fails);
311 printf ("\n");
312 return result;
313 }
317 /* process command-line arguments */
318 int
319 process_arguments (int argc, char **argv)
320 {
321 int c = 1;
322 char *user;
323 struct passwd *pw;
324 int option = 0;
325 static struct option longopts[] = {
326 {"warning", required_argument, 0, 'w'},
327 {"critical", required_argument, 0, 'c'},
328 {"metric", required_argument, 0, 'm'},
329 {"timeout", required_argument, 0, 't'},
330 {"status", required_argument, 0, 's'},
331 {"ppid", required_argument, 0, 'p'},
332 {"command", required_argument, 0, 'C'},
333 {"vsz", required_argument, 0, 'z'},
334 {"rss", required_argument, 0, 'r'},
335 {"pcpu", required_argument, 0, 'P'},
336 {"elapsed", required_argument, 0, 'e'},
337 {"argument-array", required_argument, 0, 'a'},
338 {"help", no_argument, 0, 'h'},
339 {"version", no_argument, 0, 'V'},
340 {"verbose", no_argument, 0, 'v'},
341 {0, 0, 0, 0}
342 };
344 for (c = 1; c < argc; c++)
345 if (strcmp ("-to", argv[c]) == 0)
346 strcpy (argv[c], "-t");
348 while (1) {
349 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:",
350 longopts, &option);
352 if (c == -1 || c == EOF)
353 break;
355 switch (c) {
356 case '?': /* help */
357 usage2 (_("Unknown argument"), optarg);
358 case 'h': /* help */
359 print_help ();
360 exit (STATE_OK);
361 case 'V': /* version */
362 print_revision (progname, revision);
363 exit (STATE_OK);
364 case 't': /* timeout period */
365 if (!is_integer (optarg))
366 usage2 (_("Timeout interval must be a positive integer"), optarg);
367 else
368 timeout_interval = atoi (optarg);
369 break;
370 case 'c': /* critical threshold */
371 if (is_integer (optarg))
372 cmax = atoi (optarg);
373 else if (sscanf (optarg, ":%d", &cmax) == 1)
374 break;
375 else if (sscanf (optarg, "%d:%d", &cmin, &cmax) == 2)
376 break;
377 else if (sscanf (optarg, "%d:", &cmin) == 1)
378 break;
379 else
380 usage4 (_("Critical Process Count must be an integer!"));
381 break;
382 case 'w': /* warning threshold */
383 if (is_integer (optarg))
384 wmax = atoi (optarg);
385 else if (sscanf (optarg, ":%d", &wmax) == 1)
386 break;
387 else if (sscanf (optarg, "%d:%d", &wmin, &wmax) == 2)
388 break;
389 else if (sscanf (optarg, "%d:", &wmin) == 1)
390 break;
391 else
392 usage4 (_("Warning Process Count must be an integer!"));
393 break;
394 case 'p': /* process id */
395 if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) {
396 asprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid);
397 options |= PPID;
398 break;
399 }
400 usage4 (_("Parent Process ID must be an integer!"));
401 case 's': /* status */
402 if (statopts)
403 break;
404 else
405 statopts = optarg;
406 asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
407 options |= STAT;
408 break;
409 case 'u': /* user or user id */
410 if (is_integer (optarg)) {
411 uid = atoi (optarg);
412 pw = getpwuid ((uid_t) uid);
413 /* check to be sure user exists */
414 if (pw == NULL)
415 usage2 (_("UID %s was not found"), optarg);
416 }
417 else {
418 pw = getpwnam (optarg);
419 /* check to be sure user exists */
420 if (pw == NULL)
421 usage2 (_("User name %s was not found"), optarg);
422 /* then get uid */
423 uid = pw->pw_uid;
424 }
425 user = pw->pw_name;
426 asprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""),
427 uid, user);
428 options |= USER;
429 break;
430 case 'C': /* command */
431 /* TODO: allow this to be passed in with --metric */
432 if (prog)
433 break;
434 else
435 prog = optarg;
436 asprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
437 prog);
438 options |= PROG;
439 break;
440 case 'a': /* args (full path name with args) */
441 /* TODO: allow this to be passed in with --metric */
442 if (args)
443 break;
444 else
445 args = optarg;
446 asprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args);
447 options |= ARGS;
448 break;
449 case 'r': /* RSS */
450 if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) {
451 asprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss);
452 options |= RSS;
453 break;
454 }
455 usage4 (_("RSS must be an integer!"));
456 case 'z': /* VSZ */
457 if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) {
458 asprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz);
459 options |= VSZ;
460 break;
461 }
462 usage4 (_("VSZ must be an integer!"));
463 case 'P': /* PCPU */
464 /* TODO: -P 1.5.5 is accepted */
465 if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) {
466 asprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu);
467 options |= PCPU;
468 break;
469 }
470 usage4 (_("PCPU must be a float!"));
471 case 'm':
472 asprintf (&metric_name, "%s", optarg);
473 if ( strcmp(optarg, "PROCS") == 0) {
474 metric = METRIC_PROCS;
475 break;
476 }
477 else if ( strcmp(optarg, "VSZ") == 0) {
478 metric = METRIC_VSZ;
479 break;
480 }
481 else if ( strcmp(optarg, "RSS") == 0 ) {
482 metric = METRIC_RSS;
483 break;
484 }
485 else if ( strcmp(optarg, "CPU") == 0 ) {
486 metric = METRIC_CPU;
487 break;
488 }
489 else if ( strcmp(optarg, "ELAPSED") == 0) {
490 metric = METRIC_ELAPSED;
491 break;
492 }
494 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
495 case 'v': /* command */
496 verbose++;
497 break;
498 }
499 }
501 c = optind;
502 if (wmax == -1 && argv[c])
503 wmax = atoi (argv[c++]);
504 if (cmax == -1 && argv[c])
505 cmax = atoi (argv[c++]);
506 if (statopts == NULL && argv[c]) {
507 asprintf (&statopts, "%s", argv[c++]);
508 asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
509 options |= STAT;
510 }
512 return validate_arguments ();
513 }
517 int
518 validate_arguments ()
519 {
521 if (wmax >= 0 && wmin == -1)
522 wmin = 0;
523 if (cmax >= 0 && cmin == -1)
524 cmin = 0;
525 if (wmax >= wmin && cmax >= cmin) { /* standard ranges */
526 if (wmax > cmax && cmax != -1) {
527 printf (_("wmax (%d) cannot be greater than cmax (%d)\n"), wmax, cmax);
528 return ERROR;
529 }
530 if (cmin > wmin && wmin != -1) {
531 printf (_("wmin (%d) cannot be less than cmin (%d)\n"), wmin, cmin);
532 return ERROR;
533 }
534 }
536 /* if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) { */
537 /* printf ("At least one threshold must be set\n"); */
538 /* return ERROR; */
539 /* } */
541 if (options == 0)
542 options = ALL;
544 if (statopts==NULL)
545 statopts = strdup("");
547 if (prog==NULL)
548 prog = strdup("");
550 if (args==NULL)
551 args = strdup("");
553 if (fmt==NULL)
554 fmt = strdup("");
556 if (fails==NULL)
557 fails = strdup("");
559 return options;
560 }
564 /* Check thresholds against value */
565 int
566 check_thresholds (int value)
567 {
568 if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) {
569 return OK;
570 }
571 else if (cmax >= 0 && cmin >= 0 && cmax < cmin) {
572 if (value > cmax && value < cmin)
573 return STATE_CRITICAL;
574 }
575 else if (cmax >= 0 && value > cmax) {
576 return STATE_CRITICAL;
577 }
578 else if (cmin >= 0 && value < cmin) {
579 return STATE_CRITICAL;
580 }
582 if (wmax >= 0 && wmin >= 0 && wmax < wmin) {
583 if (value > wmax && value < wmin) {
584 return STATE_WARNING;
585 }
586 }
587 else if (wmax >= 0 && value > wmax) {
588 return STATE_WARNING;
589 }
590 else if (wmin >= 0 && value < wmin) {
591 return STATE_WARNING;
592 }
593 return STATE_OK;
594 }
597 /* convert the elapsed time to seconds */
598 int
599 convert_to_seconds(char *etime) {
601 char *ptr;
602 int total;
604 int hyphcnt;
605 int coloncnt;
606 int days;
607 int hours;
608 int minutes;
609 int seconds;
611 hyphcnt = 0;
612 coloncnt = 0;
613 days = 0;
614 hours = 0;
615 minutes = 0;
616 seconds = 0;
618 for (ptr = etime; *ptr != '\0'; ptr++) {
620 if (*ptr == '-') {
621 hyphcnt++;
622 continue;
623 }
624 if (*ptr == ':') {
625 coloncnt++;
626 continue;
627 }
628 }
630 if (hyphcnt > 0) {
631 sscanf(etime, "%d-%d:%d:%d",
632 &days, &hours, &minutes, &seconds);
633 /* linux 2.6.5/2.6.6 reporting some processes with infinite
634 * elapsed times for some reason */
635 if (days == 49710) {
636 return 0;
637 }
638 } else {
639 if (coloncnt == 2) {
640 sscanf(etime, "%d:%d:%d",
641 &hours, &minutes, &seconds);
642 } else if (coloncnt == 1) {
643 sscanf(etime, "%d:%d",
644 &minutes, &seconds);
645 }
646 }
648 total = (days * 86400) +
649 (hours * 3600) +
650 (minutes * 60) +
651 seconds;
653 if (verbose >= 3 && metric == METRIC_ELAPSED) {
654 printf("seconds: %d\n", total);
655 }
656 return total;
657 }
660 void
661 print_help (void)
662 {
663 print_revision (progname, revision);
665 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>");
666 printf (COPYRIGHT, copyright, email);
668 printf(_("\
669 Checks all processes and generates WARNING or CRITICAL states if the specified\n\
670 metric is outside the required threshold ranges. The metric defaults to number\n\
671 of processes. Search filters can be applied to limit the processes to check.\n\n"));
673 print_usage ();
675 printf(_("\n\
676 Required Arguments:\n\
677 -w, --warning=RANGE\n\
678 Generate warning state if metric is outside this range\n\
679 -c, --critical=RANGE\n\
680 Generate critical state if metric is outside this range\n"));
682 printf(_("\n\
683 Optional Arguments:\n\
684 -m, --metric=TYPE\n\
685 Check thresholds against metric. Valid types:\n\
686 PROCS - number of processes (default)\n\
687 VSZ - virtual memory size\n\
688 RSS - resident set memory size\n\
689 CPU - percentage cpu\n"));
690 /* only linux etime is support currently */
691 #if defined( __linux__ )
692 printf(_("\
693 ELAPSED - time elapsed in seconds\n"));
694 #endif /* defined(__linux__) */
695 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
697 printf(_("\
698 -v, --verbose\n\
699 Extra information. Up to 3 verbosity levels\n"));
701 printf(_("\n\
702 Optional Filters:\n\
703 -s, --state=STATUSFLAGS\n\
704 Only scan for processes that have, in the output of `ps`, one or\n\
705 more of the status flags you specify (for example R, Z, S, RS,\n\
706 RSZDT, plus others based on the output of your 'ps' command).\n\
707 -p, --ppid=PPID\n\
708 Only scan for children of the parent process ID indicated.\n\
709 -z, --vsz=VSZ\n\
710 Only scan for processes with vsz higher than indicated.\n\
711 -r, --rss=RSS\n\
712 Only scan for processes with rss higher than indicated.\n"));
714 printf(_("\
715 -P, --pcpu=PCPU\n\
716 Only scan for processes with pcpu higher than indicated.\n\
717 -u, --user=USER\n\
718 Only scan for processes with user name or ID indicated.\n\
719 -a, --argument-array=STRING\n\
720 Only scan for processes with args that contain STRING.\n\
721 -C, --command=COMMAND\n\
722 Only scan for exact matches of COMMAND (without path).\n"));
724 printf(_("\n\
725 RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
726 specified 'max:min', a warning status will be generated if the\n\
727 count is inside the specified range\n\n"));
729 printf(_("\
730 This plugin checks the number of currently running processes and\n\
731 generates WARNING or CRITICAL states if the process count is outside\n\
732 the specified threshold ranges. The process count can be filtered by\n\
733 process owner, parent process PID, current state (e.g., 'Z'), or may\n\
734 be the total number of running processes\n\n"));
736 printf(_("\
737 Examples:\n\
738 check_procs -w 2:2 -c 2:1024 -C portsentry\n\
739 Warning if not two processes with command name portsentry. Critical\n\
740 if < 2 or > 1024 processes\n\n\
741 check_procs -w 10 -a '/usr/local/bin/perl' -u root\n\
742 Warning alert if > 10 processes with command arguments containing \n\
743 '/usr/local/bin/perl' and owned by root\n\n\
744 check_procs -w 50000 -c 100000 --metric=VSZ\n\
745 Alert if vsz of any processes over 50K or 100K\n\
746 check_procs -w 10 -c 20 --metric=CPU\n\
747 Alert if cpu of any processes over 10%% or 20%%\n\n"));
749 printf (_(UT_SUPPORT));
750 }
752 void
753 print_usage (void)
754 {
755 printf (_("Usage:"));
756 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
757 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
758 printf (" [-C command] [-t timeout] [-v]\n");
759 }