1st pass at check_procs with multiple threshold checks

git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/branches/new_threshold_syntax@1958 f882894a-f735-0410-b71e-b25c423dba1c
This commit is contained in:
Ton Voon 2008-03-19 14:42:12 +00:00
parent cab9440a67
commit b17b242198
5 changed files with 478 additions and 78 deletions

View file

@ -30,7 +30,7 @@ main (int argc, char **argv)
thresholds *thresholds = NULL;
int rc;
plan_tests(82);
plan_tests(172);
range = parse_range_string("6");
ok( range != NULL, "'6' is valid range");
@ -40,6 +40,32 @@ main (int argc, char **argv)
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = _parse_range_string_v2("6");
ok( range == NULL, "Missing colon in range" );
ok( utils_errno == NP_RANGE_MISSING_COLON, "Right error code" );
range = _parse_range_string_v2("6:");
ok( range != NULL, "'6:' is valid range");
ok( range->start == 6, "Start correct");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->end_infinity == TRUE, "Using infinity");
free(range);
range = _parse_range_string_v2("6:6");
ok( range != NULL, "'6:6' is valid range");
ok( range->start == 6, "Start correct");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->end == 6, "End correct");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = _parse_range_string_v2(":6");
ok( range != NULL, "':6' is valid range");
ok( range->start_infinity == TRUE, "Using negative infinity");
ok( range->end == 6, "End correct");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string("1:12%%");
ok( range != NULL, "'1:12%%' is valid - percentages are ignored");
ok( range->start == 1, "Start correct");
@ -48,6 +74,14 @@ main (int argc, char **argv)
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = _parse_range_string_v2("1:12%%");
ok( range != NULL, "'1:12%%' is valid - percentages are ignored");
ok( range->start == 1, "Start correct");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->end == 12, "End correct");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string("-7:23");
ok( range != NULL, "'-7:23' is valid range");
ok( range->start == -7, "Start correct");
@ -56,6 +90,14 @@ main (int argc, char **argv)
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = _parse_range_string_v2("-7:23");
ok( range != NULL, "'-7:23' is valid range");
ok( range->start == -7, "Start correct");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->end == 23, "End correct");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string(":5.75");
ok( range != NULL, "':5.75' is valid range");
ok( range->start == 0, "Start correct");
@ -64,6 +106,14 @@ main (int argc, char **argv)
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = _parse_range_string_v2(":5.75");
ok( range != NULL, "':5.75' is valid range");
ok( range->start == 0, "Start correct");
ok( range->start_infinity == TRUE, "Using negative infinity");
ok( range->end == 5.75, "End correct");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string("~:-95.99");
ok( range != NULL, "~:-95.99' is valid range");
ok( range->start_infinity == TRUE, "Using negative infinity");
@ -71,6 +121,26 @@ main (int argc, char **argv)
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = _parse_range_string_v2("~:-95.99");
ok( range == NULL, "~:-95.99' is invalid range");
ok( utils_errno == NP_RANGE_UNPARSEABLE, "Correct error code" );
/*
* This is currently parseable. This is because ~ is interpreted as a 0
* and then 95.99 is the end, so we get 0:95.99. Should validate the characters before
* passing to strtod
range = _parse_range_string_v2("~:95.99");
ok( range == NULL, "~:95.99' is invalid range");
ok( utils_errno == NP_RANGE_UNPARSEABLE, "Correct error code" );
*/
range = _parse_range_string_v2(":-95.99");
ok( range != NULL, ":-95.99' is valid range");
ok( range->start_infinity == TRUE, "Using negative infinity");
ok( range->end == -95.99, "End correct (with rounding errors)");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string("12345678901234567890:");
temp = atof("12345678901234567890"); /* Can't just use this because number too large */
ok( range != NULL, "'12345678901234567890:' is valid range");
@ -83,6 +153,14 @@ main (int argc, char **argv)
ok( check_range(temp*2, range) == FALSE, "12345678901234567890*2 - no alert");
free(range);
range = _parse_range_string_v2("12345678901234567890:");
temp = atof("12345678901234567890");
ok( range != NULL, "'12345678901234567890:' is valid range");
ok( range->start == temp, "Start correct");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->end_infinity == TRUE, "Using infinity");
free(range);
range = parse_range_string("~:0");
ok( range != NULL, "'~:0' is valid range");
ok( range->start_infinity == TRUE, "Using negative infinity");
@ -94,8 +172,16 @@ main (int argc, char **argv)
ok( check_range(0, range) == FALSE, "0 - no alert");
free(range);
range = _parse_range_string_v2("-4.33:-4.33");
ok( range != NULL, "'-4.33:-4.33' is valid range");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->start == -4.33, "Start right");
ok( range->end == -4.33, "End correct");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string("@0:657.8210567");
ok( range != 0, "@0:657.8210567' is a valid range");
ok( range != NULL, "@0:657.8210567' is a valid range");
ok( range->start == 0, "Start correct");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->end == 657.8210567, "End correct");
@ -107,6 +193,14 @@ main (int argc, char **argv)
ok( check_range(0, range) == TRUE, "0 - alert");
free(range);
range = parse_range_string("^0:657.8210567");
ok( range != NULL, "^0:657.8210567' is a valid range");
ok( range->start == 0, "Start correct");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->end == 657.8210567, "End correct");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string("1:1");
ok( range != NULL, "'1:1' is a valid range");
ok( range->start == 1, "Start correct");
@ -121,22 +215,71 @@ main (int argc, char **argv)
range = parse_range_string("2:1");
ok( range == NULL, "'2:1' rejected");
range = _parse_range_string_v2("2:1");
ok( range == NULL, "'2:1' rejected");
ok( utils_errno == NP_RANGE_UNPARSEABLE, "Errno correct" );
rc = _set_thresholds(&thresholds, NULL, NULL);
ok( rc == 0, "Thresholds (NULL, NULL) set");
ok( thresholds->warning == NULL, "Warning not set");
ok( thresholds->critical == NULL, "Critical not set");
thresholds = _parse_thresholds_string(NULL);
ok( thresholds != NULL, "Threshold still set, even though NULL");
ok( thresholds->warning == NULL, "Warning set to NULL");
ok( thresholds->critical == NULL, "Critical set to NULL");
thresholds = _parse_thresholds_string("");
ok( thresholds != NULL, "Threshold still set, even though ''");
ok( thresholds->warning == NULL, "Warning set to NULL");
ok( thresholds->critical == NULL, "Critical set to NULL");
thresholds = _parse_thresholds_string("/");
ok( thresholds != NULL, "Threshold still set, even though '/'");
ok( thresholds->warning == NULL, "Warning set to NULL");
ok( thresholds->critical == NULL, "Critical set to NULL");
rc = _set_thresholds(&thresholds, NULL, "80");
ok( rc == 0, "Thresholds (NULL, '80') set");
ok( thresholds->warning == NULL, "Warning not set");
ok( thresholds->critical->end == 80, "Critical set correctly");
thresholds = _parse_thresholds_string(":80/");
ok( thresholds != NULL, "Threshold set for ':80/'");
ok( thresholds->warning == NULL, "Warning set to NULL");
ok( thresholds->critical->start_infinity == TRUE, "Start is right" );
ok( thresholds->critical->end == 80, "Critical set to 80");
thresholds = _parse_thresholds_string(":80");
ok( thresholds != NULL, "Threshold set for ':80'");
ok( thresholds->warning == NULL, "Warning set to NULL");
ok( thresholds->critical->start_infinity == TRUE, "Start is right" );
ok( thresholds->critical->end == 80, "Critical set to 80");
thresholds = _parse_thresholds_string("80");
ok( thresholds == NULL, "Threshold not set because of single value '80'");
ok( utils_errno == NP_RANGE_MISSING_COLON, "Correct error message");
rc = _set_thresholds(&thresholds, "5:33", NULL);
ok( rc == 0, "Thresholds ('5:33', NULL) set");
ok( thresholds->warning->start == 5, "Warning start set");
ok( thresholds->warning->end == 33, "Warning end set");
ok( thresholds->critical == NULL, "Critical not set");
thresholds = _parse_thresholds_string("5:33");
ok( thresholds != NULL, "Threshold set for '5:33'");
ok( thresholds->warning == NULL, "Warning set to NULL");
ok( thresholds->critical->start_infinity == FALSE, "Start is right" );
ok( thresholds->critical->start == 5, "Critical set to 5");
ok( thresholds->critical->end == 33, "Critical set to 33");
thresholds = _parse_thresholds_string("/5:33");
ok( thresholds != NULL, "Threshold set for '/5:33'");
ok( thresholds->critical == NULL, "Critical set to NULL");
ok( thresholds->warning->start_infinity == FALSE, "Start is right" );
ok( thresholds->warning->start == 5, "Warning start set to 5");
ok( thresholds->warning->end == 33, "Warning end set to 33");
rc = _set_thresholds(&thresholds, "30", "60");
ok( rc == 0, "Thresholds ('30', '60') set");
ok( thresholds->warning->end == 30, "Warning set correctly");
@ -145,6 +288,17 @@ main (int argc, char **argv)
ok( get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning");
ok( get_status(69, thresholds) == STATE_CRITICAL, "69 - critical");
thresholds = _parse_thresholds_string("-6.7:29 / 235.4:3333.33");
ok( thresholds != NULL, "Threshold set for '-6.7:29 / 235.4:3333.33'");
ok( thresholds->critical->start_infinity == FALSE, "Critical not starting at infinity");
ok( thresholds->critical->start == -6.7, "Critical start right" );
ok( thresholds->critical->end_infinity == FALSE, "Critical not ending at infinity");
ok( thresholds->critical->end == 29, "Critical end right" );
ok( thresholds->warning->start_infinity == FALSE, "Start is right" );
ok( thresholds->warning->start == 235.4, "Warning set to 5");
ok( thresholds->warning->end_infinity == FALSE, "End is right" );
ok( thresholds->warning->end == 3333.33, "Warning set to 33");
char *test;
test = np_escaped_string("bob\\n");
ok( strcmp(test, "bob\n") == 0, "bob\\n ok");

View file

@ -98,6 +98,138 @@ range
return NULL;
}
/* New range string parsing routines, for the v2 thresholds syntax */
/* Returns range if OK, otherwise errors. Sets utils_errno if error */
int utils_errno;
range *
_parse_range_string_v2 (char *str) {
range *temp_range;
double start;
double end;
char *end_str;
temp_range = (range *) malloc(sizeof(range));
/* Initialise */
temp_range->start = 0;
temp_range->start_infinity = FALSE;
temp_range->end = 0;
temp_range->end_infinity = FALSE;
temp_range->alert_on = INSIDE;
if (str[0] == '^') {
temp_range->alert_on = OUTSIDE;
str++;
}
end_str = index(str, ':');
if (end_str == NULL) {
utils_errno = NP_RANGE_MISSING_COLON;
free(temp_range);
temp_range = NULL;
return NULL;
}
end_str++;
if (str[0] == ':') {
temp_range->start_infinity = TRUE;
} else {
start = strtod(str, NULL); /* Will stop at ':' */
set_range_start(temp_range, start);
}
if (strcmp(end_str, "") != 0) {
end = strtod(end_str, NULL);
set_range_end(temp_range, end);
} else {
temp_range->end_infinity = TRUE;
}
if (temp_range->start_infinity == TRUE ||
temp_range->end_infinity == TRUE ||
temp_range->start <= temp_range->end) {
return temp_range;
}
free(temp_range);
temp_range = NULL;
utils_errno = NP_RANGE_UNPARSEABLE;
return NULL;
}
void
_die_on_parse_error(int errorcode) {
switch (errorcode) {
case NP_RANGE_UNPARSEABLE:
die(STATE_UNKNOWN, _("Range format incorrect\n"));
case NP_WARN_WITHIN_CRIT:
die(STATE_UNKNOWN, _("Warning level is a subset of critical and will not be alerted\n"));
case NP_RANGE_MISSING_COLON:
die(STATE_UNKNOWN, _("Range is missing a colon\n"));
case NP_MEMORY_ERROR:
die(STATE_UNKNOWN, _("Memory error\n"));
}
}
thresholds
*_parse_thresholds_string(char *string) {
thresholds *temp_thresholds = NULL;
char *separator = NULL;
char *temp_string = NULL;
range *temp_range = NULL;
int rc;
temp_thresholds = malloc(sizeof(temp_thresholds));
if (temp_thresholds == NULL) {
utils_errno = NP_MEMORY_ERROR;
return NULL;
}
temp_thresholds->warning = NULL;
temp_thresholds->critical = NULL;
if (string == NULL || strcmp(string, "") == 0)
return temp_thresholds;
if((temp_string = strdup(string)) == NULL) {
free(temp_thresholds);
utils_errno = NP_MEMORY_ERROR;
return NULL;
}
/* Find critical part and parse the range */
separator = index(temp_string, '/');
if (separator) {
*separator = '\0';
separator++;
}
if ((strcmp(temp_string, "") != 0) && (temp_range = _parse_range_string_v2( temp_string )) == NULL) {
free(temp_thresholds);
free(temp_string);
/* utils_errno already set */
return NULL;
}
temp_thresholds->critical = temp_range;
if (separator == NULL || strcmp(separator, "") == 0) {
return temp_thresholds;
}
/* UOM not processed yet */
if(( temp_range = _parse_range_string_v2( separator )) == NULL) {
free(temp_thresholds);
free(temp_string);
return NULL;
}
temp_thresholds->warning = temp_range;
return temp_thresholds;
}
thresholds
*parse_thresholds_string(char *string)
{
thresholds *my_threshold;
if ((my_threshold = _parse_thresholds_string(string)) == NULL)
_die_on_parse_error(utils_errno);
return my_threshold;
}
/* returns 0 if okay, otherwise 1 */
int
_set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
@ -139,8 +271,7 @@ set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_str
}
}
void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
printf("%s - ", threshold_name);
void print_thresholds(thresholds *my_threshold) {
if (! my_threshold) {
printf("Threshold not set");
} else {

View file

@ -31,7 +31,7 @@ typedef struct thresholds_struct {
range *parse_range_string (char *);
int _set_thresholds(thresholds **, char *, char *);
void set_thresholds(thresholds **, char *, char *);
void print_thresholds(const char *, thresholds *);
void print_thresholds(thresholds *);
int check_range(double, range *);
int get_status(double, thresholds *);
@ -39,9 +39,22 @@ char *np_escaped_string (const char *);
void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3)));
/* Return codes for _set_thresholds */
#define NP_RANGE_UNPARSEABLE 1
#define NP_WARN_WITHIN_CRIT 2
/* Parses a threshold string, as entered from command line */
/* Returns a malloc'd threshold* which can be freed */
thresholds *parse_thresholds_string(char *);
thresholds * _parse_thresholds_string(char *);
void free_thresholds(thresholds *);
range * _parse_range_string_v2(char *);
int utils_errno;
/* Error codes */
#define NP_RANGE_UNPARSEABLE 1
#define NP_WARN_WITHIN_CRIT 2
#define NP_RANGE_MISSING_COLON 3
#define NP_THRESHOLD_UNPARSEABLE 4
#define NP_MEMORY_ERROR 5
/* a simple check to see if we're running as root.
* returns zero on failure, nonzero on success */

