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