mirror of
https://github.com/monitoring-plugins/monitoring-plugins.git
synced 2026-05-28 04:35:40 -04:00
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:
parent
cab9440a67
commit
b17b242198
5 changed files with 478 additions and 78 deletions
|
|
@ -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");
|
||||
|
|
|
|||
135
lib/utils_base.c
135
lib/utils_base.c
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,",")){
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue