Code

Added support for --extra-opts in all C plugins (disabled by default, see configure...
[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 * Last Modified: $Date$
9
10 * Description:
11
12 * This file contains the check_procs plugin
13
14 * Checks all processes and generates WARNING or CRITICAL states if the
15 * specified metric is outside the required threshold ranges. The metric
16 * defaults to number of processes.  Search filters can be applied to limit
17 * the processes to check.
18
19
20 * This program is free software: you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation, either version 3 of the License, or
23 * (at your option) any later version.
24
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 * GNU General Public License for more details.
29
30 * You should have received a copy of the GNU General Public License
31 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
32
33 * $Id$
34
35 *****************************************************************************/
37 const char *progname = "check_procs";
38 const char *program_name = "check_procs";  /* Required for coreutils libs */
39 const char *revision = "$Revision$";
40 const char *copyright = "2000-2008";
41 const char *email = "nagiosplug-devel@lists.sourceforge.net";
43 #include "common.h"
44 #include "popen.h"
45 #include "utils.h"
46 #include "regex.h"
48 #include <pwd.h>
50 int process_arguments (int, char **);
51 int validate_arguments (void);
52 int check_thresholds (int);
53 int convert_to_seconds (char *); 
54 void print_help (void);
55 void print_usage (void);
57 int wmax = -1;
58 int cmax = -1;
59 int wmin = -1;
60 int cmin = -1;
62 int options = 0; /* bitmask of filter criteria to test against */
63 #define ALL 1
64 #define STAT 2
65 #define PPID 4
66 #define USER 8
67 #define PROG 16
68 #define ARGS 32
69 #define VSZ  64
70 #define RSS  128
71 #define PCPU 256
72 #define ELAPSED 512
73 #define EREG_ARGS 1024
74 /* Different metrics */
75 char *metric_name;
76 enum metric {
77         METRIC_PROCS,
78         METRIC_VSZ,
79         METRIC_RSS,
80         METRIC_CPU,
81         METRIC_ELAPSED
82 };
83 enum metric metric = METRIC_PROCS;
85 int verbose = 0;
86 int uid;
87 pid_t ppid;
88 int vsz;
89 int rss;
90 float pcpu;
91 char *statopts;
92 char *prog;
93 char *args;
94 char *input_filename = NULL;
95 regex_t re_args;
96 char *fmt;
97 char *fails;
98 char tmp[MAX_INPUT_BUFFER];
100 FILE *ps_input = NULL;
103 int
104 main (int argc, char **argv)
106         char *input_buffer;
107         char *input_line;
108         char *procprog;
110         pid_t mypid = 0;
111         int procuid = 0;
112         pid_t procpid = 0;
113         pid_t procppid = 0;
114         int procvsz = 0;
115         int procrss = 0;
116         int procseconds = 0;
117         float procpcpu = 0;
118         char procstat[8];
119         char procetime[MAX_INPUT_BUFFER] = { '\0' };
120         char *procargs;
122         const char *zombie = "Z";
124         int resultsum = 0; /* bitmask of the filter criteria met by a process */
125         int found = 0; /* counter for number of lines returned in `ps` output */
126         int procs = 0; /* counter for number of processes meeting filter criteria */
127         int pos; /* number of spaces before 'args' in `ps` output */
128         int cols; /* number of columns in ps output */
129         int expected_cols = PS_COLS - 1;
130         int warn = 0; /* number of processes in warn state */
131         int crit = 0; /* number of processes in crit state */
132         int i = 0;
133         int result = STATE_UNKNOWN;
135         setlocale (LC_ALL, "");
136         bindtextdomain (PACKAGE, LOCALEDIR);
137         textdomain (PACKAGE);
138         setlocale(LC_NUMERIC, "POSIX");
140         input_buffer = malloc (MAX_INPUT_BUFFER);
141         procprog = malloc (MAX_INPUT_BUFFER);
143         asprintf (&metric_name, "PROCS");
144         metric = METRIC_PROCS;
146         /* Parse extra opts if any */
147         argv=np_extra_opts (&argc, argv, progname);
149         if (process_arguments (argc, argv) == ERROR)
150                 usage4 (_("Could not parse arguments"));
152         /* get our pid */
153         mypid = getpid();
155         /* Set signal handling and alarm timeout */
156         if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
157                 usage4 (_("Cannot catch SIGALRM"));
158         }
159         alarm (timeout_interval);
161         if (verbose >= 2)
162                 printf (_("CMD: %s\n"), PS_COMMAND);
164         if (input_filename == NULL) {
165                 ps_input = spopen (PS_COMMAND);
166                 if (ps_input == NULL) {
167                         printf (_("Could not open pipe: %s\n"), PS_COMMAND);
168                         return STATE_UNKNOWN;
169                 }
170                 child_stderr = fdopen (child_stderr_array[fileno (ps_input)], "r");
171                 if (child_stderr == NULL)
172                         printf (_("Could not open stderr for %s\n"), PS_COMMAND);
173         } else {
174                 ps_input = fopen(input_filename, "r");
175                 if (ps_input == NULL) {
176                         die( STATE_UNKNOWN, _("Error opening %s\n"), input_filename );
177                 }
178         }
180         /* flush first line */
181         fgets (input_buffer, MAX_INPUT_BUFFER - 1, ps_input);
182         while ( input_buffer[strlen(input_buffer)-1] != '\n' )
183                 fgets (input_buffer, MAX_INPUT_BUFFER - 1, ps_input);
185         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, ps_input)) {
186                 asprintf (&input_line, "%s", input_buffer);
187                 while ( input_buffer[strlen(input_buffer)-1] != '\n' ) {
188                         fgets (input_buffer, MAX_INPUT_BUFFER - 1, ps_input);
189                         asprintf (&input_line, "%s%s", input_line, input_buffer);
190                 }
192                 if (verbose >= 3)
193                         printf ("%s", input_line);
195                 strcpy (procprog, "");
196                 asprintf (&procargs, "%s", "");
198                 cols = sscanf (input_line, PS_FORMAT, PS_VARLIST);
200                 /* Zombie processes do not give a procprog command */
201                 if ( cols < expected_cols && strstr(procstat, zombie) ) {
202                         cols = expected_cols;
203                 }
204                 if ( cols >= expected_cols ) {
205                         resultsum = 0;
206                         asprintf (&procargs, "%s", input_line + pos);
207                         strip (procargs);
209                         /* Some ps return full pathname for command. This removes path */
210                         strcpy(procprog, base_name(procprog));
212                         /* we need to convert the elapsed time to seconds */
213                         procseconds = convert_to_seconds(procetime);
215                         if (verbose >= 3)
216                                 printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", 
217                                         procs, procuid, procvsz, procrss,
218                                         procpid, procppid, procpcpu, procstat, 
219                                         procetime, procprog, procargs);
221                         /* Ignore self */
222                         if (mypid == procpid) continue;
224                         if ((options & STAT) && (strstr (statopts, procstat)))
225                                 resultsum |= STAT;
226                         if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
227                                 resultsum |= ARGS;
228                         if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t) 0, NULL, 0) == 0))
229                                 resultsum |= EREG_ARGS;
230                         if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0))
231                                 resultsum |= PROG;
232                         if ((options & PPID) && (procppid == ppid))
233                                 resultsum |= PPID;
234                         if ((options & USER) && (procuid == uid))
235                                 resultsum |= USER;
236                         if ((options & VSZ)  && (procvsz >= vsz))
237                                 resultsum |= VSZ;
238                         if ((options & RSS)  && (procrss >= rss))
239                                 resultsum |= RSS;
240                         if ((options & PCPU)  && (procpcpu >= pcpu))
241                                 resultsum |= PCPU;
243                         found++;
245                         /* Next line if filters not matched */
246                         if (!(options == resultsum || options == ALL))
247                                 continue;
249                         procs++;
250                         if (verbose >= 2) {
251                                 printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", 
252                                         procuid, procvsz, procrss,
253                                         procpid, procppid, procpcpu, procstat, 
254                                         procetime, procprog, procargs);
255                         }
257                         if (metric == METRIC_VSZ)
258                                 i = check_thresholds (procvsz);
259                         else if (metric == METRIC_RSS)
260                                 i = check_thresholds (procrss);
261                         /* TODO? float thresholds for --metric=CPU */
262                         else if (metric == METRIC_CPU)
263                                 i = check_thresholds ((int)procpcpu); 
264                         else if (metric == METRIC_ELAPSED)
265                                 i = check_thresholds (procseconds);
267                         if (metric != METRIC_PROCS) {
268                                 if (i == STATE_WARNING) {
269                                         warn++;
270                                         asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
271                                         result = max_state (result, i);
272                                 }
273                                 if (i == STATE_CRITICAL) {
274                                         crit++;
275                                         asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
276                                         result = max_state (result, i);
277                                 }
278                         }
279                 } 
280                 /* This should not happen */
281                 else if (verbose) {
282                         printf(_("Not parseable: %s"), input_buffer);
283                 }
284         }
286         /* If we get anything on STDERR, at least set warning */
287         if (input_filename == NULL) {
288                 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
289                         if (verbose)
290                                 printf ("STDERR: %s", input_buffer);
291                         result = max_state (result, STATE_WARNING);
292                         printf (_("System call sent warnings to stderr\n"));
293                 }
294         
295                 (void) fclose (child_stderr);
297                 /* close the pipe */
298                 if (spclose (ps_input)) {
299                         printf (_("System call returned nonzero status\n"));
300                         result = max_state (result, STATE_WARNING);
301                 }
302         }
304         if (found == 0) {                                                       /* no process lines parsed so return STATE_UNKNOWN */
305                 printf (_("Unable to read output\n"));
306                 return result;
307         }
309         if ( result == STATE_UNKNOWN ) 
310                 result = STATE_OK;
312         /* Needed if procs found, but none match filter */
313         if ( metric == METRIC_PROCS ) {
314                 result = max_state (result, check_thresholds (procs) );
315         }
317         if ( result == STATE_OK ) {
318                 printf ("%s %s: ", metric_name, _("OK"));
319         } else if (result == STATE_WARNING) {
320                 printf ("%s %s: ", metric_name, _("WARNING"));
321                 if ( metric != METRIC_PROCS ) {
322                         printf (_("%d warn out of "), warn);
323                 }
324         } else if (result == STATE_CRITICAL) {
325                 printf ("%s %s: ", metric_name, _("CRITICAL"));
326                 if (metric != METRIC_PROCS) {
327                         printf (_("%d crit, %d warn out of "), crit, warn);
328                 }
329         } 
330         printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs);
331         
332         if (strcmp(fmt,"") != 0) {
333                 printf (_(" with %s"), fmt);
334         }
336         if ( verbose >= 1 && strcmp(fails,"") )
337                 printf (" [%s]", fails);
339         printf ("\n");
340         return result;
345 /* process command-line arguments */
346 int
347 process_arguments (int argc, char **argv)
349         int c = 1;
350         char *user;
351         struct passwd *pw;
352         int option = 0;
353         int err;
354         int cflags = REG_NOSUB | REG_EXTENDED;
355         char errbuf[MAX_INPUT_BUFFER];
356         static struct option longopts[] = {
357                 {"warning", required_argument, 0, 'w'},
358                 {"critical", required_argument, 0, 'c'},
359                 {"metric", required_argument, 0, 'm'},
360                 {"timeout", required_argument, 0, 't'},
361                 {"status", required_argument, 0, 's'},
362                 {"ppid", required_argument, 0, 'p'},
363                 {"command", required_argument, 0, 'C'},
364                 {"vsz", required_argument, 0, 'z'},
365                 {"rss", required_argument, 0, 'r'},
366                 {"pcpu", required_argument, 0, 'P'},
367                 {"elapsed", required_argument, 0, 'e'},
368                 {"argument-array", required_argument, 0, 'a'},
369                 {"help", no_argument, 0, 'h'},
370                 {"version", no_argument, 0, 'V'},
371                 {"verbose", no_argument, 0, 'v'},
372                 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1},
373                 {"input-file", required_argument, 0, CHAR_MAX+2},
374                 {0, 0, 0, 0}
375         };
377         for (c = 1; c < argc; c++)
378                 if (strcmp ("-to", argv[c]) == 0)
379                         strcpy (argv[c], "-t");
381         while (1) {
382                 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:", 
383                         longopts, &option);
385                 if (c == -1 || c == EOF)
386                         break;
388                 switch (c) {
389                 case '?':                                                                       /* help */
390                         usage5 ();
391                 case 'h':                                                                       /* help */
392                         print_help ();
393                         exit (STATE_OK);
394                 case 'V':                                                                       /* version */
395                         print_revision (progname, revision);
396                         exit (STATE_OK);
397                 case 't':                                                                       /* timeout period */
398                         if (!is_integer (optarg))
399                                 usage2 (_("Timeout interval must be a positive integer"), optarg);
400                         else
401                                 timeout_interval = atoi (optarg);
402                         break;
403                 case 'c':                                                                       /* critical threshold */
404                         if (is_integer (optarg))
405                                 cmax = atoi (optarg);
406                         else if (sscanf (optarg, ":%d", &cmax) == 1)
407                                 break;
408                         else if (sscanf (optarg, "%d:%d", &cmin, &cmax) == 2)
409                                 break;
410                         else if (sscanf (optarg, "%d:", &cmin) == 1)
411                                 break;
412                         else
413                                 usage4 (_("Critical Process Count must be an integer!"));
414                         break;                                                   
415                 case 'w':                                                                       /* warning threshold */
416                         if (is_integer (optarg))
417                                 wmax = atoi (optarg);
418                         else if (sscanf (optarg, ":%d", &wmax) == 1)
419                                 break;
420                         else if (sscanf (optarg, "%d:%d", &wmin, &wmax) == 2)
421                                 break;
422                         else if (sscanf (optarg, "%d:", &wmin) == 1)
423                                 break;
424                         else
425                                 usage4 (_("Warning Process Count must be an integer!"));
426                         break;
427                 case 'p':                                                                       /* process id */
428                         if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) {
429                                 asprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid);
430                                 options |= PPID;
431                                 break;
432                         }
433                         usage4 (_("Parent Process ID must be an integer!"));
434                 case 's':                                                                       /* status */
435                         if (statopts)
436                                 break;
437                         else
438                                 statopts = optarg;
439                         asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
440                         options |= STAT;
441                         break;
442                 case 'u':                                                                       /* user or user id */
443                         if (is_integer (optarg)) {
444                                 uid = atoi (optarg);
445                                 pw = getpwuid ((uid_t) uid);
446                                 /*  check to be sure user exists */
447                                 if (pw == NULL)
448                                         usage2 (_("UID was not found"), optarg);
449                         }
450                         else {
451                                 pw = getpwnam (optarg);
452                                 /*  check to be sure user exists */
453                                 if (pw == NULL)
454                                         usage2 (_("User name was not found"), optarg);
455                                 /*  then get uid */
456                                 uid = pw->pw_uid;
457                         }
458                         user = pw->pw_name;
459                         asprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""),
460                                   uid, user);
461                         options |= USER;
462                         break;
463                 case 'C':                                                                       /* command */
464                         /* TODO: allow this to be passed in with --metric */
465                         if (prog)
466                                 break;
467                         else
468                                 prog = optarg;
469                         asprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
470                                   prog);
471                         options |= PROG;
472                         break;
473                 case 'a':                                                                       /* args (full path name with args) */
474                         /* TODO: allow this to be passed in with --metric */
475                         if (args)
476                                 break;
477                         else
478                                 args = optarg;
479                         asprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args);
480                         options |= ARGS;
481                         break;
482                 case CHAR_MAX+1:
483                         err = regcomp(&re_args, optarg, cflags);
484                         if (err != 0) {
485                                 regerror (err, &re_args, errbuf, MAX_INPUT_BUFFER);
486                                 die (STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf);
487                         }
488                         asprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), optarg);
489                         options |= EREG_ARGS;
490                         break;
491                 case 'r':                                       /* RSS */
492                         if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) {
493                                 asprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss);
494                                 options |= RSS;
495                                 break;
496                         }
497                         usage4 (_("RSS must be an integer!"));
498                 case 'z':                                       /* VSZ */
499                         if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) {
500                                 asprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz);
501                                 options |= VSZ;
502                                 break;
503                         }
504                         usage4 (_("VSZ must be an integer!"));
505                 case 'P':                                       /* PCPU */
506                         /* TODO: -P 1.5.5 is accepted */
507                         if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) {
508                                 asprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu);
509                                 options |= PCPU;
510                                 break;
511                         }
512                         usage4 (_("PCPU must be a float!"));
513                 case 'm':
514                         asprintf (&metric_name, "%s", optarg);
515                         if ( strcmp(optarg, "PROCS") == 0) {
516                                 metric = METRIC_PROCS;
517                                 break;
518                         } 
519                         else if ( strcmp(optarg, "VSZ") == 0) {
520                                 metric = METRIC_VSZ;
521                                 break;
522                         } 
523                         else if ( strcmp(optarg, "RSS") == 0 ) {
524                                 metric = METRIC_RSS;
525                                 break;
526                         }
527                         else if ( strcmp(optarg, "CPU") == 0 ) {
528                                 metric = METRIC_CPU;
529                                 break;
530                         }
531                         else if ( strcmp(optarg, "ELAPSED") == 0) {
532                                 metric = METRIC_ELAPSED;
533                                 break;
534                         }
535                                 
536                         usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
537                 case 'v':                                                                       /* command */
538                         verbose++;
539                         break;
540                 case CHAR_MAX+2:
541                         input_filename = optarg;
542                         break;
543                 }
544         }
546         c = optind;
547         if (wmax == -1 && argv[c])
548                 wmax = atoi (argv[c++]);
549         if (cmax == -1 && argv[c])
550                 cmax = atoi (argv[c++]);
551         if (statopts == NULL && argv[c]) {
552                 asprintf (&statopts, "%s", argv[c++]);
553                 asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
554                 options |= STAT;
555         }
557         return validate_arguments ();
562 int
563 validate_arguments ()
566         if (wmax >= 0 && wmin == -1)
567                 wmin = 0;
568         if (cmax >= 0 && cmin == -1)
569                 cmin = 0;
570         if (wmax >= wmin && cmax >= cmin) {     /* standard ranges */
571                 if (wmax > cmax && cmax != -1) {
572                         printf (_("wmax (%d) cannot be greater than cmax (%d)\n"), wmax, cmax);
573                         return ERROR;
574                 }
575                 if (cmin > wmin && wmin != -1) {
576                         printf (_("wmin (%d) cannot be less than cmin (%d)\n"), wmin, cmin);
577                         return ERROR;
578                 }
579         }
581 /*      if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) { */
582 /*              printf ("At least one threshold must be set\n"); */
583 /*              return ERROR; */
584 /*      } */
586         if (options == 0)
587                 options = ALL;
589         if (statopts==NULL)
590                 statopts = strdup("");
592         if (prog==NULL)
593                 prog = strdup("");
595         if (args==NULL)
596                 args = strdup("");
598         if (fmt==NULL)
599                 fmt = strdup("");
601         if (fails==NULL)
602                 fails = strdup("");
604         return options;
609 /* Check thresholds against value */
610 int
611 check_thresholds (int value)
613         if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) {
614                 return OK;
615         }
616         else if (cmax >= 0 && cmin >= 0 && cmax < cmin) {
617                 if (value > cmax && value < cmin)
618                         return STATE_CRITICAL;
619         }
620         else if (cmax >= 0 && value > cmax) {
621                 return STATE_CRITICAL;
622         }
623         else if (cmin >= 0 && value < cmin) {
624                 return STATE_CRITICAL;
625         }
627         if (wmax >= 0 && wmin >= 0 && wmax < wmin) {
628                 if (value > wmax && value < wmin) {
629                         return STATE_WARNING;
630                 }
631         }
632         else if (wmax >= 0 && value > wmax) {
633                 return STATE_WARNING;
634         }
635         else if (wmin >= 0 && value < wmin) {
636                 return STATE_WARNING;
637         }
638         return STATE_OK;
642 /* convert the elapsed time to seconds */
643 int
644 convert_to_seconds(char *etime) {
646         char *ptr;
647         int total;
649         int hyphcnt;
650         int coloncnt;
651         int days;
652         int hours;
653         int minutes;
654         int seconds;
656         hyphcnt = 0;
657         coloncnt = 0;
658         days = 0;
659         hours = 0;
660         minutes = 0;
661         seconds = 0;
663         for (ptr = etime; *ptr != '\0'; ptr++) {
664         
665                 if (*ptr == '-') {
666                         hyphcnt++;
667                         continue;
668                 }
669                 if (*ptr == ':') {
670                         coloncnt++;
671                         continue;
672                 }
673         }
675         if (hyphcnt > 0) {
676                 sscanf(etime, "%d-%d:%d:%d",
677                                 &days, &hours, &minutes, &seconds);
678                 /* linux 2.6.5/2.6.6 reporting some processes with infinite
679                  * elapsed times for some reason */
680                 if (days == 49710) {
681                         return 0;
682                 }
683         } else {
684                 if (coloncnt == 2) {
685                         sscanf(etime, "%d:%d:%d",
686                                 &hours, &minutes, &seconds);
687                 } else if (coloncnt == 1) {
688                         sscanf(etime, "%d:%d",
689                                 &minutes, &seconds);
690                 }
691         }
693         total = (days * 86400) +
694                 (hours * 3600) +
695                 (minutes * 60) +
696                 seconds;
698         if (verbose >= 3 && metric == METRIC_ELAPSED) {
699                         printf("seconds: %d\n", total);
700         }
701         return total;
705 void
706 print_help (void)
708         print_revision (progname, revision);
710         printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
711         printf (COPYRIGHT, copyright, email);
713         printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified"));
714   printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number"));
715   printf ("%s\n", _("of processes.  Search filters can be applied to limit the processes to check."));
717   printf ("\n\n");
719         print_usage ();
721   printf (_(UT_HELP_VRSN));
722   printf (_(UT_EXTRA_OPTS));
723   printf (" %s\n", "-w, --warning=RANGE");
724   printf ("   %s\n", _("Generate warning state if metric is outside this range"));
725   printf (" %s\n", "-c, --critical=RANGE");
726   printf ("   %s\n", _("Generate critical state if metric is outside this range"));
727   printf (" %s\n", "-m, --metric=TYPE");
728   printf ("  %s\n", _("Check thresholds against metric. Valid types:"));
729   printf ("  %s\n", _("PROCS   - number of processes (default)"));
730   printf ("  %s\n", _("VSZ     - virtual memory size"));
731   printf ("  %s\n", _("RSS     - resident set memory size"));
732   printf ("  %s\n", _("CPU     - percentage cpu"));
733 /* only linux etime is support currently */
734 #if defined( __linux__ )
735         printf ("  %s\n", _("ELAPSED - time elapsed in seconds"));
736 #endif /* defined(__linux__) */
737         printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
739         printf (" %s\n", "-v, --verbose");
740   printf ("    %s\n", _("Extra information. Up to 3 verbosity levels"));
742   printf ("\n");
743         printf ("%s\n", "Filters:");
744   printf (" %s\n", "-s, --state=STATUSFLAGS");
745   printf ("   %s\n", _("Only scan for processes that have, in the output of `ps`, one or"));
746   printf ("   %s\n", _("more of the status flags you specify (for example R, Z, S, RS,"));
747   printf ("   %s\n", _("RSZDT, plus others based on the output of your 'ps' command)."));
748   printf (" %s\n", "-p, --ppid=PPID");
749   printf ("   %s\n", _("Only scan for children of the parent process ID indicated."));
750   printf (" %s\n", "-z, --vsz=VSZ");
751   printf ("   %s\n", _("Only scan for processes with vsz higher than indicated."));
752   printf (" %s\n", "-r, --rss=RSS");
753   printf ("   %s\n", _("Only scan for processes with rss higher than indicated."));
754         printf (" %s\n", "-P, --pcpu=PCPU");
755   printf ("   %s\n", _("Only scan for processes with pcpu higher than indicated."));
756   printf (" %s\n", "-u, --user=USER");
757   printf ("   %s\n", _("Only scan for processes with user name or ID indicated."));
758   printf (" %s\n", "-a, --argument-array=STRING");
759   printf ("   %s\n", _("Only scan for processes with args that contain STRING."));
760   printf (" %s\n", "--ereg-argument-array=STRING");
761   printf ("   %s\n", _("Only scan for processes with args that contain the regex STRING."));
762   printf (" %s\n", "-C, --command=COMMAND");
763   printf ("   %s\n", _("Only scan for exact matches of COMMAND (without path)."));
765         printf(_("\n\
766 RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
767 specified 'max:min', a warning status will be generated if the\n\
768 count is inside the specified range\n\n"));
770         printf(_("\
771 This plugin checks the number of currently running processes and\n\
772 generates WARNING or CRITICAL states if the process count is outside\n\
773 the specified threshold ranges. The process count can be filtered by\n\
774 process owner, parent process PID, current state (e.g., 'Z'), or may\n\
775 be the total number of running processes\n\n"));
777 #ifdef NP_EXTRA_OPTS
778   printf ("%s\n", _("Notes:"));
779   printf (_(UT_EXTRA_OPTS_NOTES));
780   printf ("\n");
781 #endif
783         printf ("%s\n", _("Examples:"));
784   printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry");
785   printf ("  %s\n", _("Warning if not two processes with command name portsentry."));
786   printf ("  %s\n\n", _("Critical if < 2 or > 1024 processes"));
787   printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root");
788   printf ("  %s\n", _("Warning alert if > 10 processes with command arguments containing"));
789   printf ("  %s\n\n", _("'/usr/local/bin/perl' and owned by root"));
790   printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ");
791   printf ("  %s\n\n", _("Alert if vsz of any processes over 50K or 100K"));
792   printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU");
793   printf ("  %s\n", _("Alert if cpu of any processes over 10%% or 20%%"));
795         printf (_(UT_SUPPORT));
798 void
799 print_usage (void)
801   printf (_("Usage: "));
802         printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
803   printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
804   printf (" [-C command] [-t timeout] [-v]\n");