diff options
author | Sebastian Harl <sh@teamix.net> | 2011-04-18 11:04:28 (GMT) |
---|---|---|
committer | Sebastian Harl <sh@teamix.net> | 2012-06-06 12:10:55 (GMT) |
commit | b7e661c4ae46cb6a919a5dbf1bfb28c38e409a64 (patch) | |
tree | 5c6ae347131fbbe88d440dedd511ec1b94069fe3 | |
parent | aebde433fb2ad27f8ded9dd41224b6826ac787d2 (diff) | |
download | monitoring-plugins-b7e661c4ae46cb6a919a5dbf1bfb28c38e409a64.tar.gz |
check_dbi: Added -r and -R options.
These options may be used to specify an extended POSIX regular expression that
is applied to the query result. When using -R, a case-insensitive match is
done.
The options may not be mixed with -w/-c/-e.
-rw-r--r-- | plugins/check_dbi.c | 101 |
1 files changed, 89 insertions, 12 deletions
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index 94c6b15..39898cf 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c | |||
@@ -38,6 +38,8 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
38 | 38 | ||
39 | #include "netutils.h" | 39 | #include "netutils.h" |
40 | 40 | ||
41 | #include "regex.h" | ||
42 | |||
41 | /* required for NAN */ | 43 | /* required for NAN */ |
42 | #ifndef _ISOC99_SOURCE | 44 | #ifndef _ISOC99_SOURCE |
43 | #define _ISOC99_SOURCE | 45 | #define _ISOC99_SOURCE |
@@ -56,6 +58,11 @@ typedef enum { | |||
56 | METRIC_QUERY_TIME, | 58 | METRIC_QUERY_TIME, |
57 | } np_dbi_metric_t; | 59 | } np_dbi_metric_t; |
58 | 60 | ||
61 | typedef enum { | ||
62 | TYPE_NUMERIC, | ||
63 | TYPE_STRING, | ||
64 | } np_dbi_type_t; | ||
65 | |||
59 | typedef struct { | 66 | typedef struct { |
60 | char *key; | 67 | char *key; |
61 | char *value; | 68 | char *value; |
@@ -70,7 +77,12 @@ thresholds *dbi_thresholds = NULL; | |||
70 | 77 | ||
71 | char *expect = NULL; | 78 | char *expect = NULL; |
72 | 79 | ||
80 | regex_t expect_re; | ||
81 | char *expect_re_str = NULL; | ||
82 | int expect_re_cflags = 0; | ||
83 | |||
73 | np_dbi_metric_t metric = METRIC_QUERY_RESULT; | 84 | np_dbi_metric_t metric = METRIC_QUERY_RESULT; |
85 | np_dbi_type_t type = TYPE_NUMERIC; | ||
74 | 86 | ||
75 | char *np_dbi_driver = NULL; | 87 | char *np_dbi_driver = NULL; |
76 | driver_option_t *np_dbi_options = NULL; | 88 | driver_option_t *np_dbi_options = NULL; |
@@ -239,6 +251,22 @@ main (int argc, char **argv) | |||
239 | else | 251 | else |
240 | status = STATE_OK; | 252 | status = STATE_OK; |
241 | } | 253 | } |
254 | else if (expect_re_str) { | ||
255 | int err; | ||
256 | |||
257 | err = regexec (&expect_re, query_val_str, 0, NULL, /* flags = */ 0); | ||
258 | if (! err) | ||
259 | status = STATE_OK; | ||
260 | else if (err == REG_NOMATCH) | ||
261 | status = STATE_CRITICAL; | ||
262 | else { | ||
263 | char errmsg[1024]; | ||
264 | regerror (err, &expect_re, errmsg, sizeof (errmsg)); | ||
265 | printf ("ERROR - failed to execute regular expression: %s\n", | ||
266 | errmsg); | ||
267 | status = STATE_CRITICAL; | ||
268 | } | ||
269 | } | ||
242 | else | 270 | else |
243 | status = get_status (query_val, dbi_thresholds); | 271 | status = get_status (query_val, dbi_thresholds); |
244 | } | 272 | } |
@@ -251,16 +279,26 @@ main (int argc, char **argv) | |||
251 | dbi_conn_close (conn); | 279 | dbi_conn_close (conn); |
252 | 280 | ||
253 | /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error | 281 | /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error |
254 | * which should have been reported and handled (abort) before */ | 282 | * which should have been reported and handled (abort) before |
255 | assert ((metric != METRIC_QUERY_RESULT) || (! isnan (query_val)) || expect); | 283 | * ... unless we expected a string to be returned */ |
284 | assert ((metric != METRIC_QUERY_RESULT) || (! isnan (query_val)) | ||
285 | || (type == TYPE_STRING)); | ||
286 | |||
287 | assert ((type != TYPE_STRING) || (expect || expect_re_str)); | ||
256 | 288 | ||
257 | printf ("%s - connection time: %fs", state_text (status), conn_time); | 289 | printf ("%s - connection time: %fs", state_text (status), conn_time); |
258 | if (np_dbi_query) { | 290 | if (np_dbi_query) { |
259 | if (expect) { | 291 | if (type == TYPE_STRING) { |
292 | assert (expect || expect_re_str); | ||
260 | printf (", '%s' returned '%s' in %fs", np_dbi_query, | 293 | printf (", '%s' returned '%s' in %fs", np_dbi_query, |
261 | query_val_str ? query_val_str : "<nothing>", query_time); | 294 | query_val_str ? query_val_str : "<nothing>", query_time); |
262 | if (status != STATE_OK) | 295 | if (status != STATE_OK) { |
263 | printf (" (expected '%s')", expect); | 296 | if (expect) |
297 | printf (" (expected '%s')", expect); | ||
298 | else if (expect_re_str) | ||
299 | printf (" (expected regex /%s/%s)", expect_re_str, | ||
300 | ((expect_re_cflags & REG_ICASE) ? "i" : "")); | ||
301 | } | ||
264 | } | 302 | } |
265 | else if (isnan (query_val)) | 303 | else if (isnan (query_val)) |
266 | printf (", '%s' query execution time: %fs", np_dbi_query, query_time); | 304 | printf (", '%s' query execution time: %fs", np_dbi_query, query_time); |
@@ -295,6 +333,8 @@ process_arguments (int argc, char **argv) | |||
295 | STD_LONG_OPTS, | 333 | STD_LONG_OPTS, |
296 | 334 | ||
297 | {"expect", required_argument, 0, 'e'}, | 335 | {"expect", required_argument, 0, 'e'}, |
336 | {"regex", required_argument, 0, 'r'}, | ||
337 | {"regexi", required_argument, 0, 'R'}, | ||
298 | {"metric", required_argument, 0, 'm'}, | 338 | {"metric", required_argument, 0, 'm'}, |
299 | {"driver", required_argument, 0, 'd'}, | 339 | {"driver", required_argument, 0, 'd'}, |
300 | {"option", required_argument, 0, 'o'}, | 340 | {"option", required_argument, 0, 'o'}, |
@@ -304,7 +344,7 @@ process_arguments (int argc, char **argv) | |||
304 | }; | 344 | }; |
305 | 345 | ||
306 | while (1) { | 346 | while (1) { |
307 | c = getopt_long (argc, argv, "Vvht:c:w:e:m:H:d:o:q:D:", | 347 | c = getopt_long (argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", |
308 | longopts, &option); | 348 | longopts, &option); |
309 | 349 | ||
310 | if (c == EOF) | 350 | if (c == EOF) |
@@ -322,13 +362,38 @@ process_arguments (int argc, char **argv) | |||
322 | 362 | ||
323 | case 'c': /* critical range */ | 363 | case 'c': /* critical range */ |
324 | critical_range = optarg; | 364 | critical_range = optarg; |
365 | type = TYPE_NUMERIC; | ||
325 | break; | 366 | break; |
326 | case 'w': /* warning range */ | 367 | case 'w': /* warning range */ |
327 | warning_range = optarg; | 368 | warning_range = optarg; |
369 | type = TYPE_NUMERIC; | ||
328 | break; | 370 | break; |
329 | case 'e': | 371 | case 'e': |
330 | expect = optarg; | 372 | expect = optarg; |
373 | type = TYPE_STRING; | ||
331 | break; | 374 | break; |
375 | case 'R': | ||
376 | expect_re_cflags = REG_ICASE; | ||
377 | /* fall through */ | ||
378 | case 'r': | ||
379 | { | ||
380 | int err; | ||
381 | |||
382 | expect_re_cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; | ||
383 | expect_re_str = optarg; | ||
384 | type = TYPE_STRING; | ||
385 | |||
386 | err = regcomp (&expect_re, expect_re_str, expect_re_cflags); | ||
387 | if (err) { | ||
388 | char errmsg[1024]; | ||
389 | regerror (err, &expect_re, errmsg, sizeof (errmsg)); | ||
390 | printf ("ERROR - failed to compile regular expression: %s\n", | ||
391 | errmsg); | ||
392 | return ERROR; | ||
393 | } | ||
394 | break; | ||
395 | } | ||
396 | |||
332 | case 'm': | 397 | case 'm': |
333 | if (! strcasecmp (optarg, "CONN_TIME")) | 398 | if (! strcasecmp (optarg, "CONN_TIME")) |
334 | metric = METRIC_CONN_TIME; | 399 | metric = METRIC_CONN_TIME; |
@@ -417,12 +482,18 @@ validate_arguments () | |||
417 | && (metric != METRIC_QUERY_TIME)) | 482 | && (metric != METRIC_QUERY_TIME)) |
418 | usage ("Invalid metric specified"); | 483 | usage ("Invalid metric specified"); |
419 | 484 | ||
420 | if (expect && (warning_range || critical_range)) | 485 | if (expect && (warning_range || critical_range || expect_re_str)) |
421 | usage ("Do not mix -e and -w/-c"); | 486 | usage ("Do not mix -e and -w/-c/-r/-R"); |
487 | |||
488 | if (expect_re_str && (warning_range || critical_range || expect)) | ||
489 | usage ("Do not mix -r/-R and -w/-c/-e"); | ||
422 | 490 | ||
423 | if (expect && (metric != METRIC_QUERY_RESULT)) | 491 | if (expect && (metric != METRIC_QUERY_RESULT)) |
424 | usage ("Option -e requires metric QUERY_RESULT"); | 492 | usage ("Option -e requires metric QUERY_RESULT"); |
425 | 493 | ||
494 | if (expect_re_str && (metric != METRIC_QUERY_RESULT)) | ||
495 | usage ("Options -r/-R require metric QUERY_RESULT"); | ||
496 | |||
426 | return OK; | 497 | return OK; |
427 | } | 498 | } |
428 | 499 | ||
@@ -460,7 +531,13 @@ print_help (void) | |||
460 | printf (UT_WARN_CRIT_RANGE); | 531 | printf (UT_WARN_CRIT_RANGE); |
461 | printf (" %s\n", "-e, --expect=STRING"); | 532 | printf (" %s\n", "-e, --expect=STRING"); |
462 | printf (" %s\n", _("String to expect as query result")); | 533 | printf (" %s\n", _("String to expect as query result")); |
463 | printf (" %s\n", _("Do not mix with -w or -c!")); | 534 | printf (" %s\n", _("Do not mix with -w, -c, -r, or -R!")); |
535 | printf (" %s\n", "-r, --regex=REGEX"); | ||
536 | printf (" %s\n", _("Extended POSIX regular expression to check query result against")); | ||
537 | printf (" %s\n", _("Do not mix with -w, -c, -e, or -R!")); | ||
538 | printf (" %s\n", "-R, --regexi=REGEX"); | ||
539 | printf (" %s\n", _("Case-insensitive extended POSIX regex to check query result against")); | ||
540 | printf (" %s\n", _("Do not mix with -w, -c, -e, or -r!")); | ||
464 | printf (" %s\n", "-m, --metric=METRIC"); | 541 | printf (" %s\n", "-m, --metric=METRIC"); |
465 | printf (" %s\n", _("Metric to check thresholds against. Available metrics:")); | 542 | printf (" %s\n", _("Metric to check thresholds against. Available metrics:")); |
466 | printf (" CONN_TIME - %s\n", _("time used for setting up the database connection")); | 543 | printf (" CONN_TIME - %s\n", _("time used for setting up the database connection")); |
@@ -511,7 +588,7 @@ print_usage (void) | |||
511 | printf ("%s\n", _("Usage:")); | 588 | printf ("%s\n", _("Usage:")); |
512 | printf ("%s -d <DBI driver> [-o <DBI driver option> [...]] [-q <query>]\n", progname); | 589 | printf ("%s -d <DBI driver> [-o <DBI driver option> [...]] [-q <query>]\n", progname); |
513 | printf (" [-H <host>] [-c <critical range>] [-w <warning range>] [-m <metric>]\n"); | 590 | printf (" [-H <host>] [-c <critical range>] [-w <warning range>] [-m <metric>]\n"); |
514 | printf (" [-e <string>]\n"); | 591 | printf (" [-e <string>] [-r|-R <regex>]\n"); |
515 | } | 592 | } |
516 | 593 | ||
517 | #define CHECK_IGNORE_ERROR(s) \ | 594 | #define CHECK_IGNORE_ERROR(s) \ |
@@ -537,7 +614,7 @@ get_field_str (dbi_conn conn, dbi_result res, unsigned short field_type) | |||
537 | return NULL; | 614 | return NULL; |
538 | } | 615 | } |
539 | 616 | ||
540 | if ((verbose && expect) || (verbose > 2)) | 617 | if ((verbose && (type == TYPE_STRING)) || (verbose > 2)) |
541 | printf ("Query returned string '%s'\n", str); | 618 | printf ("Query returned string '%s'\n", str); |
542 | return str; | 619 | return str; |
543 | } | 620 | } |
@@ -629,7 +706,7 @@ get_query_result (dbi_conn conn, dbi_result res, const char **res_val_str, doubl | |||
629 | 706 | ||
630 | field_type = dbi_result_get_field_type_idx (res, 1); | 707 | field_type = dbi_result_get_field_type_idx (res, 1); |
631 | if (field_type != DBI_TYPE_ERROR) { | 708 | if (field_type != DBI_TYPE_ERROR) { |
632 | if (expect) | 709 | if (type == TYPE_STRING) |
633 | /* the value will be freed in dbi_result_free */ | 710 | /* the value will be freed in dbi_result_free */ |
634 | *res_val_str = strdup (get_field_str (conn, res, field_type)); | 711 | *res_val_str = strdup (get_field_str (conn, res, field_type)); |
635 | else | 712 | else |