Code

remove UT_HLP_VRS from print_usage
[nagiosplug.git] / plugins / check_procs.c
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$
18  
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         int procuid = 0;
89         int procppid = 0;
90         int procvsz = 0;
91         int procrss = 0;
92         int procseconds = 0;
93         float procpcpu = 0;
94         char procstat[8];
95         char procetime[MAX_INPUT_BUFFER];
96         char *procargs;
97         char *temp_string;
99         const char *zombie = "Z";
101         int resultsum = 0; /* bitmask of the filter criteria met by a process */
102         int found = 0; /* counter for number of lines returned in `ps` output */
103         int procs = 0; /* counter for number of processes meeting filter criteria */
104         int pos; /* number of spaces before 'args' in `ps` output */
105         int cols; /* number of columns in ps output */
106         int expected_cols = PS_COLS - 1;
107         int warn = 0; /* number of processes in warn state */
108         int crit = 0; /* number of processes in crit state */
109         int i = 0;
111         int result = STATE_UNKNOWN;
113         setlocale (LC_ALL, "");
114         bindtextdomain (PACKAGE, LOCALEDIR);
115         textdomain (PACKAGE);
117         input_buffer = malloc (MAX_INPUT_BUFFER);
118         procprog = malloc (MAX_INPUT_BUFFER);
120         asprintf (&metric_name, "PROCS");
121         metric = METRIC_PROCS;
123         if (process_arguments (argc, argv) != TRUE)
124                 usage4 (_("Could not parse arguments"));
126         /* Set signal handling and alarm timeout */
127         if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
128                 usage4 (_("Cannot catch SIGALRM"));
129         }
130         alarm (timeout_interval);
132         if (verbose >= 2)
133                 printf (_("CMD: %s\n"), PS_COMMAND);
135         child_process = spopen (PS_COMMAND);
136         if (child_process == NULL) {
137                 printf (_("Could not open pipe: %s\n"), PS_COMMAND);
138                 return STATE_UNKNOWN;
139         }
141         child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
142         if (child_stderr == NULL)
143                 printf (_("Could not open stderr for %s\n"), PS_COMMAND);
145         /* flush first line */
146         fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
147         while ( input_buffer[strlen(input_buffer)-1] != '\n' )
148                 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
150         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
151                 asprintf (&input_line, "%s", input_buffer);
152                 while ( input_buffer[strlen(input_buffer)-1] != '\n' ) {
153                         fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
154                         asprintf (&input_line, "%s%s", input_line, input_buffer);
155                 }
157                 if (verbose >= 3)
158                         printf ("%s", input_line);
160                 strcpy (procprog, "");
161                 asprintf (&procargs, "%s", "");
163                 cols = sscanf (input_line, PS_FORMAT, PS_VARLIST);
165                 /* Zombie processes do not give a procprog command */
166                 if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) {
167                         cols = expected_cols;
168                 }
169                 if ( cols >= expected_cols ) {
170                         resultsum = 0;
171                         asprintf (&procargs, "%s", input_line + pos);
172                         strip (procargs);
174                         /* Some ps return full pathname for command. This removes path */
175                         temp_string = strtok ((char *)procprog, "/");
176                         while (temp_string) {
177                                 strcpy(procprog, temp_string);
178                                 temp_string = strtok (NULL, "/");
179                         }
181                         /* we need to convert the elapsed time to seconds */
182                         procseconds = convert_to_seconds(procetime);
184                         if (verbose >= 3)
185                                 printf ("%d %d %d %d %d %.2f %s %s %s %s\n", 
186                                         procs, procuid, procvsz, procrss,
187                                         procppid, procpcpu, procstat, 
188                                         procetime, procprog, procargs);
190                         /* Ignore self */
191                         if (strcmp (procprog, progname) == 0) {
192                                 continue;
193                         }
195                         if ((options & STAT) && (strstr (statopts, procstat)))
196                                 resultsum |= STAT;
197                         if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
198                                 resultsum |= ARGS;
199                         if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0))
200                                 resultsum |= PROG;
201                         if ((options & PPID) && (procppid == ppid))
202                                 resultsum |= PPID;
203                         if ((options & USER) && (procuid == uid))
204                                 resultsum |= USER;
205                         if ((options & VSZ)  && (procvsz >= vsz))
206                                 resultsum |= VSZ;
207                         if ((options & RSS)  && (procrss >= rss))
208                                 resultsum |= RSS;
209                         if ((options & PCPU)  && (procpcpu >= pcpu))
210                                 resultsum |= PCPU;
212                         found++;
214                         /* Next line if filters not matched */
215                         if (!(options == resultsum || options == ALL))
216                                 continue;
218                         procs++;
220                         if (metric == METRIC_VSZ)
221                                 i = check_thresholds (procvsz);
222                         else if (metric == METRIC_RSS)
223                                 i = check_thresholds (procrss);
224                         /* TODO? float thresholds for --metric=CPU */
225                         else if (metric == METRIC_CPU)
226                                 i = check_thresholds ((int)procpcpu); 
227                         else if (metric == METRIC_ELAPSED)
228                                 i = check_thresholds (procseconds);
230                         if (metric != METRIC_PROCS) {
231                                 if (i == STATE_WARNING) {
232                                         warn++;
233                                         asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
234                                         result = max_state (result, i);
235                                 }
236                                 if (i == STATE_CRITICAL) {
237                                         crit++;
238                                         asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
239                                         result = max_state (result, i);
240                                 }
241                         }
242                 } 
243                 /* This should not happen */
244                 else if (verbose) {
245                         printf(_("Not parseable: %s"), input_buffer);
246                 }
247         }
249         /* If we get anything on STDERR, at least set warning */
250         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
251                 if (verbose)
252                         printf (_("STDERR: %s"), input_buffer);
253                 result = max_state (result, STATE_WARNING);
254                 printf (_("System call sent warnings to stderr\n"));
255         }
256         
257         (void) fclose (child_stderr);
259         /* close the pipe */
260         if (spclose (child_process)) {
261                 printf (_("System call returned nonzero status\n"));
262                 result = max_state (result, STATE_WARNING);
263         }
265         if (found == 0) {                                                       /* no process lines parsed so return STATE_UNKNOWN */
266                 printf (_("Unable to read output\n"));
267                 return result;
268         }
270         if ( result == STATE_UNKNOWN ) 
271                 result = STATE_OK;
273         /* Needed if procs found, but none match filter */
274         if ( metric == METRIC_PROCS ) {
275                 result = max_state (result, check_thresholds (procs) );
276         }
278         if ( result == STATE_OK ) {
279                 printf ("%s %s: ", metric_name, _("OK"));
280         } else if (result == STATE_WARNING) {
281                 printf ("%s %s: ", metric_name, _("WARNING"));
282                 if ( metric != METRIC_PROCS ) {
283                         printf (_("%d warn out of "), warn);
284                 }
285         } else if (result == STATE_CRITICAL) {
286                 printf ("%s %s: ", metric_name, _("CRITICAL"));
287                 if (metric != METRIC_PROCS) {
288                         printf (_("%d crit, %d warn out of "), crit, warn);
289                 }
290         } 
291         printf ("%d %s", procs, procs == 1 ? _("process") : _("processes"));
292         
293         if (strcmp(fmt,"") != 0) {
294                 printf (_(" with %s"), fmt);
295         }
297         if ( verbose >= 1 && strcmp(fails,"") )
298                 printf (" [%s]", fails);
300         printf ("\n");
301         return result;
306 /* process command-line arguments */
307 int
308 process_arguments (int argc, char **argv)
310         int c = 1;
311         char *user;
312         struct passwd *pw;
313         int option = 0;
314         static struct option longopts[] = {
315                 {"warning", required_argument, 0, 'w'},
316                 {"critical", required_argument, 0, 'c'},
317                 {"metric", required_argument, 0, 'm'},
318                 {"timeout", required_argument, 0, 't'},
319                 {"status", required_argument, 0, 's'},
320                 {"ppid", required_argument, 0, 'p'},
321                 {"command", required_argument, 0, 'C'},
322                 {"vsz", required_argument, 0, 'z'},
323                 {"rss", required_argument, 0, 'r'},
324                 {"pcpu", required_argument, 0, 'P'},
325                 {"elapsed", required_argument, 0, 'e'},
326                 {"argument-array", required_argument, 0, 'a'},
327                 {"help", no_argument, 0, 'h'},
328                 {"version", no_argument, 0, 'V'},
329                 {"verbose", no_argument, 0, 'v'},
330                 {0, 0, 0, 0}
331         };
333         for (c = 1; c < argc; c++)
334                 if (strcmp ("-to", argv[c]) == 0)
335                         strcpy (argv[c], "-t");
337         while (1) {
338                 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:", 
339                         longopts, &option);
341                 if (c == -1 || c == EOF)
342                         break;
344                 switch (c) {
345                 case '?':                                                                       /* help */
346                         printf (_("%s: Unknown argument: %s\n\n"), progname, optarg);
347                         print_usage ();
348                         exit (STATE_UNKNOWN);
349                 case 'h':                                                                       /* help */
350                         print_help ();
351                         exit (STATE_OK);
352                 case 'V':                                                                       /* version */
353                         print_revision (progname, revision);
354                         exit (STATE_OK);
355                 case 't':                                                                       /* timeout period */
356                         if (!is_integer (optarg))
357                                 usage2 (_("Timeout interval must be a positive integer"), optarg);
358                         else
359                                 timeout_interval = atoi (optarg);
360                         break;
361                 case 'c':                                                                       /* critical threshold */
362                         if (is_integer (optarg))
363                                 cmax = atoi (optarg);
364                         else if (sscanf (optarg, ":%d", &cmax) == 1)
365                                 break;
366                         else if (sscanf (optarg, "%d:%d", &cmin, &cmax) == 2)
367                                 break;
368                         else if (sscanf (optarg, "%d:", &cmin) == 1)
369                                 break;
370                         else
371                                 usage (_("Critical Process Count must be an integer!\n\n"));
372                         break;                                                   
373                 case 'w':                                                                       /* warning threshold */
374                         if (is_integer (optarg))
375                                 wmax = atoi (optarg);
376                         else if (sscanf (optarg, ":%d", &wmax) == 1)
377                                 break;
378                         else if (sscanf (optarg, "%d:%d", &wmin, &wmax) == 2)
379                                 break;
380                         else if (sscanf (optarg, "%d:", &wmin) == 1)
381                                 break;
382                         else
383                                 usage (_("Warning Process Count must be an integer!\n\n"));
384                         break;
385                 case 'p':                                                                       /* process id */
386                         if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) {
387                                 asprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid);
388                                 options |= PPID;
389                                 break;
390                         }
391                         usage2 (_("%s: Parent Process ID must be an integer!\n\n"),  progname);
392                 case 's':                                                                       /* status */
393                         if (statopts)
394                                 break;
395                         else
396                                 statopts = optarg;
397                         asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
398                         options |= STAT;
399                         break;
400                 case 'u':                                                                       /* user or user id */
401                         if (is_integer (optarg)) {
402                                 uid = atoi (optarg);
403                                 pw = getpwuid ((uid_t) uid);
404                                 /*  check to be sure user exists */
405                                 if (pw == NULL)
406                                         usage2 (_("UID %s was not found\n"), optarg);
407                         }
408                         else {
409                                 pw = getpwnam (optarg);
410                                 /*  check to be sure user exists */
411                                 if (pw == NULL)
412                                         usage2 (_("User name %s was not found\n"), optarg);
413                                 /*  then get uid */
414                                 uid = pw->pw_uid;
415                         }
416                         user = pw->pw_name;
417                         asprintf (&fmt, _("%s%sUID = %d (%s)"), (fmt ? fmt : ""), (options ? ", " : ""),
418                                   uid, user);
419                         options |= USER;
420                         break;
421                 case 'C':                                                                       /* command */
422                         /* TODO: allow this to be passed in with --metric */
423                         if (prog)
424                                 break;
425                         else
426                                 prog = optarg;
427                         asprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
428                                   prog);
429                         options |= PROG;
430                         break;
431                 case 'a':                                                                       /* args (full path name with args) */
432                         /* TODO: allow this to be passed in with --metric */
433                         if (args)
434                                 break;
435                         else
436                                 args = optarg;
437                         asprintf (&fmt, _("%s%sargs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), args);
438                         options |= ARGS;
439                         break;
440                 case 'r':                                       /* RSS */
441                         if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) {
442                                 asprintf (&fmt, _("%s%sRSS >= %d"), (fmt ? fmt : ""), (options ? ", " : ""), rss);
443                                 options |= RSS;
444                                 break;
445                         }
446                         usage2 (_("%s: RSS must be an integer!\n\n"), progname);
447                 case 'z':                                       /* VSZ */
448                         if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) {
449                                 asprintf (&fmt, _("%s%sVSZ >= %d"), (fmt ? fmt : ""), (options ? ", " : ""), vsz);
450                                 options |= VSZ;
451                                 break;
452                         }
453                         usage2 (_("%s: VSZ must be an integer!\n\n"), progname);
454                 case 'P':                                       /* PCPU */
455                         /* TODO: -P 1.5.5 is accepted */
456                         if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) {
457                                 asprintf (&fmt, _("%s%sPCPU >= %.2f"), (fmt ? fmt : ""), (options ? ", " : ""), pcpu);
458                                 options |= PCPU;
459                                 break;
460                         }
461                         usage2 (_("%s: PCPU must be a float!\n\n"), progname);
462                 case 'm':
463                         asprintf (&metric_name, "%s", optarg);
464                         if ( strcmp(optarg, "PROCS") == 0) {
465                                 metric = METRIC_PROCS;
466                                 break;
467                         } 
468                         else if ( strcmp(optarg, "VSZ") == 0) {
469                                 metric = METRIC_VSZ;
470                                 break;
471                         } 
472                         else if ( strcmp(optarg, "RSS") == 0 ) {
473                                 metric = METRIC_RSS;
474                                 break;
475                         }
476                         else if ( strcmp(optarg, "CPU") == 0 ) {
477                                 metric = METRIC_CPU;
478                                 break;
479                         }
480                         else if ( strcmp(optarg, "ELAPSED") == 0) {
481                                 metric = METRIC_ELAPSED;
482                                 break;
483                         }
484                                 
485                         printf (_("%s: metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!\n\n"),
486                                 progname);
487                         print_usage ();
488                         exit (STATE_UNKNOWN);
489                 case 'v':                                                                       /* command */
490                         verbose++;
491                         break;
492                 }
493         }
495         c = optind;
496         if (wmax == -1 && argv[c])
497                 wmax = atoi (argv[c++]);
498         if (cmax == -1 && argv[c])
499                 cmax = atoi (argv[c++]);
500         if (statopts == NULL && argv[c]) {
501                 asprintf (&statopts, "%s", argv[c++]);
502                 asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
503                 options |= STAT;
504         }
506         return validate_arguments ();
511 int
512 validate_arguments ()
515         if (wmax >= 0 && wmin == -1)
516                 wmin = 0;
517         if (cmax >= 0 && cmin == -1)
518                 cmin = 0;
519         if (wmax >= wmin && cmax >= cmin) {     /* standard ranges */
520                 if (wmax > cmax && cmax != -1) {
521                         printf (_("wmax (%d) cannot be greater than cmax (%d)\n"), wmax, cmax);
522                         return ERROR;
523                 }
524                 if (cmin > wmin && wmin != -1) {
525                         printf (_("wmin (%d) cannot be less than cmin (%d)\n"), wmin, cmin);
526                         return ERROR;
527                 }
528         }
530 /*      if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) { */
531 /*              printf ("At least one threshold must be set\n"); */
532 /*              return ERROR; */
533 /*      } */
535         if (options == 0)
536                 options = ALL;
538         if (statopts==NULL)
539                 statopts = strdup("");
541         if (prog==NULL)
542                 prog = strdup("");
544         if (args==NULL)
545                 args = strdup("");
547         if (fmt==NULL)
548                 fmt = strdup("");
550         if (fails==NULL)
551                 fails = strdup("");
553         return options;
558 /* Check thresholds against value */
559 int
560 check_thresholds (int value)
562         if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) {
563                 return OK;
564         }
565         else if (cmax >= 0 && cmin >= 0 && cmax < cmin) {
566                 if (value > cmax && value < cmin)
567                         return STATE_CRITICAL;
568         }
569         else if (cmax >= 0 && value > cmax) {
570                 return STATE_CRITICAL;
571         }
572         else if (cmin >= 0 && value < cmin) {
573                 return STATE_CRITICAL;
574         }
576         if (wmax >= 0 && wmin >= 0 && wmax < wmin) {
577                 if (value > wmax && value < wmin) {
578                         return STATE_WARNING;
579                 }
580         }
581         else if (wmax >= 0 && value > wmax) {
582                 return STATE_WARNING;
583         }
584         else if (wmin >= 0 && value < wmin) {
585                 return STATE_WARNING;
586         }
587         return STATE_OK;
593 /* convert the elapsed time to seconds */
594 int
595 convert_to_seconds(char *etime) {
597         char *ptr;
598         int total;
600         int hyphcnt;
601         int coloncnt;
602         int days;
603         int hours;
604         int minutes;
605         int seconds;
607         hyphcnt = 0;
608         coloncnt = 0;
609         days = 0;
610         hours = 0;
611         minutes = 0;
612         seconds = 0;
614         for (ptr = etime; *ptr != '\0'; ptr++) {
615         
616                 if (*ptr == '-') {
617                         hyphcnt++;
618                         continue;
619                 }
620                 if (*ptr == ':') {
621                         coloncnt++;
622                         continue;
623                 }
624         }
626         if (hyphcnt > 0) {
627                 sscanf(etime, "%d-%d:%d:%d",
628                                 &days, &hours, &minutes, &seconds);
629                 /* linux 2.6.5/2.6.6 reporting some processes with infinite
630                  * elapsed times for some reason */
631                 if (days == 49710) {
632                         return 0;
633                 }
634         } else {
635                 if (coloncnt == 2) {
636                         sscanf(etime, "%d:%d:%d",
637                                 &hours, &minutes, &seconds);
638                 } else if (coloncnt == 1) {
639                         sscanf(etime, "%d:%d",
640                                 &minutes, &seconds);
641                 }
642         }
644         total = (days * 86400) +
645                 (hours * 3600) +
646                 (minutes * 60) +
647                 seconds;
649         if (verbose >= 3) {
650                 printf("seconds: %d\n", total);
651         }
652         return total;
657 void
658 print_help (void)
660         print_revision (progname, revision);
662         printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>");
663         printf (COPYRIGHT, copyright, email);
665         printf(_("\
666 Checks all processes and generates WARNING or CRITICAL states if the specified\n\
667 metric is outside the required threshold ranges. The metric defaults to number\n\
668 of processes.  Search filters can be applied to limit the processes to check.\n\n"));
670         print_usage ();
672         printf(_("\n\
673 Required Arguments:\n\
674  -w, --warning=RANGE\n\
675    Generate warning state if metric is outside this range\n\
676  -c, --critical=RANGE\n\
677    Generate critical state if metric is outside this range\n"));
679         printf(_("\n\
680 Optional Arguments:\n\
681  -m, --metric=TYPE\n\
682    Check thresholds against metric. Valid types:\n\
683    PROCS   - number of processes (default)\n\
684    VSZ     - virtual memory size\n\
685    RSS     - resident set memory size\n\
686    CPU     - percentage cpu\n"));
687 /* only linux etime is support currently */
688 #if defined( __linux__ )
689         printf(_("\
690    ELAPSED - time elapsed in seconds\n"));
691 #endif /* defined(__linux__) */
692         printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
694         printf(_("\
695  -v, --verbose\n\
696    Extra information. Up to 3 verbosity levels\n"));
698         printf(_("\n\
699 Optional Filters:\n\
700  -s, --state=STATUSFLAGS\n\
701    Only scan for processes that have, in the output of `ps`, one or\n\
702    more of the status flags you specify (for example R, Z, S, RS,\n\
703    RSZDT, plus others based on the output of your 'ps' command).\n\
704  -p, --ppid=PPID\n\
705    Only scan for children of the parent process ID indicated.\n\
706  -z, --vsz=VSZ\n\
707    Only scan for processes with vsz higher than indicated.\n\
708  -r, --rss=RSS\n\
709    Only scan for processes with rss higher than indicated.\n"));
711         printf(_("\
712  -P, --pcpu=PCPU\n\
713    Only scan for processes with pcpu higher than indicated.\n\
714  -u, --user=USER\n\
715    Only scan for processes with user name or ID indicated.\n\
716  -a, --argument-array=STRING\n\
717    Only scan for processes with args that contain STRING.\n\
718  -C, --command=COMMAND\n\
719    Only scan for exact matches of COMMAND (without path).\n"));
721         printf(_("\n\
722 RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
723 specified 'max:min', a warning status will be generated if the\n\
724 count is inside the specified range\n\n"));
726         printf(_("\
727 This plugin checks the number of currently running processes and\n\
728 generates WARNING or CRITICAL states if the process count is outside\n\
729 the specified threshold ranges. The process count can be filtered by\n\
730 process owner, parent process PID, current state (e.g., 'Z'), or may\n\
731 be the total number of running processes\n\n"));
733         printf(_("\
734 Examples:\n\
735  check_procs -w 2:2 -c 2:1024 -C portsentry\n\
736    Warning if not two processes with command name portsentry. Critical\n\
737    if < 2 or > 1024 processes\n\n\
738  check_procs -w 10 -a '/usr/local/bin/perl' -u root\n\
739    Warning alert if > 10 processes with command arguments containing \n\
740    '/usr/local/bin/perl' and owned by root\n\n\
741  check_procs -w 50000 -c 100000 --metric=VSZ\n\
742    Alert if vsz of any processes over 50K or 100K\n\
743  check_procs -w 10 -c 20 --metric=CPU\n\
744    Alert if cpu of any processes over 10%% or 20%%\n\n"));
746         printf (_(UT_SUPPORT));
749 void
750 print_usage (void)
752         printf ("\
753 Usage: %s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n\
754           [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n\
755           [-C command] [-t timeout] [-v]\n", progname);