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 ad6f59e..82dbeca 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 1fda367..5604bac 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 dbb2520..685a638 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 f47d053..ffcb39d 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 *); |