diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-03-12 13:54:00 +0100 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-03-12 13:54:00 +0100 |
| commit | c71a2e414ff3716325a6f4ce715e4a3037d52c0e (patch) | |
| tree | db3a1ccadcac886fcb3c7be50088d53ae6cad260 /plugins | |
| parent | 9f71e510af8aa1c6244e9e334910193ae1468486 (diff) | |
| download | monitoring-plugins-c71a2e414ff3716325a6f4ce715e4a3037d52c0e.tar.gz | |
check_procs: clang-format
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/check_procs.c | 843 |
1 files changed, 422 insertions, 421 deletions
diff --git a/plugins/check_procs.c b/plugins/check_procs.c index 1d78ccee..69b424dc 100644 --- a/plugins/check_procs.c +++ b/plugins/check_procs.c | |||
| @@ -1,41 +1,41 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Monitoring check_procs plugin | 3 | * Monitoring check_procs plugin |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 2000-2024 Monitoring Plugins Development Team | 6 | * Copyright (c) 2000-2024 Monitoring Plugins Development Team |
| 7 | * | 7 | * |
| 8 | * Description: | 8 | * Description: |
| 9 | * | 9 | * |
| 10 | * This file contains the check_procs plugin | 10 | * This file contains the check_procs plugin |
| 11 | * | 11 | * |
| 12 | * Checks all processes and generates WARNING or CRITICAL states if the | 12 | * Checks all processes and generates WARNING or CRITICAL states if the |
| 13 | * specified metric is outside the required threshold ranges. The metric | 13 | * specified metric is outside the required threshold ranges. The metric |
| 14 | * defaults to number of processes. Search filters can be applied to limit | 14 | * defaults to number of processes. Search filters can be applied to limit |
| 15 | * the processes to check. | 15 | * the processes to check. |
| 16 | * | 16 | * |
| 17 | * The parent process, check_procs itself and any child process of | 17 | * The parent process, check_procs itself and any child process of |
| 18 | * check_procs (ps) are excluded from any checks to prevent false positives. | 18 | * check_procs (ps) are excluded from any checks to prevent false positives. |
| 19 | * | 19 | * |
| 20 | * | 20 | * |
| 21 | * This program is free software: you can redistribute it and/or modify | 21 | * This program is free software: you can redistribute it and/or modify |
| 22 | * it under the terms of the GNU General Public License as published by | 22 | * it under the terms of the GNU General Public License as published by |
| 23 | * the Free Software Foundation, either version 3 of the License, or | 23 | * the Free Software Foundation, either version 3 of the License, or |
| 24 | * (at your option) any later version. | 24 | * (at your option) any later version. |
| 25 | * | 25 | * |
| 26 | * This program is distributed in the hope that it will be useful, | 26 | * This program is distributed in the hope that it will be useful, |
| 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 29 | * GNU General Public License for more details. | 29 | * GNU General Public License for more details. |
| 30 | * | 30 | * |
| 31 | * You should have received a copy of the GNU General Public License | 31 | * You should have received a copy of the GNU General Public License |
| 32 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 32 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 33 | * | 33 | * |
| 34 | * | 34 | * |
| 35 | *****************************************************************************/ | 35 | *****************************************************************************/ |
| 36 | 36 | ||
| 37 | const char *progname = "check_procs"; | 37 | const char *progname = "check_procs"; |
| 38 | const char *program_name = "check_procs"; /* Required for coreutils libs */ | 38 | const char *program_name = "check_procs"; /* Required for coreutils libs */ |
| 39 | const char *copyright = "2000-2024"; | 39 | const char *copyright = "2000-2024"; |
| 40 | const char *email = "devel@monitoring-plugins.org"; | 40 | const char *email = "devel@monitoring-plugins.org"; |
| 41 | 41 | ||
| @@ -48,35 +48,36 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 48 | #include <errno.h> | 48 | #include <errno.h> |
| 49 | 49 | ||
| 50 | #ifdef HAVE_SYS_STAT_H | 50 | #ifdef HAVE_SYS_STAT_H |
| 51 | #include <sys/stat.h> | 51 | # include <sys/stat.h> |
| 52 | #endif | 52 | #endif |
| 53 | 53 | ||
| 54 | static int process_arguments (int /*argc*/, char ** /*argv*/); | 54 | static int process_arguments(int /*argc*/, char ** /*argv*/); |
| 55 | static int validate_arguments (void); | 55 | static int validate_arguments(void); |
| 56 | static int convert_to_seconds (char * /*etime*/); | 56 | static int convert_to_seconds(char * /*etime*/); |
| 57 | static void print_help (void); | 57 | static void print_help(void); |
| 58 | void print_usage (void); | 58 | void print_usage(void); |
| 59 | 59 | ||
| 60 | static char *warning_range = NULL; | 60 | static char *warning_range = NULL; |
| 61 | static char *critical_range = NULL; | 61 | static char *critical_range = NULL; |
| 62 | static thresholds *procs_thresholds = NULL; | 62 | static thresholds *procs_thresholds = NULL; |
| 63 | 63 | ||
| 64 | static int options = 0; /* bitmask of filter criteria to test against */ | 64 | static int options = 0; /* bitmask of filter criteria to test against */ |
| 65 | #define ALL 1 | 65 | #define ALL 1 |
| 66 | #define STAT 2 | 66 | #define STAT 2 |
| 67 | #define PPID 4 | 67 | #define PPID 4 |
| 68 | #define USER 8 | 68 | #define USER 8 |
| 69 | #define PROG 16 | 69 | #define PROG 16 |
| 70 | #define ARGS 32 | 70 | #define ARGS 32 |
| 71 | #define VSZ 64 | 71 | #define VSZ 64 |
| 72 | #define RSS 128 | 72 | #define RSS 128 |
| 73 | #define PCPU 256 | 73 | #define PCPU 256 |
| 74 | #define ELAPSED 512 | 74 | #define ELAPSED 512 |
| 75 | #define EREG_ARGS 1024 | 75 | #define EREG_ARGS 1024 |
| 76 | #define EXCLUDE_PROGS 2048 | 76 | #define EXCLUDE_PROGS 2048 |
| 77 | 77 | ||
| 78 | #define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads: | 78 | #define KTHREAD_PARENT \ |
| 79 | ppid of procs are compared to pid of this proc*/ | 79 | "kthreadd" /* the parent process of kernel threads: \ |
| 80 | ppid of procs are compared to pid of this proc*/ | ||
| 80 | 81 | ||
| 81 | /* Different metrics */ | 82 | /* Different metrics */ |
| 82 | char *metric_name; | 83 | char *metric_name; |
| @@ -109,8 +110,7 @@ static char tmp[MAX_INPUT_BUFFER]; | |||
| 109 | static int kthread_filter = 0; | 110 | static int kthread_filter = 0; |
| 110 | static int usepid = 0; /* whether to test for pid or /proc/pid/exe */ | 111 | static int usepid = 0; /* whether to test for pid or /proc/pid/exe */ |
| 111 | 112 | ||
| 112 | static int | 113 | static int stat_exe(const pid_t pid, struct stat *buf) { |
| 113 | stat_exe (const pid_t pid, struct stat *buf) { | ||
| 114 | char *path; | 114 | char *path; |
| 115 | int ret; | 115 | int ret; |
| 116 | xasprintf(&path, "/proc/%d/exe", pid); | 116 | xasprintf(&path, "/proc/%d/exe", pid); |
| @@ -119,10 +119,7 @@ stat_exe (const pid_t pid, struct stat *buf) { | |||
| 119 | return ret; | 119 | return ret; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | 122 | int main(int argc, char **argv) { | |
| 123 | int | ||
| 124 | main (int argc, char **argv) | ||
| 125 | { | ||
| 126 | char *input_buffer; | 123 | char *input_buffer; |
| 127 | char *input_line; | 124 | char *input_line; |
| 128 | char *procprog; | 125 | char *procprog; |
| @@ -141,16 +138,16 @@ main (int argc, char **argv) | |||
| 141 | int procseconds = 0; | 138 | int procseconds = 0; |
| 142 | float procpcpu = 0; | 139 | float procpcpu = 0; |
| 143 | char procstat[8]; | 140 | char procstat[8]; |
| 144 | char procetime[MAX_INPUT_BUFFER] = { '\0' }; | 141 | char procetime[MAX_INPUT_BUFFER] = {'\0'}; |
| 145 | char *procargs; | 142 | char *procargs; |
| 146 | 143 | ||
| 147 | const char *zombie = "Z"; | 144 | const char *zombie = "Z"; |
| 148 | 145 | ||
| 149 | int resultsum = 0; /* bitmask of the filter criteria met by a process */ | 146 | int resultsum = 0; /* bitmask of the filter criteria met by a process */ |
| 150 | int found = 0; /* counter for number of lines returned in `ps` output */ | 147 | int found = 0; /* counter for number of lines returned in `ps` output */ |
| 151 | int procs = 0; /* counter for number of processes meeting filter criteria */ | 148 | int procs = 0; /* counter for number of processes meeting filter criteria */ |
| 152 | int pos; /* number of spaces before 'args' in `ps` output */ | 149 | int pos; /* number of spaces before 'args' in `ps` output */ |
| 153 | int cols; /* number of columns in ps output */ | 150 | int cols; /* number of columns in ps output */ |
| 154 | int expected_cols = PS_COLS - 1; | 151 | int expected_cols = PS_COLS - 1; |
| 155 | int warn = 0; /* number of processes in warn state */ | 152 | int warn = 0; /* number of processes in warn state */ |
| 156 | int crit = 0; /* number of processes in crit state */ | 153 | int crit = 0; /* number of processes in crit state */ |
| @@ -159,22 +156,23 @@ main (int argc, char **argv) | |||
| 159 | int ret = 0; | 156 | int ret = 0; |
| 160 | output chld_out, chld_err; | 157 | output chld_out, chld_err; |
| 161 | 158 | ||
| 162 | setlocale (LC_ALL, ""); | 159 | setlocale(LC_ALL, ""); |
| 163 | bindtextdomain (PACKAGE, LOCALEDIR); | 160 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 164 | textdomain (PACKAGE); | 161 | textdomain(PACKAGE); |
| 165 | setlocale(LC_NUMERIC, "POSIX"); | 162 | setlocale(LC_NUMERIC, "POSIX"); |
| 166 | 163 | ||
| 167 | input_buffer = malloc (MAX_INPUT_BUFFER); | 164 | input_buffer = malloc(MAX_INPUT_BUFFER); |
| 168 | procprog = malloc (MAX_INPUT_BUFFER); | 165 | procprog = malloc(MAX_INPUT_BUFFER); |
| 169 | 166 | ||
| 170 | xasprintf (&metric_name, "PROCS"); | 167 | xasprintf(&metric_name, "PROCS"); |
| 171 | metric = METRIC_PROCS; | 168 | metric = METRIC_PROCS; |
| 172 | 169 | ||
| 173 | /* Parse extra opts if any */ | 170 | /* Parse extra opts if any */ |
| 174 | argv=np_extra_opts (&argc, argv, progname); | 171 | argv = np_extra_opts(&argc, argv, progname); |
| 175 | 172 | ||
| 176 | if (process_arguments (argc, argv) == ERROR) | 173 | if (process_arguments(argc, argv) == ERROR) { |
| 177 | usage4 (_("Could not parse arguments")); | 174 | usage4(_("Could not parse arguments")); |
| 175 | } | ||
| 178 | 176 | ||
| 179 | /* find ourself */ | 177 | /* find ourself */ |
| 180 | mypid = getpid(); | 178 | mypid = getpid(); |
| @@ -189,44 +187,46 @@ main (int argc, char **argv) | |||
| 189 | } | 187 | } |
| 190 | 188 | ||
| 191 | /* Set signal handling and alarm timeout */ | 189 | /* Set signal handling and alarm timeout */ |
| 192 | if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 190 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
| 193 | die (STATE_UNKNOWN, _("Cannot catch SIGALRM")); | 191 | die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); |
| 194 | } | 192 | } |
| 195 | (void) alarm ((unsigned) timeout_interval); | 193 | (void)alarm((unsigned)timeout_interval); |
| 196 | 194 | ||
| 197 | if (verbose >= 2) | 195 | if (verbose >= 2) { |
| 198 | printf (_("CMD: %s\n"), PS_COMMAND); | 196 | printf(_("CMD: %s\n"), PS_COMMAND); |
| 197 | } | ||
| 199 | 198 | ||
| 200 | if (input_filename == NULL) { | 199 | if (input_filename == NULL) { |
| 201 | result = cmd_run( PS_COMMAND, &chld_out, &chld_err, 0); | 200 | result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0); |
| 202 | if (chld_err.lines > 0) { | 201 | if (chld_err.lines > 0) { |
| 203 | printf ("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); | 202 | printf("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); |
| 204 | exit(STATE_WARNING); | 203 | exit(STATE_WARNING); |
| 205 | } | 204 | } |
| 206 | } else { | 205 | } else { |
| 207 | result = cmd_file_read( input_filename, &chld_out, 0); | 206 | result = cmd_file_read(input_filename, &chld_out, 0); |
| 208 | } | 207 | } |
| 209 | 208 | ||
| 210 | /* flush first line: j starts at 1 */ | 209 | /* flush first line: j starts at 1 */ |
| 211 | for (size_t j = 1; j < chld_out.lines; j++) { | 210 | for (size_t j = 1; j < chld_out.lines; j++) { |
| 212 | input_line = chld_out.line[j]; | 211 | input_line = chld_out.line[j]; |
| 213 | 212 | ||
| 214 | if (verbose >= 3) | 213 | if (verbose >= 3) { |
| 215 | printf ("%s", input_line); | 214 | printf("%s", input_line); |
| 215 | } | ||
| 216 | 216 | ||
| 217 | strcpy (procprog, ""); | 217 | strcpy(procprog, ""); |
| 218 | xasprintf (&procargs, "%s", ""); | 218 | xasprintf(&procargs, "%s", ""); |
| 219 | 219 | ||
| 220 | cols = sscanf (input_line, PS_FORMAT, PS_VARLIST); | 220 | cols = sscanf(input_line, PS_FORMAT, PS_VARLIST); |
| 221 | 221 | ||
| 222 | /* Zombie processes do not give a procprog command */ | 222 | /* Zombie processes do not give a procprog command */ |
| 223 | if ( cols < expected_cols && strstr(procstat, zombie) ) { | 223 | if (cols < expected_cols && strstr(procstat, zombie)) { |
| 224 | cols = expected_cols; | 224 | cols = expected_cols; |
| 225 | } | 225 | } |
| 226 | if ( cols >= expected_cols ) { | 226 | if (cols >= expected_cols) { |
| 227 | resultsum = 0; | 227 | resultsum = 0; |
| 228 | xasprintf (&procargs, "%s", input_line + pos); | 228 | xasprintf(&procargs, "%s", input_line + pos); |
| 229 | strip (procargs); | 229 | strip(procargs); |
| 230 | 230 | ||
| 231 | /* Some ps return full pathname for command. This removes path */ | 231 | /* Some ps return full pathname for command. This removes path */ |
| 232 | strcpy(procprog, base_name(procprog)); | 232 | strcpy(procprog, base_name(procprog)); |
| @@ -234,52 +234,53 @@ main (int argc, char **argv) | |||
| 234 | /* we need to convert the elapsed time to seconds */ | 234 | /* we need to convert the elapsed time to seconds */ |
| 235 | procseconds = convert_to_seconds(procetime); | 235 | procseconds = convert_to_seconds(procetime); |
| 236 | 236 | ||
| 237 | if (verbose >= 3) | 237 | if (verbose >= 3) { |
| 238 | printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", | 238 | printf("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procs, procuid, procvsz, |
| 239 | procs, procuid, procvsz, procrss, | 239 | procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); |
| 240 | procpid, procppid, procpcpu, procstat, | 240 | } |
| 241 | procetime, procprog, procargs); | ||
| 242 | 241 | ||
| 243 | /* Ignore self */ | 242 | /* Ignore self */ |
| 244 | if ((usepid && mypid == procpid) || | 243 | if ((usepid && mypid == procpid) || |
| 245 | ( ((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || | 244 | (((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || |
| 246 | (ret == -1 && errno == ENOENT)) | 245 | (ret == -1 && errno == ENOENT))) { |
| 247 | ) { | 246 | if (verbose >= 3) { |
| 248 | if (verbose >= 3) | 247 | printf("not considering - is myself or gone\n"); |
| 249 | printf("not considering - is myself or gone\n"); | 248 | } |
| 250 | continue; | 249 | continue; |
| 251 | } | 250 | } |
| 252 | /* Ignore parent*/ | 251 | /* Ignore parent*/ |
| 253 | else if (myppid == procpid) { | 252 | else if (myppid == procpid) { |
| 254 | if (verbose >= 3) | 253 | if (verbose >= 3) { |
| 255 | printf("not considering - is parent\n"); | 254 | printf("not considering - is parent\n"); |
| 255 | } | ||
| 256 | continue; | 256 | continue; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | /* Ignore our own children */ | 259 | /* Ignore our own children */ |
| 260 | if (procppid == mypid) { | 260 | if (procppid == mypid) { |
| 261 | if (verbose >= 3) | 261 | if (verbose >= 3) { |
| 262 | printf("not considering - is our child\n"); | 262 | printf("not considering - is our child\n"); |
| 263 | } | ||
| 263 | continue; | 264 | continue; |
| 264 | } | 265 | } |
| 265 | 266 | ||
| 266 | /* Ignore excluded processes by name */ | 267 | /* Ignore excluded processes by name */ |
| 267 | if(options & EXCLUDE_PROGS) { | 268 | if (options & EXCLUDE_PROGS) { |
| 268 | int found = 0; | 269 | int found = 0; |
| 269 | int i = 0; | 270 | int i = 0; |
| 270 | 271 | ||
| 271 | for(i=0; i < (exclude_progs_counter); i++) { | 272 | for (i = 0; i < (exclude_progs_counter); i++) { |
| 272 | if(!strcmp(procprog, exclude_progs_arr[i])) { | 273 | if (!strcmp(procprog, exclude_progs_arr[i])) { |
| 273 | found = 1; | 274 | found = 1; |
| 274 | } | 275 | } |
| 275 | } | 276 | } |
| 276 | if(found == 0) { | 277 | if (found == 0) { |
| 277 | resultsum |= EXCLUDE_PROGS; | 278 | resultsum |= EXCLUDE_PROGS; |
| 278 | } else | 279 | } else { |
| 279 | { | 280 | if (verbose >= 3) { |
| 280 | if(verbose >= 3) | 281 | printf("excluding - by ignorelist\n"); |
| 281 | printf("excluding - by ignorelist\n"); | 282 | } |
| 282 | } | 283 | } |
| 283 | } | 284 | } |
| 284 | 285 | ||
| 285 | /* filter kernel threads (children of KTHREAD_PARENT)*/ | 286 | /* filter kernel threads (children of KTHREAD_PARENT)*/ |
| @@ -287,69 +288,81 @@ main (int argc, char **argv) | |||
| 287 | sorry for not doing that, but I've no other OSes to test :-( */ | 288 | sorry for not doing that, but I've no other OSes to test :-( */ |
| 288 | if (kthread_filter == 1) { | 289 | if (kthread_filter == 1) { |
| 289 | /* get pid KTHREAD_PARENT */ | 290 | /* get pid KTHREAD_PARENT */ |
| 290 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) ) | 291 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) { |
| 291 | kthread_ppid = procpid; | 292 | kthread_ppid = procpid; |
| 293 | } | ||
| 292 | 294 | ||
| 293 | if (kthread_ppid == procppid) { | 295 | if (kthread_ppid == procppid) { |
| 294 | if (verbose >= 2) | 296 | if (verbose >= 2) { |
| 295 | printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); | 297 | printf("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); |
| 298 | } | ||
| 296 | continue; | 299 | continue; |
| 297 | } | 300 | } |
| 298 | } | 301 | } |
| 299 | 302 | ||
| 300 | if ((options & STAT) && (strstr (procstat, statopts))) | 303 | if ((options & STAT) && (strstr(procstat, statopts))) { |
| 301 | resultsum |= STAT; | 304 | resultsum |= STAT; |
| 302 | if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) | 305 | } |
| 306 | if ((options & ARGS) && procargs && (strstr(procargs, args) != NULL)) { | ||
| 303 | resultsum |= ARGS; | 307 | resultsum |= ARGS; |
| 304 | if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t) 0, NULL, 0) == 0)) | 308 | } |
| 309 | if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t)0, NULL, 0) == 0)) { | ||
| 305 | resultsum |= EREG_ARGS; | 310 | resultsum |= EREG_ARGS; |
| 306 | if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0)) | 311 | } |
| 312 | if ((options & PROG) && procprog && (strcmp(prog, procprog) == 0)) { | ||
| 307 | resultsum |= PROG; | 313 | resultsum |= PROG; |
| 308 | if ((options & PPID) && (procppid == ppid)) | 314 | } |
| 315 | if ((options & PPID) && (procppid == ppid)) { | ||
| 309 | resultsum |= PPID; | 316 | resultsum |= PPID; |
| 310 | if ((options & USER) && (procuid == uid)) | 317 | } |
| 318 | if ((options & USER) && (procuid == uid)) { | ||
| 311 | resultsum |= USER; | 319 | resultsum |= USER; |
| 312 | if ((options & VSZ) && (procvsz >= vsz)) | 320 | } |
| 321 | if ((options & VSZ) && (procvsz >= vsz)) { | ||
| 313 | resultsum |= VSZ; | 322 | resultsum |= VSZ; |
| 314 | if ((options & RSS) && (procrss >= rss)) | 323 | } |
| 324 | if ((options & RSS) && (procrss >= rss)) { | ||
| 315 | resultsum |= RSS; | 325 | resultsum |= RSS; |
| 316 | if ((options & PCPU) && (procpcpu >= pcpu)) | 326 | } |
| 327 | if ((options & PCPU) && (procpcpu >= pcpu)) { | ||
| 317 | resultsum |= PCPU; | 328 | resultsum |= PCPU; |
| 329 | } | ||
| 318 | 330 | ||
| 319 | found++; | 331 | found++; |
| 320 | 332 | ||
| 321 | /* Next line if filters not matched */ | 333 | /* Next line if filters not matched */ |
| 322 | if (!(options == resultsum || options == ALL)) | 334 | if (!(options == resultsum || options == ALL)) { |
| 323 | continue; | 335 | continue; |
| 336 | } | ||
| 324 | 337 | ||
| 325 | procs++; | 338 | procs++; |
| 326 | if (verbose >= 2) { | 339 | if (verbose >= 2) { |
| 327 | printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", | 340 | printf("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procuid, procvsz, |
| 328 | procuid, procvsz, procrss, | 341 | procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); |
| 329 | procpid, procppid, procpcpu, procstat, | ||
| 330 | procetime, procprog, procargs); | ||
| 331 | } | 342 | } |
| 332 | 343 | ||
| 333 | if (metric == METRIC_VSZ) | 344 | if (metric == METRIC_VSZ) { |
| 334 | i = get_status ((double)procvsz, procs_thresholds); | 345 | i = get_status((double)procvsz, procs_thresholds); |
| 335 | else if (metric == METRIC_RSS) | 346 | } else if (metric == METRIC_RSS) { |
| 336 | i = get_status ((double)procrss, procs_thresholds); | 347 | i = get_status((double)procrss, procs_thresholds); |
| 348 | } | ||
| 337 | /* TODO? float thresholds for --metric=CPU */ | 349 | /* TODO? float thresholds for --metric=CPU */ |
| 338 | else if (metric == METRIC_CPU) | 350 | else if (metric == METRIC_CPU) { |
| 339 | i = get_status (procpcpu, procs_thresholds); | 351 | i = get_status(procpcpu, procs_thresholds); |
| 340 | else if (metric == METRIC_ELAPSED) | 352 | } else if (metric == METRIC_ELAPSED) { |
| 341 | i = get_status ((double)procseconds, procs_thresholds); | 353 | i = get_status((double)procseconds, procs_thresholds); |
| 354 | } | ||
| 342 | 355 | ||
| 343 | if (metric != METRIC_PROCS) { | 356 | if (metric != METRIC_PROCS) { |
| 344 | if (i == STATE_WARNING) { | 357 | if (i == STATE_WARNING) { |
| 345 | warn++; | 358 | warn++; |
| 346 | xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); | 359 | xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); |
| 347 | result = max_state (result, i); | 360 | result = max_state(result, i); |
| 348 | } | 361 | } |
| 349 | if (i == STATE_CRITICAL) { | 362 | if (i == STATE_CRITICAL) { |
| 350 | crit++; | 363 | crit++; |
| 351 | xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); | 364 | xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); |
| 352 | result = max_state (result, i); | 365 | result = max_state(result, i); |
| 353 | } | 366 | } |
| 354 | } | 367 | } |
| 355 | } | 368 | } |
| @@ -359,58 +372,55 @@ main (int argc, char **argv) | |||
| 359 | } | 372 | } |
| 360 | } | 373 | } |
| 361 | 374 | ||
| 362 | if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ | 375 | if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ |
| 363 | printf (_("Unable to read output\n")); | 376 | printf(_("Unable to read output\n")); |
| 364 | return STATE_UNKNOWN; | 377 | return STATE_UNKNOWN; |
| 365 | } | 378 | } |
| 366 | 379 | ||
| 367 | if ( result == STATE_UNKNOWN ) | 380 | if (result == STATE_UNKNOWN) { |
| 368 | result = STATE_OK; | 381 | result = STATE_OK; |
| 382 | } | ||
| 369 | 383 | ||
| 370 | /* Needed if procs found, but none match filter */ | 384 | /* Needed if procs found, but none match filter */ |
| 371 | if ( metric == METRIC_PROCS ) { | 385 | if (metric == METRIC_PROCS) { |
| 372 | result = max_state (result, get_status ((double)procs, procs_thresholds) ); | 386 | result = max_state(result, get_status((double)procs, procs_thresholds)); |
| 373 | } | 387 | } |
| 374 | 388 | ||
| 375 | if ( result == STATE_OK ) { | 389 | if (result == STATE_OK) { |
| 376 | printf ("%s %s: ", metric_name, _("OK")); | 390 | printf("%s %s: ", metric_name, _("OK")); |
| 377 | } else if (result == STATE_WARNING) { | 391 | } else if (result == STATE_WARNING) { |
| 378 | printf ("%s %s: ", metric_name, _("WARNING")); | 392 | printf("%s %s: ", metric_name, _("WARNING")); |
| 379 | if ( metric != METRIC_PROCS ) { | 393 | if (metric != METRIC_PROCS) { |
| 380 | printf (_("%d warn out of "), warn); | 394 | printf(_("%d warn out of "), warn); |
| 381 | } | 395 | } |
| 382 | } else if (result == STATE_CRITICAL) { | 396 | } else if (result == STATE_CRITICAL) { |
| 383 | printf ("%s %s: ", metric_name, _("CRITICAL")); | 397 | printf("%s %s: ", metric_name, _("CRITICAL")); |
| 384 | if (metric != METRIC_PROCS) { | 398 | if (metric != METRIC_PROCS) { |
| 385 | printf (_("%d crit, %d warn out of "), crit, warn); | 399 | printf(_("%d crit, %d warn out of "), crit, warn); |
| 386 | } | 400 | } |
| 387 | } | 401 | } |
| 388 | printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); | 402 | printf(ngettext("%d process", "%d processes", (unsigned long)procs), procs); |
| 389 | 403 | ||
| 390 | if (strcmp(fmt,"") != 0) { | 404 | if (strcmp(fmt, "") != 0) { |
| 391 | printf (_(" with %s"), fmt); | 405 | printf(_(" with %s"), fmt); |
| 392 | } | 406 | } |
| 393 | 407 | ||
| 394 | if ( verbose >= 1 && strcmp(fails,"") ) | 408 | if (verbose >= 1 && strcmp(fails, "")) { |
| 395 | printf (" [%s]", fails); | 409 | printf(" [%s]", fails); |
| 410 | } | ||
| 396 | 411 | ||
| 397 | if (metric == METRIC_PROCS) | 412 | if (metric == METRIC_PROCS) { |
| 398 | printf (" | procs=%d;%s;%s;0;", procs, | 413 | printf(" | procs=%d;%s;%s;0;", procs, warning_range ? warning_range : "", critical_range ? critical_range : ""); |
| 399 | warning_range ? warning_range : "", | 414 | } else { |
| 400 | critical_range ? critical_range : ""); | 415 | printf(" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); |
| 401 | else | 416 | } |
| 402 | printf (" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); | ||
| 403 | 417 | ||
| 404 | printf ("\n"); | 418 | printf("\n"); |
| 405 | return result; | 419 | return result; |
| 406 | } | 420 | } |
| 407 | 421 | ||
| 408 | |||
| 409 | |||
| 410 | /* process command-line arguments */ | 422 | /* process command-line arguments */ |
| 411 | int | 423 | int process_arguments(int argc, char **argv) { |
| 412 | process_arguments (int argc, char **argv) | ||
| 413 | { | ||
| 414 | int c = 1; | 424 | int c = 1; |
| 415 | char *user; | 425 | char *user; |
| 416 | struct passwd *pw; | 426 | struct passwd *pw; |
| @@ -419,260 +429,262 @@ process_arguments (int argc, char **argv) | |||
| 419 | int cflags = REG_NOSUB | REG_EXTENDED; | 429 | int cflags = REG_NOSUB | REG_EXTENDED; |
| 420 | char errbuf[MAX_INPUT_BUFFER]; | 430 | char errbuf[MAX_INPUT_BUFFER]; |
| 421 | char *temp_string; | 431 | char *temp_string; |
| 422 | int i=0; | 432 | int i = 0; |
| 423 | static struct option longopts[] = { | 433 | static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, |
| 424 | {"warning", required_argument, 0, 'w'}, | 434 | {"critical", required_argument, 0, 'c'}, |
| 425 | {"critical", required_argument, 0, 'c'}, | 435 | {"metric", required_argument, 0, 'm'}, |
| 426 | {"metric", required_argument, 0, 'm'}, | 436 | {"timeout", required_argument, 0, 't'}, |
| 427 | {"timeout", required_argument, 0, 't'}, | 437 | {"status", required_argument, 0, 's'}, |
| 428 | {"status", required_argument, 0, 's'}, | 438 | {"ppid", required_argument, 0, 'p'}, |
| 429 | {"ppid", required_argument, 0, 'p'}, | 439 | {"user", required_argument, 0, 'u'}, |
| 430 | {"user", required_argument, 0, 'u'}, | 440 | {"command", required_argument, 0, 'C'}, |
| 431 | {"command", required_argument, 0, 'C'}, | 441 | {"vsz", required_argument, 0, 'z'}, |
| 432 | {"vsz", required_argument, 0, 'z'}, | 442 | {"rss", required_argument, 0, 'r'}, |
| 433 | {"rss", required_argument, 0, 'r'}, | 443 | {"pcpu", required_argument, 0, 'P'}, |
| 434 | {"pcpu", required_argument, 0, 'P'}, | 444 | {"elapsed", required_argument, 0, 'e'}, |
| 435 | {"elapsed", required_argument, 0, 'e'}, | 445 | {"argument-array", required_argument, 0, 'a'}, |
| 436 | {"argument-array", required_argument, 0, 'a'}, | 446 | {"help", no_argument, 0, 'h'}, |
| 437 | {"help", no_argument, 0, 'h'}, | 447 | {"version", no_argument, 0, 'V'}, |
| 438 | {"version", no_argument, 0, 'V'}, | 448 | {"verbose", no_argument, 0, 'v'}, |
| 439 | {"verbose", no_argument, 0, 'v'}, | 449 | {"ereg-argument-array", required_argument, 0, CHAR_MAX + 1}, |
| 440 | {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, | 450 | {"input-file", required_argument, 0, CHAR_MAX + 2}, |
| 441 | {"input-file", required_argument, 0, CHAR_MAX+2}, | 451 | {"no-kthreads", required_argument, 0, 'k'}, |
| 442 | {"no-kthreads", required_argument, 0, 'k'}, | 452 | {"traditional-filter", no_argument, 0, 'T'}, |
| 443 | {"traditional-filter", no_argument, 0, 'T'}, | 453 | {"exclude-process", required_argument, 0, 'X'}, |
| 444 | {"exclude-process", required_argument, 0, 'X'}, | 454 | {0, 0, 0, 0}}; |
| 445 | {0, 0, 0, 0} | 455 | |
| 446 | }; | 456 | for (c = 1; c < argc; c++) { |
| 447 | 457 | if (strcmp("-to", argv[c]) == 0) { | |
| 448 | for (c = 1; c < argc; c++) | 458 | strcpy(argv[c], "-t"); |
| 449 | if (strcmp ("-to", argv[c]) == 0) | 459 | } |
| 450 | strcpy (argv[c], "-t"); | 460 | } |
| 451 | 461 | ||
| 452 | while (1) { | 462 | while (1) { |
| 453 | c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", | 463 | c = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); |
| 454 | longopts, &option); | ||
| 455 | 464 | ||
| 456 | if (c == -1 || c == EOF) | 465 | if (c == -1 || c == EOF) { |
| 457 | break; | 466 | break; |
| 467 | } | ||
| 458 | 468 | ||
| 459 | switch (c) { | 469 | switch (c) { |
| 460 | case '?': /* help */ | 470 | case '?': /* help */ |
| 461 | usage5 (); | 471 | usage5(); |
| 462 | case 'h': /* help */ | 472 | case 'h': /* help */ |
| 463 | print_help (); | 473 | print_help(); |
| 464 | exit (STATE_UNKNOWN); | 474 | exit(STATE_UNKNOWN); |
| 465 | case 'V': /* version */ | 475 | case 'V': /* version */ |
| 466 | print_revision (progname, NP_VERSION); | 476 | print_revision(progname, NP_VERSION); |
| 467 | exit (STATE_UNKNOWN); | 477 | exit(STATE_UNKNOWN); |
| 468 | case 't': /* timeout period */ | 478 | case 't': /* timeout period */ |
| 469 | if (!is_integer (optarg)) | 479 | if (!is_integer(optarg)) { |
| 470 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 480 | usage2(_("Timeout interval must be a positive integer"), optarg); |
| 471 | else | 481 | } else { |
| 472 | timeout_interval = atoi (optarg); | 482 | timeout_interval = atoi(optarg); |
| 483 | } | ||
| 473 | break; | 484 | break; |
| 474 | case 'c': /* critical threshold */ | 485 | case 'c': /* critical threshold */ |
| 475 | critical_range = optarg; | 486 | critical_range = optarg; |
| 476 | break; | 487 | break; |
| 477 | case 'w': /* warning threshold */ | 488 | case 'w': /* warning threshold */ |
| 478 | warning_range = optarg; | 489 | warning_range = optarg; |
| 479 | break; | 490 | break; |
| 480 | case 'p': /* process id */ | 491 | case 'p': /* process id */ |
| 481 | if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) { | 492 | if (sscanf(optarg, "%d%[^0-9]", &ppid, tmp) == 1) { |
| 482 | xasprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid); | 493 | xasprintf(&fmt, "%s%sPPID = %d", (fmt ? fmt : ""), (options ? ", " : ""), ppid); |
| 483 | options |= PPID; | 494 | options |= PPID; |
| 484 | break; | 495 | break; |
| 485 | } | 496 | } |
| 486 | usage4 (_("Parent Process ID must be an integer!")); | 497 | usage4(_("Parent Process ID must be an integer!")); |
| 487 | case 's': /* status */ | 498 | case 's': /* status */ |
| 488 | if (statopts) | 499 | if (statopts) { |
| 489 | break; | 500 | break; |
| 490 | else | 501 | } else { |
| 491 | statopts = optarg; | 502 | statopts = optarg; |
| 492 | xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 503 | } |
| 504 | xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | ||
| 493 | options |= STAT; | 505 | options |= STAT; |
| 494 | break; | 506 | break; |
| 495 | case 'u': /* user or user id */ | 507 | case 'u': /* user or user id */ |
| 496 | if (is_integer (optarg)) { | 508 | if (is_integer(optarg)) { |
| 497 | uid = atoi (optarg); | 509 | uid = atoi(optarg); |
| 498 | pw = getpwuid ((uid_t) uid); | 510 | pw = getpwuid((uid_t)uid); |
| 499 | /* check to be sure user exists */ | 511 | /* check to be sure user exists */ |
| 500 | if (pw == NULL) | 512 | if (pw == NULL) { |
| 501 | usage2 (_("UID was not found"), optarg); | 513 | usage2(_("UID was not found"), optarg); |
| 502 | } | 514 | } |
| 503 | else { | 515 | } else { |
| 504 | pw = getpwnam (optarg); | 516 | pw = getpwnam(optarg); |
| 505 | /* check to be sure user exists */ | 517 | /* check to be sure user exists */ |
| 506 | if (pw == NULL) | 518 | if (pw == NULL) { |
| 507 | usage2 (_("User name was not found"), optarg); | 519 | usage2(_("User name was not found"), optarg); |
| 520 | } | ||
| 508 | /* then get uid */ | 521 | /* then get uid */ |
| 509 | uid = pw->pw_uid; | 522 | uid = pw->pw_uid; |
| 510 | } | 523 | } |
| 511 | user = pw->pw_name; | 524 | user = pw->pw_name; |
| 512 | xasprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), | 525 | xasprintf(&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), uid, user); |
| 513 | uid, user); | ||
| 514 | options |= USER; | 526 | options |= USER; |
| 515 | break; | 527 | break; |
| 516 | case 'C': /* command */ | 528 | case 'C': /* command */ |
| 517 | /* TODO: allow this to be passed in with --metric */ | 529 | /* TODO: allow this to be passed in with --metric */ |
| 518 | if (prog) | 530 | if (prog) { |
| 519 | break; | 531 | break; |
| 520 | else | 532 | } else { |
| 521 | prog = optarg; | 533 | prog = optarg; |
| 522 | xasprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), | 534 | } |
| 523 | prog); | 535 | xasprintf(&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), prog); |
| 524 | options |= PROG; | 536 | options |= PROG; |
| 525 | break; | 537 | break; |
| 526 | case 'X': | 538 | case 'X': |
| 527 | if(exclude_progs) | 539 | if (exclude_progs) { |
| 528 | break; | 540 | break; |
| 529 | else | 541 | } else { |
| 530 | exclude_progs = optarg; | 542 | exclude_progs = optarg; |
| 531 | xasprintf (&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), | 543 | } |
| 532 | exclude_progs); | 544 | xasprintf(&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), exclude_progs); |
| 533 | char *p = strtok(exclude_progs, ","); | 545 | char *p = strtok(exclude_progs, ","); |
| 534 | 546 | ||
| 535 | while(p){ | 547 | while (p) { |
| 536 | exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char*) * ++exclude_progs_counter); | 548 | exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char *) * ++exclude_progs_counter); |
| 537 | exclude_progs_arr[exclude_progs_counter-1] = p; | 549 | exclude_progs_arr[exclude_progs_counter - 1] = p; |
| 538 | p = strtok(NULL, ","); | 550 | p = strtok(NULL, ","); |
| 539 | } | 551 | } |
| 540 | 552 | ||
| 541 | options |= EXCLUDE_PROGS; | 553 | options |= EXCLUDE_PROGS; |
| 542 | break; | 554 | break; |
| 543 | case 'a': /* args (full path name with args) */ | 555 | case 'a': /* args (full path name with args) */ |
| 544 | /* TODO: allow this to be passed in with --metric */ | 556 | /* TODO: allow this to be passed in with --metric */ |
| 545 | if (args) | 557 | if (args) { |
| 546 | break; | 558 | break; |
| 547 | else | 559 | } else { |
| 548 | args = optarg; | 560 | args = optarg; |
| 549 | xasprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); | 561 | } |
| 562 | xasprintf(&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); | ||
| 550 | options |= ARGS; | 563 | options |= ARGS; |
| 551 | break; | 564 | break; |
| 552 | case CHAR_MAX+1: | 565 | case CHAR_MAX + 1: |
| 553 | err = regcomp(&re_args, optarg, cflags); | 566 | err = regcomp(&re_args, optarg, cflags); |
| 554 | if (err != 0) { | 567 | if (err != 0) { |
| 555 | regerror (err, &re_args, errbuf, MAX_INPUT_BUFFER); | 568 | regerror(err, &re_args, errbuf, MAX_INPUT_BUFFER); |
| 556 | die (STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 569 | die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); |
| 557 | } | 570 | } |
| 558 | /* Strip off any | within the regex optarg */ | 571 | /* Strip off any | within the regex optarg */ |
| 559 | temp_string = strdup(optarg); | 572 | temp_string = strdup(optarg); |
| 560 | while(temp_string[i]!='\0'){ | 573 | while (temp_string[i] != '\0') { |
| 561 | if(temp_string[i]=='|') | 574 | if (temp_string[i] == '|') { |
| 562 | temp_string[i]=','; | 575 | temp_string[i] = ','; |
| 576 | } | ||
| 563 | i++; | 577 | i++; |
| 564 | } | 578 | } |
| 565 | xasprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); | 579 | xasprintf(&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); |
| 566 | options |= EREG_ARGS; | 580 | options |= EREG_ARGS; |
| 567 | break; | 581 | break; |
| 568 | case 'r': /* RSS */ | 582 | case 'r': /* RSS */ |
| 569 | if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) { | 583 | if (sscanf(optarg, "%d%[^0-9]", &rss, tmp) == 1) { |
| 570 | xasprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); | 584 | xasprintf(&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); |
| 571 | options |= RSS; | 585 | options |= RSS; |
| 572 | break; | 586 | break; |
| 573 | } | 587 | } |
| 574 | usage4 (_("RSS must be an integer!")); | 588 | usage4(_("RSS must be an integer!")); |
| 575 | case 'z': /* VSZ */ | 589 | case 'z': /* VSZ */ |
| 576 | if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) { | 590 | if (sscanf(optarg, "%d%[^0-9]", &vsz, tmp) == 1) { |
| 577 | xasprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz); | 591 | xasprintf(&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz); |
| 578 | options |= VSZ; | 592 | options |= VSZ; |
| 579 | break; | 593 | break; |
| 580 | } | 594 | } |
| 581 | usage4 (_("VSZ must be an integer!")); | 595 | usage4(_("VSZ must be an integer!")); |
| 582 | case 'P': /* PCPU */ | 596 | case 'P': /* PCPU */ |
| 583 | /* TODO: -P 1.5.5 is accepted */ | 597 | /* TODO: -P 1.5.5 is accepted */ |
| 584 | if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) { | 598 | if (sscanf(optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) { |
| 585 | xasprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu); | 599 | xasprintf(&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu); |
| 586 | options |= PCPU; | 600 | options |= PCPU; |
| 587 | break; | 601 | break; |
| 588 | } | 602 | } |
| 589 | usage4 (_("PCPU must be a float!")); | 603 | usage4(_("PCPU must be a float!")); |
| 590 | case 'm': | 604 | case 'm': |
| 591 | xasprintf (&metric_name, "%s", optarg); | 605 | xasprintf(&metric_name, "%s", optarg); |
| 592 | if ( strcmp(optarg, "PROCS") == 0) { | 606 | if (strcmp(optarg, "PROCS") == 0) { |
| 593 | metric = METRIC_PROCS; | 607 | metric = METRIC_PROCS; |
| 594 | break; | 608 | break; |
| 595 | } | 609 | } else if (strcmp(optarg, "VSZ") == 0) { |
| 596 | else if ( strcmp(optarg, "VSZ") == 0) { | ||
| 597 | metric = METRIC_VSZ; | 610 | metric = METRIC_VSZ; |
| 598 | break; | 611 | break; |
| 599 | } | 612 | } else if (strcmp(optarg, "RSS") == 0) { |
| 600 | else if ( strcmp(optarg, "RSS") == 0 ) { | ||
| 601 | metric = METRIC_RSS; | 613 | metric = METRIC_RSS; |
| 602 | break; | 614 | break; |
| 603 | } | 615 | } else if (strcmp(optarg, "CPU") == 0) { |
| 604 | else if ( strcmp(optarg, "CPU") == 0 ) { | ||
| 605 | metric = METRIC_CPU; | 616 | metric = METRIC_CPU; |
| 606 | break; | 617 | break; |
| 607 | } | 618 | } else if (strcmp(optarg, "ELAPSED") == 0) { |
| 608 | else if ( strcmp(optarg, "ELAPSED") == 0) { | ||
| 609 | metric = METRIC_ELAPSED; | 619 | metric = METRIC_ELAPSED; |
| 610 | break; | 620 | break; |
| 611 | } | 621 | } |
| 612 | 622 | ||
| 613 | usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); | 623 | usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); |
| 614 | case 'k': /* linux kernel thread filter */ | 624 | case 'k': /* linux kernel thread filter */ |
| 615 | kthread_filter = 1; | 625 | kthread_filter = 1; |
| 616 | break; | 626 | break; |
| 617 | case 'v': /* command */ | 627 | case 'v': /* command */ |
| 618 | verbose++; | 628 | verbose++; |
| 619 | break; | 629 | break; |
| 620 | case 'T': | 630 | case 'T': |
| 621 | usepid = 1; | 631 | usepid = 1; |
| 622 | break; | 632 | break; |
| 623 | case CHAR_MAX+2: | 633 | case CHAR_MAX + 2: |
| 624 | input_filename = optarg; | 634 | input_filename = optarg; |
| 625 | break; | 635 | break; |
| 626 | } | 636 | } |
| 627 | } | 637 | } |
| 628 | 638 | ||
| 629 | c = optind; | 639 | c = optind; |
| 630 | if ((! warning_range) && argv[c]) | 640 | if ((!warning_range) && argv[c]) { |
| 631 | warning_range = argv[c++]; | 641 | warning_range = argv[c++]; |
| 632 | if ((! critical_range) && argv[c]) | 642 | } |
| 643 | if ((!critical_range) && argv[c]) { | ||
| 633 | critical_range = argv[c++]; | 644 | critical_range = argv[c++]; |
| 645 | } | ||
| 634 | if (statopts == NULL && argv[c]) { | 646 | if (statopts == NULL && argv[c]) { |
| 635 | xasprintf (&statopts, "%s", argv[c++]); | 647 | xasprintf(&statopts, "%s", argv[c++]); |
| 636 | xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 648 | xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); |
| 637 | options |= STAT; | 649 | options |= STAT; |
| 638 | } | 650 | } |
| 639 | 651 | ||
| 640 | /* this will abort in case of invalid ranges */ | 652 | /* this will abort in case of invalid ranges */ |
| 641 | set_thresholds (&procs_thresholds, warning_range, critical_range); | 653 | set_thresholds(&procs_thresholds, warning_range, critical_range); |
| 642 | 654 | ||
| 643 | return validate_arguments (); | 655 | return validate_arguments(); |
| 644 | } | 656 | } |
| 645 | 657 | ||
| 646 | 658 | int validate_arguments() { | |
| 647 | 659 | if (options == 0) { | |
| 648 | int | ||
| 649 | validate_arguments () | ||
| 650 | { | ||
| 651 | if (options == 0) | ||
| 652 | options = ALL; | 660 | options = ALL; |
| 661 | } | ||
| 653 | 662 | ||
| 654 | if (statopts==NULL) | 663 | if (statopts == NULL) { |
| 655 | statopts = strdup(""); | 664 | statopts = strdup(""); |
| 665 | } | ||
| 656 | 666 | ||
| 657 | if (prog==NULL) | 667 | if (prog == NULL) { |
| 658 | prog = strdup(""); | 668 | prog = strdup(""); |
| 669 | } | ||
| 659 | 670 | ||
| 660 | if (args==NULL) | 671 | if (args == NULL) { |
| 661 | args = strdup(""); | 672 | args = strdup(""); |
| 673 | } | ||
| 662 | 674 | ||
| 663 | if (fmt==NULL) | 675 | if (fmt == NULL) { |
| 664 | fmt = strdup(""); | 676 | fmt = strdup(""); |
| 677 | } | ||
| 665 | 678 | ||
| 666 | if (fails==NULL) | 679 | if (fails == NULL) { |
| 667 | fails = strdup(""); | 680 | fails = strdup(""); |
| 681 | } | ||
| 668 | 682 | ||
| 669 | return options; | 683 | return options; |
| 670 | } | 684 | } |
| 671 | 685 | ||
| 672 | |||
| 673 | /* convert the elapsed time to seconds */ | 686 | /* convert the elapsed time to seconds */ |
| 674 | int | 687 | int convert_to_seconds(char *etime) { |
| 675 | convert_to_seconds(char *etime) { | ||
| 676 | 688 | ||
| 677 | char *ptr; | 689 | char *ptr; |
| 678 | int total; | 690 | int total; |
| @@ -704,8 +716,7 @@ convert_to_seconds(char *etime) { | |||
| 704 | } | 716 | } |
| 705 | 717 | ||
| 706 | if (hyphcnt > 0) { | 718 | if (hyphcnt > 0) { |
| 707 | sscanf(etime, "%d-%d:%d:%d", | 719 | sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds); |
| 708 | &days, &hours, &minutes, &seconds); | ||
| 709 | /* linux 2.6.5/2.6.6 reporting some processes with infinite | 720 | /* linux 2.6.5/2.6.6 reporting some processes with infinite |
| 710 | * elapsed times for some reason */ | 721 | * elapsed times for some reason */ |
| 711 | if (days == 49710) { | 722 | if (days == 49710) { |
| @@ -713,135 +724,125 @@ convert_to_seconds(char *etime) { | |||
| 713 | } | 724 | } |
| 714 | } else { | 725 | } else { |
| 715 | if (coloncnt == 2) { | 726 | if (coloncnt == 2) { |
| 716 | sscanf(etime, "%d:%d:%d", | 727 | sscanf(etime, "%d:%d:%d", &hours, &minutes, &seconds); |
| 717 | &hours, &minutes, &seconds); | ||
| 718 | } else if (coloncnt == 1) { | 728 | } else if (coloncnt == 1) { |
| 719 | sscanf(etime, "%d:%d", | 729 | sscanf(etime, "%d:%d", &minutes, &seconds); |
| 720 | &minutes, &seconds); | ||
| 721 | } | 730 | } |
| 722 | } | 731 | } |
| 723 | 732 | ||
| 724 | total = (days * 86400) + | 733 | total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds; |
| 725 | (hours * 3600) + | ||
| 726 | (minutes * 60) + | ||
| 727 | seconds; | ||
| 728 | 734 | ||
| 729 | if (verbose >= 3 && metric == METRIC_ELAPSED) { | 735 | if (verbose >= 3 && metric == METRIC_ELAPSED) { |
| 730 | printf("seconds: %d\n", total); | 736 | printf("seconds: %d\n", total); |
| 731 | } | 737 | } |
| 732 | return total; | 738 | return total; |
| 733 | } | 739 | } |
| 734 | 740 | ||
| 741 | void print_help(void) { | ||
| 742 | print_revision(progname, NP_VERSION); | ||
| 735 | 743 | ||
| 736 | void | 744 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); |
| 737 | print_help (void) | 745 | printf(COPYRIGHT, copyright, email); |
| 738 | { | ||
| 739 | print_revision (progname, NP_VERSION); | ||
| 740 | |||
| 741 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | ||
| 742 | printf (COPYRIGHT, copyright, email); | ||
| 743 | 746 | ||
| 744 | printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); | 747 | printf("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); |
| 745 | printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number")); | 748 | printf("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number")); |
| 746 | printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check.")); | 749 | printf("%s\n", _("of processes. Search filters can be applied to limit the processes to check.")); |
| 747 | 750 | ||
| 748 | printf ("\n\n"); | 751 | printf("\n\n"); |
| 749 | 752 | ||
| 750 | printf ("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)")); | 753 | printf("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)")); |
| 751 | printf ("%s\n", _("are excluded from any checks to prevent false positives.")); | 754 | printf("%s\n", _("are excluded from any checks to prevent false positives.")); |
| 752 | 755 | ||
| 753 | printf ("\n\n"); | 756 | printf("\n\n"); |
| 754 | 757 | ||
| 755 | print_usage (); | 758 | print_usage(); |
| 756 | 759 | ||
| 757 | printf (UT_HELP_VRSN); | 760 | printf(UT_HELP_VRSN); |
| 758 | printf (UT_EXTRA_OPTS); | 761 | printf(UT_EXTRA_OPTS); |
| 759 | printf (" %s\n", "-w, --warning=RANGE"); | 762 | printf(" %s\n", "-w, --warning=RANGE"); |
| 760 | printf (" %s\n", _("Generate warning state if metric is outside this range")); | 763 | printf(" %s\n", _("Generate warning state if metric is outside this range")); |
| 761 | printf (" %s\n", "-c, --critical=RANGE"); | 764 | printf(" %s\n", "-c, --critical=RANGE"); |
| 762 | printf (" %s\n", _("Generate critical state if metric is outside this range")); | 765 | printf(" %s\n", _("Generate critical state if metric is outside this range")); |
| 763 | printf (" %s\n", "-m, --metric=TYPE"); | 766 | printf(" %s\n", "-m, --metric=TYPE"); |
| 764 | printf (" %s\n", _("Check thresholds against metric. Valid types:")); | 767 | printf(" %s\n", _("Check thresholds against metric. Valid types:")); |
| 765 | printf (" %s\n", _("PROCS - number of processes (default)")); | 768 | printf(" %s\n", _("PROCS - number of processes (default)")); |
| 766 | printf (" %s\n", _("VSZ - virtual memory size")); | 769 | printf(" %s\n", _("VSZ - virtual memory size")); |
| 767 | printf (" %s\n", _("RSS - resident set memory size")); | 770 | printf(" %s\n", _("RSS - resident set memory size")); |
| 768 | printf (" %s\n", _("CPU - percentage CPU")); | 771 | printf(" %s\n", _("CPU - percentage CPU")); |
| 769 | /* only linux etime is support currently */ | 772 | /* only linux etime is support currently */ |
| 770 | #if defined( __linux__ ) | 773 | #if defined(__linux__) |
| 771 | printf (" %s\n", _("ELAPSED - time elapsed in seconds")); | 774 | printf(" %s\n", _("ELAPSED - time elapsed in seconds")); |
| 772 | #endif /* defined(__linux__) */ | 775 | #endif /* defined(__linux__) */ |
| 773 | printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 776 | printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 774 | 777 | ||
| 775 | printf (" %s\n", "-v, --verbose"); | 778 | printf(" %s\n", "-v, --verbose"); |
| 776 | printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); | 779 | printf(" %s\n", _("Extra information. Up to 3 verbosity levels")); |
| 777 | 780 | ||
| 778 | printf (" %s\n", "-T, --traditional"); | 781 | printf(" %s\n", "-T, --traditional"); |
| 779 | printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); | 782 | printf(" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); |
| 780 | 783 | ||
| 781 | printf ("\n"); | 784 | printf("\n"); |
| 782 | printf ("%s\n", "Filters:"); | 785 | printf("%s\n", "Filters:"); |
| 783 | printf (" %s\n", "-s, --state=STATUSFLAGS"); | 786 | printf(" %s\n", "-s, --state=STATUSFLAGS"); |
| 784 | printf (" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); | 787 | printf(" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); |
| 785 | printf (" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); | 788 | printf(" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); |
| 786 | printf (" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); | 789 | printf(" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); |
| 787 | printf (" %s\n", "-p, --ppid=PPID"); | 790 | printf(" %s\n", "-p, --ppid=PPID"); |
| 788 | printf (" %s\n", _("Only scan for children of the parent process ID indicated.")); | 791 | printf(" %s\n", _("Only scan for children of the parent process ID indicated.")); |
| 789 | printf (" %s\n", "-z, --vsz=VSZ"); | 792 | printf(" %s\n", "-z, --vsz=VSZ"); |
| 790 | printf (" %s\n", _("Only scan for processes with VSZ higher than indicated.")); | 793 | printf(" %s\n", _("Only scan for processes with VSZ higher than indicated.")); |
| 791 | printf (" %s\n", "-r, --rss=RSS"); | 794 | printf(" %s\n", "-r, --rss=RSS"); |
| 792 | printf (" %s\n", _("Only scan for processes with RSS higher than indicated.")); | 795 | printf(" %s\n", _("Only scan for processes with RSS higher than indicated.")); |
| 793 | printf (" %s\n", "-P, --pcpu=PCPU"); | 796 | printf(" %s\n", "-P, --pcpu=PCPU"); |
| 794 | printf (" %s\n", _("Only scan for processes with PCPU higher than indicated.")); | 797 | printf(" %s\n", _("Only scan for processes with PCPU higher than indicated.")); |
| 795 | printf (" %s\n", "-u, --user=USER"); | 798 | printf(" %s\n", "-u, --user=USER"); |
| 796 | printf (" %s\n", _("Only scan for processes with user name or ID indicated.")); | 799 | printf(" %s\n", _("Only scan for processes with user name or ID indicated.")); |
| 797 | printf (" %s\n", "-a, --argument-array=STRING"); | 800 | printf(" %s\n", "-a, --argument-array=STRING"); |
| 798 | printf (" %s\n", _("Only scan for processes with args that contain STRING.")); | 801 | printf(" %s\n", _("Only scan for processes with args that contain STRING.")); |
| 799 | printf (" %s\n", "--ereg-argument-array=STRING"); | 802 | printf(" %s\n", "--ereg-argument-array=STRING"); |
| 800 | printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); | 803 | printf(" %s\n", _("Only scan for processes with args that contain the regex STRING.")); |
| 801 | printf (" %s\n", "-C, --command=COMMAND"); | 804 | printf(" %s\n", "-C, --command=COMMAND"); |
| 802 | printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); | 805 | printf(" %s\n", _("Only scan for exact matches of COMMAND (without path).")); |
| 803 | printf (" %s\n", "-X, --exclude-process"); | 806 | printf(" %s\n", "-X, --exclude-process"); |
| 804 | printf (" %s\n", _("Exclude processes which match this comma separated list")); | 807 | printf(" %s\n", _("Exclude processes which match this comma separated list")); |
| 805 | printf (" %s\n", "-k, --no-kthreads"); | 808 | printf(" %s\n", "-k, --no-kthreads"); |
| 806 | printf (" %s\n", _("Only scan for non kernel threads (works on Linux only).")); | 809 | printf(" %s\n", _("Only scan for non kernel threads (works on Linux only).")); |
| 807 | 810 | ||
| 808 | printf(_("\n\ | 811 | printf(_("\n\ |
| 809 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ | 812 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ |
| 810 | specified 'max:min', a warning status will be generated if the\n\ | 813 | specified 'max:min', a warning status will be generated if the\n\ |
| 811 | count is inside the specified range\n\n")); | 814 | count is inside the specified range\n\n")); |
| 812 | 815 | ||
| 813 | printf(_("\ | 816 | printf(_("\ |
| 814 | This plugin checks the number of currently running processes and\n\ | 817 | This plugin checks the number of currently running processes and\n\ |
| 815 | generates WARNING or CRITICAL states if the process count is outside\n\ | 818 | generates WARNING or CRITICAL states if the process count is outside\n\ |
| 816 | the specified threshold ranges. The process count can be filtered by\n\ | 819 | the specified threshold ranges. The process count can be filtered by\n\ |
| 817 | process owner, parent process PID, current state (e.g., 'Z'), or may\n\ | 820 | process owner, parent process PID, current state (e.g., 'Z'), or may\n\ |
| 818 | be the total number of running processes\n\n")); | 821 | be the total number of running processes\n\n")); |
| 819 | 822 | ||
| 820 | printf ("%s\n", _("Examples:")); | 823 | printf("%s\n", _("Examples:")); |
| 821 | printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); | 824 | printf(" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); |
| 822 | printf (" %s\n", _("Warning if not two processes with command name portsentry.")); | 825 | printf(" %s\n", _("Warning if not two processes with command name portsentry.")); |
| 823 | printf (" %s\n\n", _("Critical if < 2 or > 1024 processes")); | 826 | printf(" %s\n\n", _("Critical if < 2 or > 1024 processes")); |
| 824 | printf (" %s\n", "check_procs -c 1: -C sshd"); | 827 | printf(" %s\n", "check_procs -c 1: -C sshd"); |
| 825 | printf (" %s\n", _("Critical if not at least 1 process with command sshd")); | 828 | printf(" %s\n", _("Critical if not at least 1 process with command sshd")); |
| 826 | printf (" %s\n", "check_procs -w 1024 -c 1: -C sshd"); | 829 | printf(" %s\n", "check_procs -w 1024 -c 1: -C sshd"); |
| 827 | printf (" %s\n", _("Warning if > 1024 processes with command name sshd.")); | 830 | printf(" %s\n", _("Warning if > 1024 processes with command name sshd.")); |
| 828 | printf (" %s\n\n", _("Critical if < 1 processes with command name sshd.")); | 831 | printf(" %s\n\n", _("Critical if < 1 processes with command name sshd.")); |
| 829 | printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); | 832 | printf(" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); |
| 830 | printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing")); | 833 | printf(" %s\n", _("Warning alert if > 10 processes with command arguments containing")); |
| 831 | printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); | 834 | printf(" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); |
| 832 | printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); | 835 | printf(" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); |
| 833 | printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); | 836 | printf(" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); |
| 834 | printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); | 837 | printf(" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); |
| 835 | printf (" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); | 838 | printf(" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); |
| 836 | 839 | ||
| 837 | printf (UT_SUPPORT); | 840 | printf(UT_SUPPORT); |
| 838 | } | 841 | } |
| 839 | 842 | ||
| 840 | void | 843 | void print_usage(void) { |
| 841 | print_usage (void) | 844 | printf("%s\n", _("Usage:")); |
| 842 | { | 845 | printf("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); |
| 843 | printf ("%s\n", _("Usage:")); | 846 | printf(" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); |
| 844 | printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); | 847 | printf(" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n"); |
| 845 | printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); | ||
| 846 | printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n"); | ||
| 847 | } | 848 | } |
