diff options
| -rw-r--r-- | doc/developer-guidelines.sgml | 22 | ||||
| -rw-r--r-- | plugins/tests/test_utils.c | 77 | ||||
| -rw-r--r-- | plugins/utils.c | 133 | ||||
| -rw-r--r-- | plugins/utils.h | 17 |
4 files changed, 195 insertions, 54 deletions
diff --git a/doc/developer-guidelines.sgml b/doc/developer-guidelines.sgml index ad6f59e9..82dbecaa 100644 --- a/doc/developer-guidelines.sgml +++ b/doc/developer-guidelines.sgml | |||
| @@ -196,12 +196,18 @@ | |||
| 196 | 196 | ||
| 197 | </section> | 197 | </section> |
| 198 | 198 | ||
| 199 | <section id="thresholdformat"><title>Threshold range format</title> | 199 | <section id="thresholdformat"><title>Threshold and ranges</title> |
| 200 | <para>Thresholds ranges define the warning and critical levels for plugins to | 200 | <para>A range is defined as a start and end point (inclusive) on a numeric scale (possibly |
| 201 | alert on. The theory is that the plugin will do some sort of check which returns | 201 | negative or positive infinity). |
| 202 | </para> | ||
| 203 | <para>A threshold is a range with an alert level (either warning or critical). Use the | ||
| 204 | set_thresholds(thresholds *, char *, char *) function to set the thresholds. | ||
| 205 | </para> | ||
| 206 | <para>The theory is that the plugin will do some sort of check which returns | ||
| 202 | back a numerical value, or metric, which is then compared to the warning and | 207 | back a numerical value, or metric, which is then compared to the warning and |
| 203 | critical thresholds. | 208 | critical thresholds. Use the get_status(double, thresholds *) function to |
| 204 | This is the generalised format for threshold ranges:</para> | 209 | compare the value against the thresholds.</para> |
| 210 | <para>This is the generalised format for ranges:</para> | ||
| 205 | 211 | ||
| 206 | <literallayout> | 212 | <literallayout> |
| 207 | [@]start:end | 213 | [@]start:end |
| @@ -226,10 +232,8 @@ | |||
| 226 | </listitem> | 232 | </listitem> |
| 227 | </orderedlist> | 233 | </orderedlist> |
| 228 | 234 | ||
| 229 | <para>Note: Not all plugins are coded to expect ranges in this format. It is | 235 | <para>Note: Not all plugins are coded to expect ranges in this format yet. |
| 230 | planned for a future release to | 236 | There will be some work in providing multiple metrics.</para> |
| 231 | provide standard libraries to parse and compare metrics against ranges. There | ||
| 232 | will also be some work in providing multiple metrics.</para> | ||
| 233 | </section> | 237 | </section> |
| 234 | 238 | ||
| 235 | <section><title>Performance data</title> | 239 | <section><title>Performance data</title> |
diff --git a/plugins/tests/test_utils.c b/plugins/tests/test_utils.c index 1fda3675..5604bacd 100644 --- a/plugins/tests/test_utils.c +++ b/plugins/tests/test_utils.c | |||
| @@ -29,77 +29,112 @@ const char *progname = "utils"; | |||
| 29 | int | 29 | int |
| 30 | main (int argc, char **argv) | 30 | main (int argc, char **argv) |
| 31 | { | 31 | { |
| 32 | threshold *range; | 32 | range *range; |
| 33 | double temp; | 33 | double temp; |
| 34 | thresholds *thresholds; | ||
| 35 | int rc; | ||
| 34 | 36 | ||
| 35 | plan_tests(40); | 37 | plan_tests(66); |
| 36 | 38 | ||
| 37 | range = parse_threshold("6"); | 39 | range = parse_range_string("6"); |
| 38 | ok( range != NULL, "'6' is valid threshold"); | 40 | ok( range != NULL, "'6' is valid range"); |
| 39 | ok( range->start == 0, "Start correct"); | 41 | ok( range->start == 0, "Start correct"); |
| 40 | ok( range->start_infinity == FALSE, "Not using negative infinity"); | 42 | ok( range->start_infinity == FALSE, "Not using negative infinity"); |
| 41 | ok( range->end == 6, "End correct"); | 43 | ok( range->end == 6, "End correct"); |
| 42 | ok( range->end_infinity == FALSE, "Not using infinity"); | 44 | ok( range->end_infinity == FALSE, "Not using infinity"); |
| 43 | free(range); | 45 | free(range); |
| 44 | 46 | ||
| 45 | range = parse_threshold("-7:23"); | 47 | range = parse_range_string("-7:23"); |
| 46 | ok( range != NULL, "'-7:23' is valid threshold"); | 48 | ok( range != NULL, "'-7:23' is valid range"); |
| 47 | ok( range->start == -7, "Start correct"); | 49 | ok( range->start == -7, "Start correct"); |
| 48 | ok( range->start_infinity == FALSE, "Not using negative infinity"); | 50 | ok( range->start_infinity == FALSE, "Not using negative infinity"); |
| 49 | ok( range->end == 23, "End correct"); | 51 | ok( range->end == 23, "End correct"); |
| 50 | ok( range->end_infinity == FALSE, "Not using infinity"); | 52 | ok( range->end_infinity == FALSE, "Not using infinity"); |
| 51 | free(range); | 53 | free(range); |
| 52 | 54 | ||
| 53 | range = parse_threshold(":5.75"); | 55 | range = parse_range_string(":5.75"); |
| 54 | ok( range != NULL, "':5.75' is valid threshold"); | 56 | ok( range != NULL, "':5.75' is valid range"); |
| 55 | ok( range->start == 0, "Start correct"); | 57 | ok( range->start == 0, "Start correct"); |
| 56 | ok( range->start_infinity == FALSE, "Not using negative infinity"); | 58 | ok( range->start_infinity == FALSE, "Not using negative infinity"); |
| 57 | ok( range->end == 5.75, "End correct"); | 59 | ok( range->end == 5.75, "End correct"); |
| 58 | ok( range->end_infinity == FALSE, "Not using infinity"); | 60 | ok( range->end_infinity == FALSE, "Not using infinity"); |
| 59 | free(range); | 61 | free(range); |
| 60 | 62 | ||
| 61 | range = parse_threshold("~:-95.99"); | 63 | range = parse_range_string("~:-95.99"); |
| 62 | ok( range != NULL, "~:-95.99' is valid threshold"); | 64 | ok( range != NULL, "~:-95.99' is valid range"); |
| 63 | ok( range->start_infinity == TRUE, "Using negative infinity"); | 65 | ok( range->start_infinity == TRUE, "Using negative infinity"); |
| 64 | ok( range->end == -95.99, "End correct (with rounding errors)"); | 66 | ok( range->end == -95.99, "End correct (with rounding errors)"); |
| 65 | ok( range->end_infinity == FALSE, "Not using infinity"); | 67 | ok( range->end_infinity == FALSE, "Not using infinity"); |
| 66 | free(range); | 68 | free(range); |
| 67 | 69 | ||
| 68 | range = parse_threshold("12345678901234567890:"); | 70 | range = parse_range_string("12345678901234567890:"); |
| 69 | temp = atof("12345678901234567890"); /* Can't just use this because number too large */ | 71 | temp = atof("12345678901234567890"); /* Can't just use this because number too large */ |
| 70 | ok( range != NULL, "'12345678901234567890:' is valid threshold"); | 72 | ok( range != NULL, "'12345678901234567890:' is valid range"); |
| 71 | ok( range->start == temp, "Start correct"); | 73 | ok( range->start == temp, "Start correct"); |
| 72 | ok( range->start_infinity == FALSE, "Not using negative infinity"); | 74 | ok( range->start_infinity == FALSE, "Not using negative infinity"); |
| 73 | ok( range->end_infinity == TRUE, "Using infinity"); | 75 | ok( range->end_infinity == TRUE, "Using infinity"); |
| 76 | /* Cannot do a "-1" on temp, as it appears to be same value */ | ||
| 77 | ok( check_range(temp/1.1, range) == TRUE, "12345678901234567890/1.1 - alert"); | ||
| 78 | ok( check_range(temp, range) == FALSE, "12345678901234567890 - no alert"); | ||
| 79 | ok( check_range(temp*2, range) == FALSE, "12345678901234567890*2 - no alert"); | ||
| 74 | free(range); | 80 | free(range); |
| 75 | 81 | ||
| 76 | range = parse_threshold("~:0"); | 82 | range = parse_range_string("~:0"); |
| 77 | ok( range != NULL, "'~:0' is valid threshold"); | 83 | ok( range != NULL, "'~:0' is valid range"); |
| 78 | ok( range->start_infinity == TRUE, "Using negative infinity"); | 84 | ok( range->start_infinity == TRUE, "Using negative infinity"); |
| 79 | ok( range->end == 0, "End correct"); | 85 | ok( range->end == 0, "End correct"); |
| 80 | ok( range->end_infinity == FALSE, "Not using infinity"); | 86 | ok( range->end_infinity == FALSE, "Not using infinity"); |
| 81 | ok( range->alert_on == OUTSIDE, "Will alert on outside of this range"); | 87 | ok( range->alert_on == OUTSIDE, "Will alert on outside of this range"); |
| 88 | ok( check_range(0.5, range) == TRUE, "0.5 - alert"); | ||
| 89 | ok( check_range(-10, range) == FALSE, "-10 - no alert"); | ||
| 90 | ok( check_range(0, range) == FALSE, "0 - no alert"); | ||
| 82 | free(range); | 91 | free(range); |
| 83 | 92 | ||
| 84 | range = parse_threshold("@0:657.8210567"); | 93 | range = parse_range_string("@0:657.8210567"); |
| 85 | ok( range != 0, "@0:657.8210567' is a valid threshold"); | 94 | ok( range != 0, "@0:657.8210567' is a valid range"); |
| 86 | ok( range->start == 0, "Start correct"); | 95 | ok( range->start == 0, "Start correct"); |
| 87 | ok( range->start_infinity == FALSE, "Not using negative infinity"); | 96 | ok( range->start_infinity == FALSE, "Not using negative infinity"); |
| 88 | ok( range->end == 657.8210567, "End correct"); | 97 | ok( range->end == 657.8210567, "End correct"); |
| 89 | ok( range->end_infinity == FALSE, "Not using infinity"); | 98 | ok( range->end_infinity == FALSE, "Not using infinity"); |
| 90 | ok( range->alert_on == INSIDE, "Will alert on inside of this range" ); | 99 | ok( range->alert_on == INSIDE, "Will alert on inside of this range" ); |
| 100 | ok( check_range(32.88, range) == TRUE, "32.88 - alert"); | ||
| 101 | ok( check_range(-2, range) == FALSE, "-2 - no alert"); | ||
| 102 | ok( check_range(657.8210567, range) == TRUE, "657.8210567 - alert"); | ||
| 103 | ok( check_range(0, range) == TRUE, "0 - alert"); | ||
| 91 | free(range); | 104 | free(range); |
| 92 | 105 | ||
| 93 | range = parse_threshold("1:1"); | 106 | range = parse_range_string("1:1"); |
| 94 | ok( range != NULL, "'1:1' is a valid threshold"); | 107 | ok( range != NULL, "'1:1' is a valid range"); |
| 95 | ok( range->start == 1, "Start correct"); | 108 | ok( range->start == 1, "Start correct"); |
| 96 | ok( range->start_infinity == FALSE, "Not using negative infinity"); | 109 | ok( range->start_infinity == FALSE, "Not using negative infinity"); |
| 97 | ok( range->end == 1, "End correct"); | 110 | ok( range->end == 1, "End correct"); |
| 98 | ok( range->end_infinity == FALSE, "Not using infinity"); | 111 | ok( range->end_infinity == FALSE, "Not using infinity"); |
| 112 | ok( check_range(0.5, range) == TRUE, "0.5 - alert"); | ||
| 113 | ok( check_range(1, range) == FALSE, "1 - no alert"); | ||
| 114 | ok( check_range(5.2, range) == TRUE, "5.2 - alert"); | ||
| 99 | free(range); | 115 | free(range); |
| 100 | 116 | ||
| 101 | range = parse_threshold("2:1"); | 117 | range = parse_range_string("2:1"); |
| 102 | ok( range == NULL, "''2:1' rejected"); | 118 | ok( range == NULL, "'2:1' rejected"); |
| 119 | |||
| 120 | rc = _set_thresholds(&thresholds, NULL, "80"); | ||
| 121 | ok( rc == 0, "Thresholds (NULL, '80') set"); | ||
| 122 | ok( thresholds->warning == NULL, "Warning not set"); | ||
| 123 | ok( thresholds->critical->end == 80, "Critical set correctly"); | ||
| 124 | |||
| 125 | rc = _set_thresholds(&thresholds, "5:33", NULL); | ||
| 126 | ok( rc == 0, "Thresholds ('5:33', NULL) set"); | ||
| 127 | ok( thresholds->warning->start == 5, "Warning start set"); | ||
| 128 | ok( thresholds->warning->end == 33, "Warning end set"); | ||
| 129 | ok( thresholds->critical == NULL, "Critical not set"); | ||
| 130 | |||
| 131 | rc = _set_thresholds(&thresholds, "30", "60"); | ||
| 132 | ok( rc == 0, "Thresholds ('30', '60') set"); | ||
| 133 | ok( thresholds->warning->end == 30, "Warning set correctly"); | ||
| 134 | ok( thresholds->critical->end == 60, "Critical set correctly"); | ||
| 135 | ok( get_status(15.3, thresholds) == STATE_OK, "15.3 - ok"); | ||
| 136 | ok( get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning"); | ||
| 137 | ok( get_status(69, thresholds) == STATE_CRITICAL, "69 - critical"); | ||
| 103 | 138 | ||
| 104 | return exit_status(); | 139 | return exit_status(); |
| 105 | } | 140 | } |
diff --git a/plugins/utils.c b/plugins/utils.c index dbb25202..685a638a 100644 --- a/plugins/utils.c +++ b/plugins/utils.c | |||
| @@ -265,44 +265,44 @@ is_option (char *str) | |||
| 265 | return FALSE; | 265 | return FALSE; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | void set_threshold_start (threshold *this, double value) { | 268 | void set_range_start (range *this, double value) { |
| 269 | this->start = value; | 269 | this->start = value; |
| 270 | this->start_infinity = FALSE; | 270 | this->start_infinity = FALSE; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | void set_threshold_end (threshold *this, double value) { | 273 | void set_range_end (range *this, double value) { |
| 274 | this->end = value; | 274 | this->end = value; |
| 275 | this->end_infinity = FALSE; | 275 | this->end_infinity = FALSE; |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | threshold | 278 | range |
| 279 | *parse_threshold (char *str) { | 279 | *parse_range_string (char *str) { |
| 280 | threshold *temp_threshold; | 280 | range *temp_range; |
| 281 | double start; | 281 | double start; |
| 282 | double end; | 282 | double end; |
| 283 | char *end_str; | 283 | char *end_str; |
| 284 | 284 | ||
| 285 | temp_threshold = (threshold *) malloc(sizeof(threshold)); | 285 | temp_range = (range *) malloc(sizeof(range)); |
| 286 | 286 | ||
| 287 | /* Set defaults */ | 287 | /* Set defaults */ |
| 288 | temp_threshold->start = 0; | 288 | temp_range->start = 0; |
| 289 | temp_threshold->start_infinity = FALSE; | 289 | temp_range->start_infinity = FALSE; |
| 290 | temp_threshold->end = 0; | 290 | temp_range->end = 0; |
| 291 | temp_threshold->end_infinity = TRUE; | 291 | temp_range->end_infinity = TRUE; |
| 292 | temp_threshold->alert_on = OUTSIDE; | 292 | temp_range->alert_on = OUTSIDE; |
| 293 | 293 | ||
| 294 | if (str[0] == '@') { | 294 | if (str[0] == '@') { |
| 295 | temp_threshold->alert_on = INSIDE; | 295 | temp_range->alert_on = INSIDE; |
| 296 | str++; | 296 | str++; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | end_str = index(str, ':'); | 299 | end_str = index(str, ':'); |
| 300 | if (end_str != NULL) { | 300 | if (end_str != NULL) { |
| 301 | if (str[0] == '~') { | 301 | if (str[0] == '~') { |
| 302 | temp_threshold->start_infinity = TRUE; | 302 | temp_range->start_infinity = TRUE; |
| 303 | } else { | 303 | } else { |
| 304 | start = strtod(str, NULL); /* Will stop at the ':' */ | 304 | start = strtod(str, NULL); /* Will stop at the ':' */ |
| 305 | set_threshold_start(temp_threshold, start); | 305 | set_range_start(temp_range, start); |
| 306 | } | 306 | } |
| 307 | end_str++; /* Move past the ':' */ | 307 | end_str++; /* Move past the ':' */ |
| 308 | } else { | 308 | } else { |
| @@ -310,18 +310,111 @@ threshold | |||
| 310 | } | 310 | } |
| 311 | end = strtod(end_str, NULL); | 311 | end = strtod(end_str, NULL); |
| 312 | if (strcmp(end_str, "") != 0) { | 312 | if (strcmp(end_str, "") != 0) { |
| 313 | set_threshold_end(temp_threshold, end); | 313 | set_range_end(temp_range, end); |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | if (temp_threshold->start_infinity == TRUE || | 316 | if (temp_range->start_infinity == TRUE || |
| 317 | temp_threshold->end_infinity == TRUE || | 317 | temp_range->end_infinity == TRUE || |
| 318 | temp_threshold->start <= temp_threshold->end) { | 318 | temp_range->start <= temp_range->end) { |
| 319 | return temp_threshold; | 319 | return temp_range; |
| 320 | } | 320 | } |
| 321 | free(temp_threshold); | 321 | free(temp_range); |
| 322 | return NULL; | 322 | return NULL; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | /* returns 0 if okay, otherwise 1 */ | ||
| 326 | int | ||
| 327 | _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) | ||
| 328 | { | ||
| 329 | thresholds *temp_thresholds = NULL; | ||
| 330 | |||
| 331 | temp_thresholds = malloc(sizeof(temp_thresholds)); | ||
| 332 | |||
| 333 | temp_thresholds->warning = NULL; | ||
| 334 | temp_thresholds->critical = NULL; | ||
| 335 | |||
| 336 | if (warn_string != NULL) { | ||
| 337 | if ((temp_thresholds->warning = parse_range_string(warn_string)) == NULL) { | ||
| 338 | return 1; | ||
| 339 | } | ||
| 340 | } | ||
| 341 | if (critical_string != NULL) { | ||
| 342 | if ((temp_thresholds->critical = parse_range_string(critical_string)) == NULL) { | ||
| 343 | return 1; | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | if (*my_thresholds != 0) { | ||
| 348 | /* printf("Freeing here: %d\n", *my_thresholds); */ | ||
| 349 | free(*my_thresholds); | ||
| 350 | } | ||
| 351 | *my_thresholds = temp_thresholds; | ||
| 352 | |||
| 353 | return 0; | ||
| 354 | } | ||
| 355 | |||
| 356 | void | ||
| 357 | set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) | ||
| 358 | { | ||
| 359 | if (_set_thresholds(my_thresholds, warn_string, critical_string) == 0) { | ||
| 360 | return; | ||
| 361 | } else { | ||
| 362 | usage("Range format incorrect"); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | |||
| 366 | /* Returns TRUE if alert should be raised based on the range */ | ||
| 367 | int | ||
| 368 | check_range(double value, range *my_range) | ||
| 369 | { | ||
| 370 | int false = FALSE; | ||
| 371 | int true = TRUE; | ||
| 372 | |||
| 373 | if (my_range->alert_on == INSIDE) { | ||
| 374 | false = TRUE; | ||
| 375 | true = FALSE; | ||
| 376 | } | ||
| 377 | |||
| 378 | if (my_range->end_infinity == FALSE && my_range->start_infinity == FALSE) { | ||
| 379 | if ((my_range->start <= value) && (value <= my_range->end)) { | ||
| 380 | return false; | ||
| 381 | } else { | ||
| 382 | return true; | ||
| 383 | } | ||
| 384 | } else if (my_range->start_infinity == FALSE && my_range->end_infinity == TRUE) { | ||
| 385 | if (my_range->start <= value) { | ||
| 386 | return false; | ||
| 387 | } else { | ||
| 388 | return true; | ||
| 389 | } | ||
| 390 | } else if (my_range->start_infinity == TRUE && my_range->end_infinity == FALSE) { | ||
| 391 | if (value <= my_range->end) { | ||
| 392 | return false; | ||
| 393 | } else { | ||
| 394 | return true; | ||
| 395 | } | ||
| 396 | } else { | ||
| 397 | return false; | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | /* Returns status */ | ||
| 402 | int | ||
| 403 | get_status(double value, thresholds *my_thresholds) | ||
| 404 | { | ||
| 405 | if (my_thresholds->critical != NULL) { | ||
| 406 | if (check_range(value, my_thresholds->critical) == TRUE) { | ||
| 407 | return STATE_CRITICAL; | ||
| 408 | } | ||
| 409 | } | ||
| 410 | if (my_thresholds->warning != NULL) { | ||
| 411 | if (check_range(value, my_thresholds->warning) == TRUE) { | ||
| 412 | return STATE_WARNING; | ||
| 413 | } | ||
| 414 | } | ||
| 415 | return STATE_OK; | ||
| 416 | } | ||
| 417 | |||
| 325 | #ifdef NEED_GETTIMEOFDAY | 418 | #ifdef NEED_GETTIMEOFDAY |
| 326 | int | 419 | int |
| 327 | gettimeofday (struct timeval *tv, struct timezone *tz) | 420 | gettimeofday (struct timeval *tv, struct timezone *tz) |
diff --git a/plugins/utils.h b/plugins/utils.h index f47d0533..ffcb39da 100644 --- a/plugins/utils.h +++ b/plugins/utils.h | |||
| @@ -61,15 +61,24 @@ struct timeval { | |||
| 61 | #define OUTSIDE 0 | 61 | #define OUTSIDE 0 |
| 62 | #define INSIDE 1 | 62 | #define INSIDE 1 |
| 63 | 63 | ||
| 64 | typedef struct threshold_struct { | 64 | typedef struct range_struct { |
| 65 | double start; | 65 | double start; |
| 66 | int start_infinity; /* FALSE (default) or TRUE */ | 66 | int start_infinity; /* FALSE (default) or TRUE */ |
| 67 | double end; | 67 | double end; |
| 68 | int end_infinity; | 68 | int end_infinity; |
| 69 | int alert_on; /* OUTSIDE (default) or INSIDE */ | 69 | int alert_on; /* OUTSIDE (default) or INSIDE */ |
| 70 | } threshold; | 70 | } range; |
| 71 | 71 | ||
| 72 | threshold *parse_threshold (char *); | 72 | typedef struct thresholds_struct { |
| 73 | range *warning; | ||
| 74 | range *critical; | ||
| 75 | } thresholds; | ||
| 76 | |||
| 77 | range *parse_range_string (char *); | ||
| 78 | int _set_thresholds(thresholds **, char *, char *); | ||
| 79 | void set_thresholds(thresholds **, char *, char *); | ||
| 80 | int check_range(double, range *); | ||
| 81 | int get_status(double, thresholds *); | ||
| 73 | 82 | ||
| 74 | #ifndef HAVE_GETTIMEOFDAY | 83 | #ifndef HAVE_GETTIMEOFDAY |
| 75 | int gettimeofday(struct timeval *, struct timezone *); | 84 | int gettimeofday(struct timeval *, struct timezone *); |
