Code

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