View file

@ -80,7 +80,7 @@ int main(int argc, char **argv){
/* Initialize the thresholds */
set_thresholds(&thresholds, warn_threshold, crit_threshold);
if(verbose)
print_thresholds("check_cluster", thresholds);
print_thresholds(thresholds);
/* check the data values */
for(ptr=strtok(data_vals,",");ptr!=NULL;ptr=strtok(NULL,",")){

View file

@ -44,6 +44,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
#include "popen.h"
#include "utils.h"
#include "regex.h"
#include "utils_base.h"
#include <pwd.h>
@ -53,6 +54,7 @@ int check_thresholds (int);
int convert_to_seconds (char *);
void print_help (void);
void print_usage (void);
void actions_on_failed_state (int, char*); /* Helper routine */
int wmax = -1;
int cmax = -1;
@ -74,13 +76,16 @@ int options = 0; /* bitmask of filter criteria to test against */
/* Different metrics */
char *metric_name;
enum metric {
NONE,
DEFAULT,
METRIC_PROCS,
METRIC_VSZ,
METRIC_RSS,
METRIC_CPU,
METRIC_ELAPSED
};
enum metric metric = METRIC_PROCS;
enum metric metric = DEFAULT;
enum metric default_metric = METRIC_PROCS;
int verbose = 0;
int uid;
@ -99,6 +104,14 @@ char tmp[MAX_INPUT_BUFFER];
FILE *ps_input = NULL;
thresholds *number_threshold = NULL;
thresholds *vsz_threshold = NULL;
thresholds *rss_threshold = NULL;
thresholds *cpu_threshold = NULL;
int warn = 0; /* number of processes in warn state */
int crit = 0; /* number of processes in crit state */
int result = STATE_UNKNOWN;
int
main (int argc, char **argv)
@ -127,10 +140,14 @@ main (int argc, char **argv)
int pos; /* number of spaces before 'args' in `ps` output */
int cols; /* number of columns in ps output */
int expected_cols = PS_COLS - 1;
int warn = 0; /* number of processes in warn state */
int crit = 0; /* number of processes in crit state */
int i = 0;
int result = STATE_UNKNOWN;
int i = 0; /* Temporary values */
double rss_sum = 0;
double vsz_sum = 0;
double cpu_sum = 0;
double vsz_max = 0;
double rss_max = 0;
double cpu_max = 0;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
@ -141,7 +158,6 @@ main (int argc, char **argv)
procprog = malloc (MAX_INPUT_BUFFER);
asprintf (&metric_name, "PROCS");
metric = METRIC_PROCS;
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
@ -218,6 +234,7 @@ main (int argc, char **argv)
/* Ignore self */
if (mypid == procpid) continue;
/* Filter */
if ((options & STAT) && (strstr (statopts, procstat)))
resultsum |= STAT;
if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
@ -244,35 +261,64 @@ main (int argc, char **argv)
continue;
procs++;
if (verbose >= 2) {
if (verbose >= 3) {
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, procrss,
procpid, procppid, procpcpu, procstat,
procetime, procprog, procargs);
}
if (metric == METRIC_VSZ)
i = check_thresholds (procvsz);
else if (metric == METRIC_RSS)
i = check_thresholds (procrss);
/* Check against metric - old style single check */
if (metric == METRIC_VSZ) {
actions_on_failed_state( check_thresholds (procvsz), procprog );
} else if (metric == METRIC_RSS) {
actions_on_failed_state( check_thresholds (procrss), procprog );
/* TODO? float thresholds for --metric=CPU */
else if (metric == METRIC_CPU)
i = check_thresholds ((int)procpcpu);
else if (metric == METRIC_ELAPSED)
i = check_thresholds (procseconds);
} else if (metric == METRIC_CPU) {
actions_on_failed_state( check_thresholds ((int)procpcpu), procprog );
} else if (metric == METRIC_ELAPSED) {
actions_on_failed_state( check_thresholds (procseconds), procprog );
}
if (metric != METRIC_PROCS) {
if (i == STATE_WARNING) {
warn++;
asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
result = max_state (result, i);
}
if (i == STATE_CRITICAL) {
crit++;
asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
result = max_state (result, i);
/* Check against all new style thresholds */
if (vsz_threshold != NULL) {
if ((i = get_status( procvsz, vsz_threshold )) != STATE_OK ) {
actions_on_failed_state(i, procprog);
if (verbose >= 2) {
printf("VSZ state %d: proc=%s vsz=%d ", i, procprog, procvsz);
print_thresholds( vsz_threshold );
}
}
}
if (rss_threshold != NULL) {
if ((i = get_status( procrss, rss_threshold )) != STATE_OK ) {
actions_on_failed_state(i, procprog);
if (verbose >= 2) {
printf("RSS: proc=%s rss=%d ", procprog, procrss);
print_thresholds( rss_threshold );
}
}
}
if (cpu_threshold != NULL) {
if (( i = get_status( procpcpu, cpu_threshold )) != STATE_OK ) {
actions_on_failed_state(i, procprog);
if (verbose >= 2) {
printf("CPU: proc=%s cpu=%f ", procprog, procpcpu);
print_thresholds( cpu_threshold );
}
}
}
/* Summary information */
rss_sum += procrss;
vsz_sum += procvsz;
cpu_sum += procpcpu;
if (procrss > rss_max)
rss_max = procrss;
if (procvsz > vsz_max)
vsz_max = procvsz;
if (procpcpu > cpu_max)
cpu_max = procpcpu;
}
/* This should not happen */
else if (verbose) {
@ -308,7 +354,12 @@ main (int argc, char **argv)
/* Needed if procs found, but none match filter */
if ( metric == METRIC_PROCS ) {
result = max_state (result, check_thresholds (procs) );
result = max_state (result, i = check_thresholds (procs) );
}
if (number_threshold != NULL) {
i = get_status( procs, number_threshold );
actions_on_failed_state(i, "NUMBER_OF_PROCESSES");
}
if ( result == STATE_OK ) {
@ -316,12 +367,12 @@ main (int argc, char **argv)
} else if (result == STATE_WARNING) {
printf ("%s %s: ", metric_name, _("WARNING"));
if ( metric != METRIC_PROCS ) {
printf (_("%d warn out of "), warn);
printf (_("Alerts: %d warn from "), warn);
}
} else if (result == STATE_CRITICAL) {
printf ("%s %s: ", metric_name, _("CRITICAL"));
if (metric != METRIC_PROCS) {
printf (_("%d crit, %d warn out of "), crit, warn);
printf (_("Alerts: %d crit, %d warn from "), crit, warn);
}
}
printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs);
@ -333,6 +384,17 @@ main (int argc, char **argv)
if ( verbose >= 1 && strcmp(fails,"") )
printf (" [%s]", fails);
printf(" | ");
if( number_threshold != NULL)
printf("number=%d ", procs);
if (procs > 0) {
if( vsz_threshold != NULL)
printf("vsz=%.0f ", vsz_sum/procs);
if( rss_threshold != NULL)
printf("rss=%.0f ", rss_sum/procs);
if( cpu_threshold != NULL)
printf("cpu=%.2f ", cpu_sum/procs);
}
printf ("\n");
return result;
}
@ -368,6 +430,22 @@ process_arguments (int argc, char **argv)
{"verbose", no_argument, 0, 'v'},
{"ereg-argument-array", required_argument, 0, CHAR_MAX+1},
{"input-file", required_argument, 0, CHAR_MAX+2},
{"number", optional_argument, 0, CHAR_MAX+3},
{"rss-threshold", optional_argument, 0, CHAR_MAX+4},
/*
{"rss-max", optional_argument, 0, CHAR_MAX+5},
{"rss-sum", optional_argument, 0, CHAR_MAX+6},
*/
{"vsz-threshold", optional_argument, 0, CHAR_MAX+7},
/*
{"vsz-max", optional_argument, 0, CHAR_MAX+8},
{"vsz-sum", optional_argument, 0, CHAR_MAX+9},
*/
{"cpu-threshold", optional_argument, 0, CHAR_MAX+10},
/*
{"cpu-max", optional_argument, 0, CHAR_MAX+11},
{"cpu-sum", optional_argument, 0, CHAR_MAX+12},
*/
{0, 0, 0, 0}
};
@ -537,6 +615,26 @@ process_arguments (int argc, char **argv)
case CHAR_MAX+2:
input_filename = optarg;
break;
case CHAR_MAX+3:
number_threshold = parse_thresholds_string(optarg);
if (metric == DEFAULT)
default_metric=NONE;
break;
case CHAR_MAX+4:
rss_threshold = parse_thresholds_string(optarg);
if (metric == DEFAULT)
default_metric=NONE;
break;
case CHAR_MAX+7:
vsz_threshold = parse_thresholds_string(optarg);
if (metric == DEFAULT)
default_metric=NONE;
break;
case CHAR_MAX+10:
cpu_threshold = parse_thresholds_string(optarg);
if (metric == DEFAULT)
default_metric=NONE;
break;
}
}
@ -598,6 +696,9 @@ validate_arguments ()
if (fails==NULL)
fails = strdup("");
if (metric==DEFAULT)
metric = default_metric;
return options;
}
@ -636,6 +737,21 @@ check_thresholds (int value)
}
void
actions_on_failed_state(int state, char *procprog) {
result = max_state (result, state);
if (state != STATE_WARNING && state != STATE_CRITICAL)
return;
if (state == STATE_WARNING) {
warn++;
}
if (state == STATE_CRITICAL) {
crit++;
}
/* TODO: This should be a hash, to remove duplicates */
asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
}
/* convert the elapsed time to seconds */
int
convert_to_seconds(char *etime) {
@ -707,31 +823,21 @@ print_help (void)
printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf (COPYRIGHT, copyright, email);
printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified"));
printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number"));
printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check."));
printf ("\n\n");
print_usage ();
printf ("%s\n", _("Required Arguments:"));
printf (" %s\n", "-w, --warning=RANGE");
printf (" %s\n", _("Generate warning state if metric is outside this range"));
printf (" %s\n", "-c, --critical=RANGE");
printf (" %s\n", _("Generate critical state if metric is outside this range"));
printf ("\n\n");
printf("Checks all processes and, optionally, filters to a subset to check thresholds values against.\n");
printf("Can specify any of the following thresholds:\n");
printf(" --number=THRESHOLD - Compares the number of matching processes\n");
printf(" --vsz-threshold=THRESHOLD - Compares each process' vsz (in kilobytes)\n");
printf(" --rss-threshold=THRESHOLD - Compares each process' rss (in kilobytes)\n");
printf(" --cpu-threshold=THRESHOLD - Compares each process' cpu (in %%)\n");
/* TODO: Add support for etime */
printf("\n\n");
printf ("%s\n", _("Optional Arguments:"));
printf (" %s\n", "-m, --metric=TYPE");
printf (" %s\n", _("Check thresholds against metric. Valid types:"));
printf (" %s\n", _("PROCS - number of processes (default)"));
printf (" %s\n", _("VSZ - virtual memory size"));
printf (" %s\n", _("RSS - resident set memory size"));
printf (" %s\n", _("CPU - percentage cpu"));
/* only linux etime is support currently */
#if defined( __linux__ )
printf (" %s\n", _("ELAPSED - time elapsed in seconds"));
#endif /* defined(__linux__) */
printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
printf (" %s\n", "-v, --verbose");
@ -759,29 +865,25 @@ print_help (void)
printf (" %s\n", "-C, --command=COMMAND");
printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
printf(_("\n\
RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
specified 'max:min', a warning status will be generated if the\n\
count is inside the specified range\n\n"));
printf("\n");
printf(_("\
This plugin checks the number of currently running processes and\n\
generates WARNING or CRITICAL states if the process count is outside\n\
the specified threshold ranges. The process count can be filtered by\n\
process owner, parent process PID, current state (e.g., 'Z'), or may\n\
be the total number of running processes\n\n"));
printf("\
THRESHOLDS are specified as 'critical_range/warning_range' where\n\
RANGES are defined as 'min:max'. max can be removed if it is infinity.\n\
Alerts will occur inside this range, unless you specify '^' before\n\
the range, to mean alert outside this range\n\n");
printf ("%s\n", _("Examples:"));
printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry");
printf (" %s\n", _("Warning if not two processes with command name portsentry."));
printf (" %s\n\n", _("Critical if < 2 or > 1024 processes"));
printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root");
printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing"));
printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root"));
printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ");
printf (" %s\n\n", _("Alert if vsz of any processes over 50K or 100K"));
printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU");
printf (" %s\n\n", _("Alert if cpu of any processes over 10%% or 20%%"));
printf (" %s\n", "check_procs --number=:2/5: -C portsentry");
printf (" %s\n", _("Warning if greater than five processes with command name portsentry."));
printf (" %s\n\n", _("Critical if <= 2 processes"));
printf (" %s\n", "check_procs --vsz-threshold=100:/50:");
printf (" %s\n\n", _("Warning if vsz of any processes is over 50K or critical if vsz is over 100K"));
printf (" %s\n", "check_procs --cpu-threshold=20:/10: --ereg-argument-array='java.*server'");
printf (" %s\n\n", _("For all processes with arguments matching the regular expression, warning if cpu is over 10% or critical if over 20%"));
printf (" %s\n", "check_procs --rss-threshold=100: --number=/:10 --cpu-threshold=30:/10: -a '/usr/local/bin/perl' -u root");
printf (" %s\n", _("Critical if rss >= 100K, or warning if total number of process <= 10, or critical if cpu >= 30% or warning if cpu >= 10%."));
printf (" %s\n", _("Filter by arguments containing '/usr/local/bin/perl' and owned by root"));
printf (_(UT_SUPPORT));
}