1 /*****************************************************************************
3 * Monitoring check_procs plugin
6 * Copyright (c) 2000-2024 Monitoring Plugins Development Team
10 * This file contains the check_procs plugin
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.
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.
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
23 * the Free Software Foundation, either version 3 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
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/>.
35 *****************************************************************************/
37 const char *progname
= "check_procs";
38 const char *program_name
= "check_procs"; /* Required for coreutils libs */
39 const char *copyright
= "2000-2024";
40 const char *email
= "devel@monitoring-plugins.org";
44 #include "utils_cmd.h"
50 #ifdef HAVE_SYS_STAT_H
54 int process_arguments (int, char **);
55 int validate_arguments (void);
56 int convert_to_seconds (char *);
57 void print_help (void);
58 void print_usage (void);
60 char *warning_range
= NULL
;
61 char *critical_range
= NULL
;
62 thresholds
*procs_thresholds
= NULL
;
64 int options
= 0; /* bitmask of filter criteria to test against */
75 #define EREG_ARGS 1024
76 #define EXCLUDE_PROGS 2048
78 #define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
79 ppid of procs are compared to pid of this proc*/
81 /* Different metrics */
90 enum metric metric
= METRIC_PROCS
;
101 char **exclude_progs_arr
= NULL
;
102 char exclude_progs_counter
= 0;
104 char *input_filename
= NULL
;
108 char tmp
[MAX_INPUT_BUFFER
];
109 int kthread_filter
= 0;
110 int usepid
= 0; /* whether to test for pid or /proc/pid/exe */
112 FILE *ps_input
= NULL
;
115 stat_exe (const pid_t pid
, struct stat
*buf
) {
118 xasprintf(&path
, "/proc/%d/exe", pid
);
119 ret
= stat(path
, buf
);
126 main (int argc
, char **argv
)
140 pid_t kthread_ppid
= 0;
146 char procetime
[MAX_INPUT_BUFFER
] = { '\0' };
149 const char *zombie
= "Z";
151 int resultsum
= 0; /* bitmask of the filter criteria met by a process */
152 int found
= 0; /* counter for number of lines returned in `ps` output */
153 int procs
= 0; /* counter for number of processes meeting filter criteria */
154 int pos
; /* number of spaces before 'args' in `ps` output */
155 int cols
; /* number of columns in ps output */
156 int expected_cols
= PS_COLS
- 1;
157 int warn
= 0; /* number of processes in warn state */
158 int crit
= 0; /* number of processes in crit state */
160 int result
= STATE_UNKNOWN
;
162 output chld_out
, chld_err
;
164 setlocale (LC_ALL
, "");
165 bindtextdomain (PACKAGE
, LOCALEDIR
);
166 textdomain (PACKAGE
);
167 setlocale(LC_NUMERIC
, "POSIX");
169 input_buffer
= malloc (MAX_INPUT_BUFFER
);
170 procprog
= malloc (MAX_INPUT_BUFFER
);
172 xasprintf (&metric_name
, "PROCS");
173 metric
= METRIC_PROCS
;
175 /* Parse extra opts if any */
176 argv
=np_extra_opts (&argc
, argv
, progname
);
178 if (process_arguments (argc
, argv
) == ERROR
)
179 usage4 (_("Could not parse arguments"));
184 if (usepid
|| stat_exe(mypid
, &statbuf
) == -1) {
185 /* usepid might have been set by -T */
189 mydev
= statbuf
.st_dev
;
190 myino
= statbuf
.st_ino
;
193 /* Set signal handling and alarm timeout */
194 if (signal (SIGALRM
, timeout_alarm_handler
) == SIG_ERR
) {
195 die (STATE_UNKNOWN
, _("Cannot catch SIGALRM"));
197 (void) alarm ((unsigned) timeout_interval
);
200 printf (_("CMD: %s\n"), PS_COMMAND
);
202 if (input_filename
== NULL
) {
203 result
= cmd_run( PS_COMMAND
, &chld_out
, &chld_err
, 0);
204 if (chld_err
.lines
> 0) {
205 printf ("%s: %s", _("System call sent warnings to stderr"), chld_err
.line
[0]);
209 result
= cmd_file_read( input_filename
, &chld_out
, 0);
212 /* flush first line: j starts at 1 */
213 for (size_t j
= 1; j
< chld_out
.lines
; j
++) {
214 input_line
= chld_out
.line
[j
];
217 printf ("%s", input_line
);
219 strcpy (procprog
, "");
220 xasprintf (&procargs
, "%s", "");
222 cols
= sscanf (input_line
, PS_FORMAT
, PS_VARLIST
);
224 /* Zombie processes do not give a procprog command */
225 if ( cols
< expected_cols
&& strstr(procstat
, zombie
) ) {
226 cols
= expected_cols
;
228 if ( cols
>= expected_cols
) {
230 xasprintf (&procargs
, "%s", input_line
+ pos
);
233 /* Some ps return full pathname for command. This removes path */
234 strcpy(procprog
, base_name(procprog
));
236 /* we need to convert the elapsed time to seconds */
237 procseconds
= convert_to_seconds(procetime
);
240 printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
241 procs
, procuid
, procvsz
, procrss
,
242 procpid
, procppid
, procpcpu
, procstat
,
243 procetime
, procprog
, procargs
);
246 if ((usepid
&& mypid
== procpid
) ||
247 ( ((!usepid
) && ((ret
= stat_exe(procpid
, &statbuf
) != -1) && statbuf
.st_dev
== mydev
&& statbuf
.st_ino
== myino
)) ||
248 (ret
== -1 && errno
== ENOENT
))
251 printf("not considering - is myself or gone\n");
255 else if (myppid
== procpid
) {
257 printf("not considering - is parent\n");
261 /* Ignore our own children */
262 if (procppid
== mypid
) {
264 printf("not considering - is our child\n");
268 /* Ignore excluded processes by name */
269 if(options
& EXCLUDE_PROGS
) {
273 for(i
=0; i
< (exclude_progs_counter
); i
++) {
274 if(!strcmp(procprog
, exclude_progs_arr
[i
])) {
279 resultsum
|= EXCLUDE_PROGS
;
283 printf("excluding - by ignorelist\n");
287 /* filter kernel threads (children of KTHREAD_PARENT)*/
288 /* TODO adapt for other OSes than GNU/Linux
289 sorry for not doing that, but I've no other OSes to test :-( */
290 if (kthread_filter
== 1) {
291 /* get pid KTHREAD_PARENT */
292 if (kthread_ppid
== 0 && !strcmp(procprog
, KTHREAD_PARENT
) )
293 kthread_ppid
= procpid
;
295 if (kthread_ppid
== procppid
) {
297 printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid
, procppid
, procprog
, procargs
);
302 if ((options
& STAT
) && (strstr (procstat
, statopts
)))
304 if ((options
& ARGS
) && procargs
&& (strstr (procargs
, args
) != NULL
))
306 if ((options
& EREG_ARGS
) && procargs
&& (regexec(&re_args
, procargs
, (size_t) 0, NULL
, 0) == 0))
307 resultsum
|= EREG_ARGS
;
308 if ((options
& PROG
) && procprog
&& (strcmp (prog
, procprog
) == 0))
310 if ((options
& PPID
) && (procppid
== ppid
))
312 if ((options
& USER
) && (procuid
== uid
))
314 if ((options
& VSZ
) && (procvsz
>= vsz
))
316 if ((options
& RSS
) && (procrss
>= rss
))
318 if ((options
& PCPU
) && (procpcpu
>= pcpu
))
323 /* Next line if filters not matched */
324 if (!(options
== resultsum
|| options
== ALL
))
329 printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
330 procuid
, procvsz
, procrss
,
331 procpid
, procppid
, procpcpu
, procstat
,
332 procetime
, procprog
, procargs
);
335 if (metric
== METRIC_VSZ
)
336 i
= get_status ((double)procvsz
, procs_thresholds
);
337 else if (metric
== METRIC_RSS
)
338 i
= get_status ((double)procrss
, procs_thresholds
);
339 /* TODO? float thresholds for --metric=CPU */
340 else if (metric
== METRIC_CPU
)
341 i
= get_status (procpcpu
, procs_thresholds
);
342 else if (metric
== METRIC_ELAPSED
)
343 i
= get_status ((double)procseconds
, procs_thresholds
);
345 if (metric
!= METRIC_PROCS
) {
346 if (i
== STATE_WARNING
) {
348 xasprintf (&fails
, "%s%s%s", fails
, (strcmp(fails
,"") ? ", " : ""), procprog
);
349 result
= max_state (result
, i
);
351 if (i
== STATE_CRITICAL
) {
353 xasprintf (&fails
, "%s%s%s", fails
, (strcmp(fails
,"") ? ", " : ""), procprog
);
354 result
= max_state (result
, i
);
358 /* This should not happen */
360 printf(_("Not parseable: %s"), input_buffer
);
364 if (found
== 0) { /* no process lines parsed so return STATE_UNKNOWN */
365 printf (_("Unable to read output\n"));
366 return STATE_UNKNOWN
;
369 if ( result
== STATE_UNKNOWN
)
372 /* Needed if procs found, but none match filter */
373 if ( metric
== METRIC_PROCS
) {
374 result
= max_state (result
, get_status ((double)procs
, procs_thresholds
) );
377 if ( result
== STATE_OK
) {
378 printf ("%s %s: ", metric_name
, _("OK"));
379 } else if (result
== STATE_WARNING
) {
380 printf ("%s %s: ", metric_name
, _("WARNING"));
381 if ( metric
!= METRIC_PROCS
) {
382 printf (_("%d warn out of "), warn
);
384 } else if (result
== STATE_CRITICAL
) {
385 printf ("%s %s: ", metric_name
, _("CRITICAL"));
386 if (metric
!= METRIC_PROCS
) {
387 printf (_("%d crit, %d warn out of "), crit
, warn
);
390 printf (ngettext ("%d process", "%d processes", (unsigned long) procs
), procs
);
392 if (strcmp(fmt
,"") != 0) {
393 printf (_(" with %s"), fmt
);
396 if ( verbose
>= 1 && strcmp(fails
,"") )
397 printf (" [%s]", fails
);
399 if (metric
== METRIC_PROCS
)
400 printf (" | procs=%d;%s;%s;0;", procs
,
401 warning_range
? warning_range
: "",
402 critical_range
? critical_range
: "");
404 printf (" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs
, warn
, crit
);
412 /* process command-line arguments */
414 process_arguments (int argc
, char **argv
)
421 int cflags
= REG_NOSUB
| REG_EXTENDED
;
422 char errbuf
[MAX_INPUT_BUFFER
];
425 static struct option longopts
[] = {
426 {"warning", required_argument
, 0, 'w'},
427 {"critical", required_argument
, 0, 'c'},
428 {"metric", required_argument
, 0, 'm'},
429 {"timeout", required_argument
, 0, 't'},
430 {"status", required_argument
, 0, 's'},
431 {"ppid", required_argument
, 0, 'p'},
432 {"user", required_argument
, 0, 'u'},
433 {"command", required_argument
, 0, 'C'},
434 {"vsz", required_argument
, 0, 'z'},
435 {"rss", required_argument
, 0, 'r'},
436 {"pcpu", required_argument
, 0, 'P'},
437 {"elapsed", required_argument
, 0, 'e'},
438 {"argument-array", required_argument
, 0, 'a'},
439 {"help", no_argument
, 0, 'h'},
440 {"version", no_argument
, 0, 'V'},
441 {"verbose", no_argument
, 0, 'v'},
442 {"ereg-argument-array", required_argument
, 0, CHAR_MAX
+1},
443 {"input-file", required_argument
, 0, CHAR_MAX
+2},
444 {"no-kthreads", required_argument
, 0, 'k'},
445 {"traditional-filter", no_argument
, 0, 'T'},
446 {"exclude-process", required_argument
, 0, 'X'},
450 for (c
= 1; c
< argc
; c
++)
451 if (strcmp ("-to", argv
[c
]) == 0)
452 strcpy (argv
[c
], "-t");
455 c
= getopt_long (argc
, argv
, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:",
458 if (c
== -1 || c
== EOF
)
466 exit (STATE_UNKNOWN
);
467 case 'V': /* version */
468 print_revision (progname
, NP_VERSION
);
469 exit (STATE_UNKNOWN
);
470 case 't': /* timeout period */
471 if (!is_integer (optarg
))
472 usage2 (_("Timeout interval must be a positive integer"), optarg
);
474 timeout_interval
= atoi (optarg
);
476 case 'c': /* critical threshold */
477 critical_range
= optarg
;
479 case 'w': /* warning threshold */
480 warning_range
= optarg
;
482 case 'p': /* process id */
483 if (sscanf (optarg
, "%d%[^0-9]", &ppid
, tmp
) == 1) {
484 xasprintf (&fmt
, "%s%sPPID = %d", (fmt
? fmt
: "") , (options
? ", " : ""), ppid
);
488 usage4 (_("Parent Process ID must be an integer!"));
489 case 's': /* status */
494 xasprintf (&fmt
, _("%s%sSTATE = %s"), (fmt
? fmt
: ""), (options
? ", " : ""), statopts
);
497 case 'u': /* user or user id */
498 if (is_integer (optarg
)) {
500 pw
= getpwuid ((uid_t
) uid
);
501 /* check to be sure user exists */
503 usage2 (_("UID was not found"), optarg
);
506 pw
= getpwnam (optarg
);
507 /* check to be sure user exists */
509 usage2 (_("User name was not found"), optarg
);
514 xasprintf (&fmt
, "%s%sUID = %d (%s)", (fmt
? fmt
: ""), (options
? ", " : ""),
518 case 'C': /* command */
519 /* TODO: allow this to be passed in with --metric */
524 xasprintf (&fmt
, _("%s%scommand name '%s'"), (fmt
? fmt
: ""), (options
? ", " : ""),
532 exclude_progs
= optarg
;
533 xasprintf (&fmt
, _("%s%sexclude progs '%s'"), (fmt
? fmt
: ""), (options
? ", " : ""),
535 char *p
= strtok(exclude_progs
, ",");
538 exclude_progs_arr
= realloc(exclude_progs_arr
, sizeof(char*) * ++exclude_progs_counter
);
539 exclude_progs_arr
[exclude_progs_counter
-1] = p
;
540 p
= strtok(NULL
, ",");
543 options
|= EXCLUDE_PROGS
;
545 case 'a': /* args (full path name with args) */
546 /* TODO: allow this to be passed in with --metric */
551 xasprintf (&fmt
, "%s%sargs '%s'", (fmt
? fmt
: ""), (options
? ", " : ""), args
);
555 err
= regcomp(&re_args
, optarg
, cflags
);
557 regerror (err
, &re_args
, errbuf
, MAX_INPUT_BUFFER
);
558 die (STATE_UNKNOWN
, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf
);
560 /* Strip off any | within the regex optarg */
561 temp_string
= strdup(optarg
);
562 while(temp_string
[i
]!='\0'){
563 if(temp_string
[i
]=='|')
567 xasprintf (&fmt
, "%s%sregex args '%s'", (fmt
? fmt
: ""), (options
? ", " : ""), temp_string
);
568 options
|= EREG_ARGS
;
571 if (sscanf (optarg
, "%d%[^0-9]", &rss
, tmp
) == 1) {
572 xasprintf (&fmt
, "%s%sRSS >= %d", (fmt
? fmt
: ""), (options
? ", " : ""), rss
);
576 usage4 (_("RSS must be an integer!"));
578 if (sscanf (optarg
, "%d%[^0-9]", &vsz
, tmp
) == 1) {
579 xasprintf (&fmt
, "%s%sVSZ >= %d", (fmt
? fmt
: ""), (options
? ", " : ""), vsz
);
583 usage4 (_("VSZ must be an integer!"));
585 /* TODO: -P 1.5.5 is accepted */
586 if (sscanf (optarg
, "%f%[^0-9.]", &pcpu
, tmp
) == 1) {
587 xasprintf (&fmt
, "%s%sPCPU >= %.2f", (fmt
? fmt
: ""), (options
? ", " : ""), pcpu
);
591 usage4 (_("PCPU must be a float!"));
593 xasprintf (&metric_name
, "%s", optarg
);
594 if ( strcmp(optarg
, "PROCS") == 0) {
595 metric
= METRIC_PROCS
;
598 else if ( strcmp(optarg
, "VSZ") == 0) {
602 else if ( strcmp(optarg
, "RSS") == 0 ) {
606 else if ( strcmp(optarg
, "CPU") == 0 ) {
610 else if ( strcmp(optarg
, "ELAPSED") == 0) {
611 metric
= METRIC_ELAPSED
;
615 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
616 case 'k': /* linux kernel thread filter */
619 case 'v': /* command */
626 input_filename
= optarg
;
632 if ((! warning_range
) && argv
[c
])
633 warning_range
= argv
[c
++];
634 if ((! critical_range
) && argv
[c
])
635 critical_range
= argv
[c
++];
636 if (statopts
== NULL
&& argv
[c
]) {
637 xasprintf (&statopts
, "%s", argv
[c
++]);
638 xasprintf (&fmt
, _("%s%sSTATE = %s"), (fmt
? fmt
: ""), (options
? ", " : ""), statopts
);
642 /* this will abort in case of invalid ranges */
643 set_thresholds (&procs_thresholds
, warning_range
, critical_range
);
645 return validate_arguments ();
651 validate_arguments ()
657 statopts
= strdup("");
675 /* convert the elapsed time to seconds */
677 convert_to_seconds(char *etime
) {
696 for (ptr
= etime
; *ptr
!= '\0'; ptr
++) {
709 sscanf(etime
, "%d-%d:%d:%d",
710 &days
, &hours
, &minutes
, &seconds
);
711 /* linux 2.6.5/2.6.6 reporting some processes with infinite
712 * elapsed times for some reason */
718 sscanf(etime
, "%d:%d:%d",
719 &hours
, &minutes
, &seconds
);
720 } else if (coloncnt
== 1) {
721 sscanf(etime
, "%d:%d",
726 total
= (days
* 86400) +
731 if (verbose
>= 3 && metric
== METRIC_ELAPSED
) {
732 printf("seconds: %d\n", total
);
741 print_revision (progname
, NP_VERSION
);
743 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
744 printf (COPYRIGHT
, copyright
, email
);
746 printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified"));
747 printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number"));
748 printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check."));
752 printf ("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)"));
753 printf ("%s\n", _("are excluded from any checks to prevent false positives."));
759 printf (UT_HELP_VRSN
);
760 printf (UT_EXTRA_OPTS
);
761 printf (" %s\n", "-w, --warning=RANGE");
762 printf (" %s\n", _("Generate warning state if metric is outside this range"));
763 printf (" %s\n", "-c, --critical=RANGE");
764 printf (" %s\n", _("Generate critical state if metric is outside this range"));
765 printf (" %s\n", "-m, --metric=TYPE");
766 printf (" %s\n", _("Check thresholds against metric. Valid types:"));
767 printf (" %s\n", _("PROCS - number of processes (default)"));
768 printf (" %s\n", _("VSZ - virtual memory size"));
769 printf (" %s\n", _("RSS - resident set memory size"));
770 printf (" %s\n", _("CPU - percentage CPU"));
771 /* only linux etime is support currently */
772 #if defined( __linux__ )
773 printf (" %s\n", _("ELAPSED - time elapsed in seconds"));
774 #endif /* defined(__linux__) */
775 printf (UT_PLUG_TIMEOUT
, DEFAULT_SOCKET_TIMEOUT
);
777 printf (" %s\n", "-v, --verbose");
778 printf (" %s\n", _("Extra information. Up to 3 verbosity levels"));
780 printf (" %s\n", "-T, --traditional");
781 printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe"));
784 printf ("%s\n", "Filters:");
785 printf (" %s\n", "-s, --state=STATUSFLAGS");
786 printf (" %s\n", _("Only scan for processes that have, in the output of `ps`, one or"));
787 printf (" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,"));
788 printf (" %s\n", _("RSZDT, plus others based on the output of your 'ps' command)."));
789 printf (" %s\n", "-p, --ppid=PPID");
790 printf (" %s\n", _("Only scan for children of the parent process ID indicated."));
791 printf (" %s\n", "-z, --vsz=VSZ");
792 printf (" %s\n", _("Only scan for processes with VSZ higher than indicated."));
793 printf (" %s\n", "-r, --rss=RSS");
794 printf (" %s\n", _("Only scan for processes with RSS higher than indicated."));
795 printf (" %s\n", "-P, --pcpu=PCPU");
796 printf (" %s\n", _("Only scan for processes with PCPU higher than indicated."));
797 printf (" %s\n", "-u, --user=USER");
798 printf (" %s\n", _("Only scan for processes with user name or ID indicated."));
799 printf (" %s\n", "-a, --argument-array=STRING");
800 printf (" %s\n", _("Only scan for processes with args that contain STRING."));
801 printf (" %s\n", "--ereg-argument-array=STRING");
802 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING."));
803 printf (" %s\n", "-C, --command=COMMAND");
804 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
805 printf (" %s\n", "-X, --exclude-process");
806 printf (" %s\n", _("Exclude processes which match this comma separated list"));
807 printf (" %s\n", "-k, --no-kthreads");
808 printf (" %s\n", _("Only scan for non kernel threads (works on Linux only)."));
811 RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
812 specified 'max:min', a warning status will be generated if the\n\
813 count is inside the specified range\n\n"));
816 This plugin checks the number of currently running processes and\n\
817 generates WARNING or CRITICAL states if the process count is outside\n\
818 the specified threshold ranges. The process count can be filtered by\n\
819 process owner, parent process PID, current state (e.g., 'Z'), or may\n\
820 be the total number of running processes\n\n"));
822 printf ("%s\n", _("Examples:"));
823 printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry");
824 printf (" %s\n", _("Warning if not two processes with command name portsentry."));
825 printf (" %s\n\n", _("Critical if < 2 or > 1024 processes"));
826 printf (" %s\n", "check_procs -c 1: -C sshd");
827 printf (" %s\n", _("Critical if not at least 1 process with command sshd"));
828 printf (" %s\n", "check_procs -w 1024 -c 1: -C sshd");
829 printf (" %s\n", _("Warning if > 1024 processes with command name sshd."));
830 printf (" %s\n\n", _("Critical if < 1 processes with command name sshd."));
831 printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root");
832 printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing"));
833 printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root"));
834 printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ");
835 printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K"));
836 printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU");
837 printf (" %s\n", _("Alert if CPU of any processes over 10\% or 20\%"));
845 printf ("%s\n", _("Usage:"));
846 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname
);
847 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
848 printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n");