Code

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