summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/developer-guidelines.sgml22
-rw-r--r--plugins/tests/test_utils.c77
-rw-r--r--plugins/utils.c133
-rw-r--r--plugins/utils.h17
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";
29int 29int
30main (int argc, char **argv) 30main (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
268void set_threshold_start (threshold *this, double value) { 268void 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
273void set_threshold_end (threshold *this, double value) { 273void 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
278threshold 278range
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 */
326int
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
356void
357set_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 */
367int
368check_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 */
402int
403get_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
326int 419int
327gettimeofday (struct timeval *tv, struct timezone *tz) 420gettimeofday (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
64typedef struct threshold_struct { 64typedef 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
72threshold *parse_threshold (char *); 72typedef struct thresholds_struct {
73 range *warning;
74 range *critical;
75 } thresholds;
76
77range *parse_range_string (char *);
78int _set_thresholds(thresholds **, char *, char *);
79void set_thresholds(thresholds **, char *, char *);
80int check_range(double, range *);
81int get_status(double, thresholds *);
73 82
74#ifndef HAVE_GETTIMEOFDAY 83#ifndef HAVE_GETTIMEOFDAY
75int gettimeofday(struct timeval *, struct timezone *); 84int gettimeofday(struct timeval *, struct timezone *);