[Nagiosplug-checkins] SF.net SVN: nagiosplug: [1958] nagiosplug/branches/new_threshold_syntax

tonvoon at users.sourceforge.net tonvoon at users.sourceforge.net
Wed Mar 19 15:42:12 CET 2008


Revision: 1958
          http://nagiosplug.svn.sourceforge.net/nagiosplug/?rev=1958&view=rev
Author:   tonvoon
Date:     2008-03-19 07:42:12 -0700 (Wed, 19 Mar 2008)

Log Message:
-----------
1st pass at check_procs with multiple threshold checks

Modified Paths:
--------------
    nagiosplug/branches/new_threshold_syntax/lib/tests/test_utils.c
    nagiosplug/branches/new_threshold_syntax/lib/utils_base.c
    nagiosplug/branches/new_threshold_syntax/lib/utils_base.h
    nagiosplug/branches/new_threshold_syntax/plugins/check_cluster.c
    nagiosplug/branches/new_threshold_syntax/plugins/check_procs.c

Modified: nagiosplug/branches/new_threshold_syntax/lib/tests/test_utils.c
===================================================================
--- nagiosplug/branches/new_threshold_syntax/lib/tests/test_utils.c	2008-03-19 14:38:56 UTC (rev 1957)
+++ nagiosplug/branches/new_threshold_syntax/lib/tests/test_utils.c	2008-03-19 14:42:12 UTC (rev 1958)
@@ -30,7 +30,7 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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");

Modified: nagiosplug/branches/new_threshold_syntax/lib/utils_base.c
===================================================================
--- nagiosplug/branches/new_threshold_syntax/lib/utils_base.c	2008-03-19 14:38:56 UTC (rev 1957)
+++ nagiosplug/branches/new_threshold_syntax/lib/utils_base.c	2008-03-19 14:42:12 UTC (rev 1958)
@@ -98,6 +98,138 @@
 	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 @@
 	}
 }
 
-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 {

Modified: nagiosplug/branches/new_threshold_syntax/lib/utils_base.h
===================================================================
--- nagiosplug/branches/new_threshold_syntax/lib/utils_base.h	2008-03-19 14:38:56 UTC (rev 1957)
+++ nagiosplug/branches/new_threshold_syntax/lib/utils_base.h	2008-03-19 14:42:12 UTC (rev 1958)
@@ -31,7 +31,7 @@
 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,10 +39,23 @@
 
 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 */
 int np_check_if_root(void);

Modified: nagiosplug/branches/new_threshold_syntax/plugins/check_cluster.c
===================================================================
--- nagiosplug/branches/new_threshold_syntax/plugins/check_cluster.c	2008-03-19 14:38:56 UTC (rev 1957)
+++ nagiosplug/branches/new_threshold_syntax/plugins/check_cluster.c	2008-03-19 14:42:12 UTC (rev 1958)
@@ -80,7 +80,7 @@
 	/* 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,",")){

Modified: nagiosplug/branches/new_threshold_syntax/plugins/check_procs.c
===================================================================
--- nagiosplug/branches/new_threshold_syntax/plugins/check_procs.c	2008-03-19 14:38:56 UTC (rev 1957)
+++ nagiosplug/branches/new_threshold_syntax/plugins/check_procs.c	2008-03-19 14:42:12 UTC (rev 1958)
@@ -44,6 +44,7 @@
 #include "popen.h"
 #include "utils.h"
 #include "regex.h"
+#include "utils_base.h"
 
 #include <pwd.h>
 
@@ -53,6 +54,7 @@
 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 @@
 /* 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,7 +104,15 @@
 
 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,11 +140,15 @@
 	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);
 	textdomain (PACKAGE);
@@ -141,7 +158,6 @@
 	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 @@
 			/* 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 @@
 				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);
+			/* 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 (i == STATE_CRITICAL) {
-					crit++;
-					asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
-					result = max_state (result, i);
+			}
+			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,20 +354,25 @@
 
 	/* 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 ) {
 		printf ("%s %s: ", metric_name, _("OK"));
 	} 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 @@
 	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 @@
 		{"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 @@
 		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 @@
 	if (fails==NULL)
 		fails = strdup("");
 
+	if (metric==DEFAULT)
+		metric = default_metric;
+
 	return options;
 }
 
@@ -636,6 +737,21 @@
 }
 
 
+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 @@
 	printf ("Copyright (c) 1999 Ethan Galstad <nagios at 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."));
+	print_usage ();
 
   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("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 @@
   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));
 }


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Commits mailing list