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 <[email protected]>\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.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.