1 /*****************************************************************************
2 *
3 * Nagios check_procs plugin
4 *
5 * License: GPL
6 * Copyright (c) 2000-2008 Nagios Plugins Development Team
7 *
8 * Description:
9 *
10 * This file contains the check_procs plugin
11 *
12 * Checks all processes and generates WARNING or CRITICAL states if the
13 * specified metric is outside the required threshold ranges. The metric
14 * defaults to number of processes. Search filters can be applied to limit
15 * the processes to check.
16 *
17 *
18 * This program is free software: you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation, either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 *
31 *
32 *****************************************************************************/
34 const char *progname = "check_procs";
35 const char *program_name = "check_procs"; /* Required for coreutils libs */
36 const char *copyright = "2000-2008";
37 const char *email = "nagiosplug-devel@lists.sourceforge.net";
39 #include "common.h"
40 #include "utils.h"
41 #include "utils_cmd.h"
42 #include "regex.h"
44 #include <pwd.h>
46 int process_arguments (int, char **);
47 int validate_arguments (void);
48 int convert_to_seconds (char *);
49 void print_help (void);
50 void print_usage (void);
52 char *warning_range = NULL;
53 char *critical_range = NULL;
54 thresholds *procs_thresholds = NULL;
56 int options = 0; /* bitmask of filter criteria to test against */
57 #define ALL 1
58 #define STAT 2
59 #define PPID 4
60 #define USER 8
61 #define PROG 16
62 #define ARGS 32
63 #define VSZ 64
64 #define RSS 128
65 #define PCPU 256
66 #define ELAPSED 512
67 #define EREG_ARGS 1024
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 *input_filename = NULL;
89 regex_t re_args;
90 char *fmt;
91 char *fails;
92 char tmp[MAX_INPUT_BUFFER];
94 FILE *ps_input = NULL;
97 int
98 main (int argc, char **argv)
99 {
100 char *input_buffer;
101 char *input_line;
102 char *procprog;
104 pid_t mypid = 0;
105 int procuid = 0;
106 pid_t procpid = 0;
107 pid_t procppid = 0;
108 int procvsz = 0;
109 int procrss = 0;
110 int procseconds = 0;
111 float procpcpu = 0;
112 char procstat[8];
113 char procetime[MAX_INPUT_BUFFER] = { '\0' };
114 char *procargs;
116 const char *zombie = "Z";
118 int resultsum = 0; /* bitmask of the filter criteria met by a process */
119 int found = 0; /* counter for number of lines returned in `ps` output */
120 int procs = 0; /* counter for number of processes meeting filter criteria */
121 int pos; /* number of spaces before 'args' in `ps` output */
122 int cols; /* number of columns in ps output */
123 int expected_cols = PS_COLS - 1;
124 int warn = 0; /* number of processes in warn state */
125 int crit = 0; /* number of processes in crit state */
126 int i = 0, j = 0;
127 int result = STATE_UNKNOWN;
128 output chld_out, chld_err;
130 setlocale (LC_ALL, "");
131 bindtextdomain (PACKAGE, LOCALEDIR);
132 textdomain (PACKAGE);
133 setlocale(LC_NUMERIC, "POSIX");
135 input_buffer = malloc (MAX_INPUT_BUFFER);
136 procprog = malloc (MAX_INPUT_BUFFER);
138 asprintf (&metric_name, "PROCS");
139 metric = METRIC_PROCS;
141 /* Parse extra opts if any */
142 argv=np_extra_opts (&argc, argv, progname);
144 if (process_arguments (argc, argv) == ERROR)
145 usage4 (_("Could not parse arguments"));
147 /* get our pid */
148 mypid = getpid();
150 /* Set signal handling and alarm timeout */
151 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
152 die (STATE_UNKNOWN, _("Cannot catch SIGALRM"));
153 }
154 (void) alarm ((unsigned) timeout_interval);
156 if (verbose >= 2)
157 printf (_("CMD: %s\n"), PS_COMMAND);
159 if (input_filename == NULL) {
160 result = cmd_run( PS_COMMAND, &chld_out, &chld_err, 0);
161 if (chld_err.lines > 0) {
162 printf ("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]);
163 exit(STATE_WARNING);
164 }
165 } else {
166 result = cmd_file_read( input_filename, &chld_out, 0);
167 }
169 /* flush first line: j starts at 1 */
170 for (j = 1; j < chld_out.lines; j++) {
171 input_line = chld_out.line[j];
173 if (verbose >= 3)
174 printf ("%s", input_line);
176 strcpy (procprog, "");
177 asprintf (&procargs, "%s", "");
179 cols = sscanf (input_line, PS_FORMAT, PS_VARLIST);
181 /* Zombie processes do not give a procprog command */
182 if ( cols < expected_cols && strstr(procstat, zombie) ) {
183 cols = expected_cols;
184 }
185 if ( cols >= expected_cols ) {
186 resultsum = 0;
187 asprintf (&procargs, "%s", input_line + pos);
188 strip (procargs);
190 /* Some ps return full pathname for command. This removes path */
191 strcpy(procprog, base_name(procprog));
193 /* we need to convert the elapsed time to seconds */
194 procseconds = convert_to_seconds(procetime);
196 if (verbose >= 3)
197 printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
198 procs, procuid, procvsz, procrss,
199 procpid, procppid, procpcpu, procstat,
200 procetime, procprog, procargs);
202 /* Ignore self */
203 if (mypid == procpid) continue;
205 if ((options & STAT) && (strstr (statopts, procstat)))
206 resultsum |= STAT;
207 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
208 resultsum |= ARGS;
209 if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t) 0, NULL, 0) == 0))
210 resultsum |= EREG_ARGS;
211 if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0))
212 resultsum |= PROG;
213 if ((options & PPID) && (procppid == ppid))
214 resultsum |= PPID;
215 if ((options & USER) && (procuid == uid))
216 resultsum |= USER;
217 if ((options & VSZ) && (procvsz >= vsz))
218 resultsum |= VSZ;
219 if ((options & RSS) && (procrss >= rss))
220 resultsum |= RSS;
221 if ((options & PCPU) && (procpcpu >= pcpu))
222 resultsum |= PCPU;
224 found++;
226 /* Next line if filters not matched */
227 if (!(options == resultsum || options == ALL))
228 continue;
230 procs++;
231 if (verbose >= 2) {
232 printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
233 procuid, procvsz, procrss,
234 procpid, procppid, procpcpu, procstat,
235 procetime, procprog, procargs);
236 }
238 if (metric == METRIC_VSZ)
239 i = get_status ((double)procvsz, procs_thresholds);
240 else if (metric == METRIC_RSS)
241 i = get_status ((double)procrss, procs_thresholds);
242 /* TODO? float thresholds for --metric=CPU */
243 else if (metric == METRIC_CPU)
244 i = get_status (procpcpu, procs_thresholds);
245 else if (metric == METRIC_ELAPSED)
246 i = get_status ((double)procseconds, procs_thresholds);
248 if (metric != METRIC_PROCS) {
249 if (i == STATE_WARNING) {
250 warn++;
251 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
252 result = max_state (result, i);
253 }
254 if (i == STATE_CRITICAL) {
255 crit++;
256 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
257 result = max_state (result, i);
258 }
259 }
260 }
261 /* This should not happen */
262 else if (verbose) {
263 printf(_("Not parseable: %s"), input_buffer);
264 }
265 }
267 if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */
268 printf (_("Unable to read output\n"));
269 return STATE_UNKNOWN;
270 }
272 if ( result == STATE_UNKNOWN )
273 result = STATE_OK;
275 /* Needed if procs found, but none match filter */
276 if ( metric == METRIC_PROCS ) {
277 result = max_state (result, get_status ((double)procs, procs_thresholds) );
278 }
280 if ( result == STATE_OK ) {
281 printf ("%s %s: ", metric_name, _("OK"));
282 } else if (result == STATE_WARNING) {
283 printf ("%s %s: ", metric_name, _("WARNING"));
284 if ( metric != METRIC_PROCS ) {
285 printf (_("%d warn out of "), warn);
286 }
287 } else if (result == STATE_CRITICAL) {
288 printf ("%s %s: ", metric_name, _("CRITICAL"));
289 if (metric != METRIC_PROCS) {
290 printf (_("%d crit, %d warn out of "), crit, warn);
291 }
292 }
293 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs);
295 if (strcmp(fmt,"") != 0) {
296 printf (_(" with %s"), fmt);
297 }
299 if ( verbose >= 1 && strcmp(fails,"") )
300 printf (" [%s]", fails);
302 printf ("\n");
303 return result;
304 }
308 /* process command-line arguments */
309 int
310 process_arguments (int argc, char **argv)
311 {
312 int c = 1;
313 char *user;
314 struct passwd *pw;
315 int option = 0;
316 int err;
317 int cflags = REG_NOSUB | REG_EXTENDED;
318 char errbuf[MAX_INPUT_BUFFER];
319 char *temp_string;
320 int i=0;
321 static struct option longopts[] = {
322 {"warning", required_argument, 0, 'w'},
323 {"critical", required_argument, 0, 'c'},
324 {"metric", required_argument, 0, 'm'},
325 {"timeout", required_argument, 0, 't'},
326 {"status", required_argument, 0, 's'},
327 {"ppid", required_argument, 0, 'p'},
328 {"command", required_argument, 0, 'C'},
329 {"vsz", required_argument, 0, 'z'},
330 {"rss", required_argument, 0, 'r'},
331 {"pcpu", required_argument, 0, 'P'},
332 {"elapsed", required_argument, 0, 'e'},
333 {"argument-array", required_argument, 0, 'a'},
334 {"help", no_argument, 0, 'h'},
335 {"version", no_argument, 0, 'V'},
336 {"verbose", no_argument, 0, 'v'},
337 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1},
338 {"input-file", required_argument, 0, CHAR_MAX+2},
339 {0, 0, 0, 0}
340 };
342 for (c = 1; c < argc; c++)
343 if (strcmp ("-to", argv[c]) == 0)
344 strcpy (argv[c], "-t");
346 while (1) {
347 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:",
348 longopts, &option);
350 if (c == -1 || c == EOF)
351 break;
353 switch (c) {
354 case '?': /* help */
355 usage5 ();
356 case 'h': /* help */
357 print_help ();
358 exit (STATE_OK);
359 case 'V': /* version */
360 print_revision (progname, NP_VERSION);
361 exit (STATE_OK);
362 case 't': /* timeout period */
363 if (!is_integer (optarg))
364 usage2 (_("Timeout interval must be a positive integer"), optarg);
365 else
366 timeout_interval = atoi (optarg);
367 break;
368 case 'c': /* critical threshold */
369 critical_range = optarg;
370 break;
371 case 'w': /* warning threshold */
372 warning_range = optarg;
373 break;
374 case 'p': /* process id */
375 if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) {
376 asprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid);
377 options |= PPID;
378 break;
379 }
380 usage4 (_("Parent Process ID must be an integer!"));
381 case 's': /* status */
382 if (statopts)
383 break;
384 else
385 statopts = optarg;
386 asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
387 options |= STAT;
388 break;
389 case 'u': /* user or user id */
390 if (is_integer (optarg)) {
391 uid = atoi (optarg);
392 pw = getpwuid ((uid_t) uid);
393 /* check to be sure user exists */
394 if (pw == NULL)
395 usage2 (_("UID was not found"), optarg);
396 }
397 else {
398 pw = getpwnam (optarg);
399 /* check to be sure user exists */
400 if (pw == NULL)
401 usage2 (_("User name was not found"), optarg);
402 /* then get uid */
403 uid = pw->pw_uid;
404 }
405 user = pw->pw_name;
406 asprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""),
407 uid, user);
408 options |= USER;
409 break;
410 case 'C': /* command */
411 /* TODO: allow this to be passed in with --metric */
412 if (prog)
413 break;
414 else
415 prog = optarg;
416 asprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
417 prog);
418 options |= PROG;
419 break;
420 case 'a': /* args (full path name with args) */
421 /* TODO: allow this to be passed in with --metric */
422 if (args)
423 break;
424 else
425 args = optarg;
426 asprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args);
427 options |= ARGS;
428 break;
429 case CHAR_MAX+1:
430 err = regcomp(&re_args, optarg, cflags);
431 if (err != 0) {
432 regerror (err, &re_args, errbuf, MAX_INPUT_BUFFER);
433 die (STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf);
434 }
435 /* Strip off any | within the regex optarg */
436 temp_string = strdup(optarg);
437 while(temp_string[i]!='\0'){
438 if(temp_string[i]=='|')
439 temp_string[i]=',';
440 i++;
441 }
442 asprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string);
443 options |= EREG_ARGS;
444 break;
445 case 'r': /* RSS */
446 if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) {
447 asprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss);
448 options |= RSS;
449 break;
450 }
451 usage4 (_("RSS must be an integer!"));
452 case 'z': /* VSZ */
453 if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) {
454 asprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz);
455 options |= VSZ;
456 break;
457 }
458 usage4 (_("VSZ must be an integer!"));
459 case 'P': /* PCPU */
460 /* TODO: -P 1.5.5 is accepted */
461 if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) {
462 asprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu);
463 options |= PCPU;
464 break;
465 }
466 usage4 (_("PCPU must be a float!"));
467 case 'm':
468 asprintf (&metric_name, "%s", optarg);
469 if ( strcmp(optarg, "PROCS") == 0) {
470 metric = METRIC_PROCS;
471 break;
472 }
473 else if ( strcmp(optarg, "VSZ") == 0) {
474 metric = METRIC_VSZ;
475 break;
476 }
477 else if ( strcmp(optarg, "RSS") == 0 ) {
478 metric = METRIC_RSS;
479 break;
480 }
481 else if ( strcmp(optarg, "CPU") == 0 ) {
482 metric = METRIC_CPU;
483 break;
484 }
485 else if ( strcmp(optarg, "ELAPSED") == 0) {
486 metric = METRIC_ELAPSED;
487 break;
488 }
490 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
491 case 'v': /* command */
492 verbose++;
493 break;
494 case CHAR_MAX+2:
495 input_filename = optarg;
496 break;
497 }
498 }
500 c = optind;
501 if ((! warning_range) && argv[c])
502 warning_range = argv[c++];
503 if ((! critical_range) && argv[c])
504 critical_range = argv[c++];
505 if (statopts == NULL && argv[c]) {
506 asprintf (&statopts, "%s", argv[c++]);
507 asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
508 options |= STAT;
509 }
511 /* this will abort in case of invalid ranges */
512 set_thresholds (&procs_thresholds, warning_range, critical_range);
514 return validate_arguments ();
515 }
519 int
520 validate_arguments ()
521 {
522 if (options == 0)
523 options = ALL;
525 if (statopts==NULL)
526 statopts = strdup("");
528 if (prog==NULL)
529 prog = strdup("");
531 if (args==NULL)
532 args = strdup("");
534 if (fmt==NULL)
535 fmt = strdup("");
537 if (fails==NULL)
538 fails = strdup("");
540 return options;
541 }
544 /* convert the elapsed time to seconds */
545 int
546 convert_to_seconds(char *etime) {
548 char *ptr;
549 int total;
551 int hyphcnt;
552 int coloncnt;
553 int days;
554 int hours;
555 int minutes;
556 int seconds;
558 hyphcnt = 0;
559 coloncnt = 0;
560 days = 0;
561 hours = 0;
562 minutes = 0;
563 seconds = 0;
565 for (ptr = etime; *ptr != '\0'; ptr++) {
567 if (*ptr == '-') {
568 hyphcnt++;
569 continue;
570 }
571 if (*ptr == ':') {
572 coloncnt++;
573 continue;
574 }
575 }
577 if (hyphcnt > 0) {
578 sscanf(etime, "%d-%d:%d:%d",
579 &days, &hours, &minutes, &seconds);
580 /* linux 2.6.5/2.6.6 reporting some processes with infinite
581 * elapsed times for some reason */
582 if (days == 49710) {
583 return 0;
584 }
585 } else {
586 if (coloncnt == 2) {
587 sscanf(etime, "%d:%d:%d",
588 &hours, &minutes, &seconds);
589 } else if (coloncnt == 1) {
590 sscanf(etime, "%d:%d",
591 &minutes, &seconds);
592 }
593 }
595 total = (days * 86400) +
596 (hours * 3600) +
597 (minutes * 60) +
598 seconds;
600 if (verbose >= 3 && metric == METRIC_ELAPSED) {
601 printf("seconds: %d\n", total);
602 }
603 return total;
604 }
607 void
608 print_help (void)
609 {
610 print_revision (progname, NP_VERSION);
612 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
613 printf (COPYRIGHT, copyright, email);
615 printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified"));
616 printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number"));
617 printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check."));
619 printf ("\n\n");
621 print_usage ();
623 printf (UT_HELP_VRSN);
624 printf (UT_EXTRA_OPTS);
625 printf (" %s\n", "-w, --warning=RANGE");
626 printf (" %s\n", _("Generate warning state if metric is outside this range"));
627 printf (" %s\n", "-c, --critical=RANGE");
628 printf (" %s\n", _("Generate critical state if metric is outside this range"));
629 printf (" %s\n", "-m, --metric=TYPE");
630 printf (" %s\n", _("Check thresholds against metric. Valid types:"));
631 printf (" %s\n", _("PROCS - number of processes (default)"));
632 printf (" %s\n", _("VSZ - virtual memory size"));
633 printf (" %s\n", _("RSS - resident set memory size"));
634 printf (" %s\n", _("CPU - percentage CPU"));
635 /* only linux etime is support currently */
636 #if defined( __linux__ )
637 printf (" %s\n", _("ELAPSED - time elapsed in seconds"));
638 #endif /* defined(__linux__) */
639 printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
641 printf (" %s\n", "-v, --verbose");
642 printf (" %s\n", _("Extra information. Up to 3 verbosity levels"));
644 printf ("\n");
645 printf ("%s\n", "Filters:");
646 printf (" %s\n", "-s, --state=STATUSFLAGS");
647 printf (" %s\n", _("Only scan for processes that have, in the output of `ps`, one or"));
648 printf (" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,"));
649 printf (" %s\n", _("RSZDT, plus others based on the output of your 'ps' command)."));
650 printf (" %s\n", "-p, --ppid=PPID");
651 printf (" %s\n", _("Only scan for children of the parent process ID indicated."));
652 printf (" %s\n", "-z, --vsz=VSZ");
653 printf (" %s\n", _("Only scan for processes with VSZ higher than indicated."));
654 printf (" %s\n", "-r, --rss=RSS");
655 printf (" %s\n", _("Only scan for processes with RSS higher than indicated."));
656 printf (" %s\n", "-P, --pcpu=PCPU");
657 printf (" %s\n", _("Only scan for processes with PCPU higher than indicated."));
658 printf (" %s\n", "-u, --user=USER");
659 printf (" %s\n", _("Only scan for processes with user name or ID indicated."));
660 printf (" %s\n", "-a, --argument-array=STRING");
661 printf (" %s\n", _("Only scan for processes with args that contain STRING."));
662 printf (" %s\n", "--ereg-argument-array=STRING");
663 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING."));
664 printf (" %s\n", "-C, --command=COMMAND");
665 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
667 printf(_("\n\
668 RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
669 specified 'max:min', a warning status will be generated if the\n\
670 count is inside the specified range\n\n"));
672 printf(_("\
673 This plugin checks the number of currently running processes and\n\
674 generates WARNING or CRITICAL states if the process count is outside\n\
675 the specified threshold ranges. The process count can be filtered by\n\
676 process owner, parent process PID, current state (e.g., 'Z'), or may\n\
677 be the total number of running processes\n\n"));
679 printf ("%s\n", _("Examples:"));
680 printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry");
681 printf (" %s\n", _("Warning if not two processes with command name portsentry."));
682 printf (" %s\n\n", _("Critical if < 2 or > 1024 processes"));
683 printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root");
684 printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing"));
685 printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root"));
686 printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ");
687 printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K"));
688 printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU");
689 printf (" %s\n", _("Alert if CPU of any processes over 10%% or 20%%"));
691 printf (UT_SUPPORT);
692 }
694 void
695 print_usage (void)
696 {
697 printf ("%s\n", _("Usage:"));
698 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
699 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
700 printf (" [-C command] [-t timeout] [-v]\n");
701 }