Code

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