diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/check_dbi.c | 95 |
1 files changed, 76 insertions, 19 deletions
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index eefcf02a..94c6b15f 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c | |||
| @@ -68,6 +68,8 @@ char *warning_range = NULL; | |||
| 68 | char *critical_range = NULL; | 68 | char *critical_range = NULL; |
| 69 | thresholds *dbi_thresholds = NULL; | 69 | thresholds *dbi_thresholds = NULL; |
| 70 | 70 | ||
| 71 | char *expect = NULL; | ||
| 72 | |||
| 71 | np_dbi_metric_t metric = METRIC_QUERY_RESULT; | 73 | np_dbi_metric_t metric = METRIC_QUERY_RESULT; |
| 72 | 74 | ||
| 73 | char *np_dbi_driver = NULL; | 75 | char *np_dbi_driver = NULL; |
| @@ -85,7 +87,7 @@ double timediff (struct timeval, struct timeval); | |||
| 85 | 87 | ||
| 86 | void np_dbi_print_error (dbi_conn, char *, ...); | 88 | void np_dbi_print_error (dbi_conn, char *, ...); |
| 87 | 89 | ||
| 88 | int do_query (dbi_conn, double *, double *); | 90 | int do_query (dbi_conn, const char **, double *, double *); |
| 89 | 91 | ||
| 90 | int | 92 | int |
| 91 | main (int argc, char **argv) | 93 | main (int argc, char **argv) |
| @@ -99,6 +101,7 @@ main (int argc, char **argv) | |||
| 99 | double conn_time = 0.0; | 101 | double conn_time = 0.0; |
| 100 | double query_time = 0.0; | 102 | double query_time = 0.0; |
| 101 | 103 | ||
| 104 | const char *query_val_str = NULL; | ||
| 102 | double query_val = 0.0; | 105 | double query_val = 0.0; |
| 103 | 106 | ||
| 104 | int i; | 107 | int i; |
| @@ -224,13 +227,21 @@ main (int argc, char **argv) | |||
| 224 | 227 | ||
| 225 | if (np_dbi_query) { | 228 | if (np_dbi_query) { |
| 226 | /* execute query */ | 229 | /* execute query */ |
| 227 | status = do_query (conn, &query_val, &query_time); | 230 | status = do_query (conn, &query_val_str, &query_val, &query_time); |
| 228 | if (status != STATE_OK) | 231 | if (status != STATE_OK) |
| 229 | /* do_query prints an error message in this case */ | 232 | /* do_query prints an error message in this case */ |
| 230 | return status; | 233 | return status; |
| 231 | 234 | ||
| 232 | if (metric == METRIC_QUERY_RESULT) | 235 | if (metric == METRIC_QUERY_RESULT) { |
| 233 | status = get_status (query_val, dbi_thresholds); | 236 | if (expect) { |
| 237 | if ((! query_val_str) || strcmp (query_val_str, expect)) | ||
| 238 | status = STATE_CRITICAL; | ||
| 239 | else | ||
| 240 | status = STATE_OK; | ||
| 241 | } | ||
| 242 | else | ||
| 243 | status = get_status (query_val, dbi_thresholds); | ||
| 244 | } | ||
| 234 | else if (metric == METRIC_QUERY_TIME) | 245 | else if (metric == METRIC_QUERY_TIME) |
| 235 | status = get_status (query_time, dbi_thresholds); | 246 | status = get_status (query_time, dbi_thresholds); |
| 236 | } | 247 | } |
| @@ -241,11 +252,17 @@ main (int argc, char **argv) | |||
| 241 | 252 | ||
| 242 | /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error | 253 | /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error |
| 243 | * which should have been reported and handled (abort) before */ | 254 | * which should have been reported and handled (abort) before */ |
| 244 | assert ((metric != METRIC_QUERY_RESULT) || (! isnan (query_val))); | 255 | assert ((metric != METRIC_QUERY_RESULT) || (! isnan (query_val)) || expect); |
| 245 | 256 | ||
| 246 | printf ("%s - connection time: %fs", state_text (status), conn_time); | 257 | printf ("%s - connection time: %fs", state_text (status), conn_time); |
| 247 | if (np_dbi_query) { | 258 | if (np_dbi_query) { |
| 248 | if (isnan (query_val)) | 259 | if (expect) { |
| 260 | printf (", '%s' returned '%s' in %fs", np_dbi_query, | ||
| 261 | query_val_str ? query_val_str : "<nothing>", query_time); | ||
| 262 | if (status != STATE_OK) | ||
| 263 | printf (" (expected '%s')", expect); | ||
| 264 | } | ||
| 265 | else if (isnan (query_val)) | ||
| 249 | printf (", '%s' query execution time: %fs", np_dbi_query, query_time); | 266 | printf (", '%s' query execution time: %fs", np_dbi_query, query_time); |
| 250 | else | 267 | else |
| 251 | printf (", '%s' returned %f in %fs", np_dbi_query, query_val, query_time); | 268 | printf (", '%s' returned %f in %fs", np_dbi_query, query_val, query_time); |
| @@ -255,7 +272,7 @@ main (int argc, char **argv) | |||
| 255 | ((metric == METRIC_CONN_TIME) && warning_range) ? warning_range : "", | 272 | ((metric == METRIC_CONN_TIME) && warning_range) ? warning_range : "", |
| 256 | ((metric == METRIC_CONN_TIME) && critical_range) ? critical_range : ""); | 273 | ((metric == METRIC_CONN_TIME) && critical_range) ? critical_range : ""); |
| 257 | if (np_dbi_query) { | 274 | if (np_dbi_query) { |
| 258 | if (! isnan (query_val)) | 275 | if (! isnan (query_val)) /* this is also true when -e is used */ |
| 259 | printf (" query=%f;%s;%s;;", query_val, | 276 | printf (" query=%f;%s;%s;;", query_val, |
| 260 | ((metric == METRIC_QUERY_RESULT) && warning_range) ? warning_range : "", | 277 | ((metric == METRIC_QUERY_RESULT) && warning_range) ? warning_range : "", |
| 261 | ((metric == METRIC_QUERY_RESULT) && critical_range) ? critical_range : ""); | 278 | ((metric == METRIC_QUERY_RESULT) && critical_range) ? critical_range : ""); |
| @@ -277,6 +294,7 @@ process_arguments (int argc, char **argv) | |||
| 277 | static struct option longopts[] = { | 294 | static struct option longopts[] = { |
| 278 | STD_LONG_OPTS, | 295 | STD_LONG_OPTS, |
| 279 | 296 | ||
| 297 | {"expect", required_argument, 0, 'e'}, | ||
| 280 | {"metric", required_argument, 0, 'm'}, | 298 | {"metric", required_argument, 0, 'm'}, |
| 281 | {"driver", required_argument, 0, 'd'}, | 299 | {"driver", required_argument, 0, 'd'}, |
| 282 | {"option", required_argument, 0, 'o'}, | 300 | {"option", required_argument, 0, 'o'}, |
| @@ -286,7 +304,7 @@ process_arguments (int argc, char **argv) | |||
| 286 | }; | 304 | }; |
| 287 | 305 | ||
| 288 | while (1) { | 306 | while (1) { |
| 289 | c = getopt_long (argc, argv, "Vvht:c:w:m:H:d:o:q:D:", | 307 | c = getopt_long (argc, argv, "Vvht:c:w:e:m:H:d:o:q:D:", |
| 290 | longopts, &option); | 308 | longopts, &option); |
| 291 | 309 | ||
| 292 | if (c == EOF) | 310 | if (c == EOF) |
| @@ -308,6 +326,9 @@ process_arguments (int argc, char **argv) | |||
| 308 | case 'w': /* warning range */ | 326 | case 'w': /* warning range */ |
| 309 | warning_range = optarg; | 327 | warning_range = optarg; |
| 310 | break; | 328 | break; |
| 329 | case 'e': | ||
| 330 | expect = optarg; | ||
| 331 | break; | ||
| 311 | case 'm': | 332 | case 'm': |
| 312 | if (! strcasecmp (optarg, "CONN_TIME")) | 333 | if (! strcasecmp (optarg, "CONN_TIME")) |
| 313 | metric = METRIC_CONN_TIME; | 334 | metric = METRIC_CONN_TIME; |
| @@ -396,6 +417,12 @@ validate_arguments () | |||
| 396 | && (metric != METRIC_QUERY_TIME)) | 417 | && (metric != METRIC_QUERY_TIME)) |
| 397 | usage ("Invalid metric specified"); | 418 | usage ("Invalid metric specified"); |
| 398 | 419 | ||
| 420 | if (expect && (warning_range || critical_range)) | ||
| 421 | usage ("Do not mix -e and -w/-c"); | ||
| 422 | |||
| 423 | if (expect && (metric != METRIC_QUERY_RESULT)) | ||
| 424 | usage ("Option -e requires metric QUERY_RESULT"); | ||
| 425 | |||
| 399 | return OK; | 426 | return OK; |
| 400 | } | 427 | } |
| 401 | 428 | ||
| @@ -431,6 +458,9 @@ print_help (void) | |||
| 431 | printf ("\n"); | 458 | printf ("\n"); |
| 432 | 459 | ||
| 433 | printf (UT_WARN_CRIT_RANGE); | 460 | printf (UT_WARN_CRIT_RANGE); |
| 461 | printf (" %s\n", "-e, --expect=STRING"); | ||
| 462 | printf (" %s\n", _("String to expect as query result")); | ||
| 463 | printf (" %s\n", _("Do not mix with -w or -c!")); | ||
| 434 | printf (" %s\n", "-m, --metric=METRIC"); | 464 | printf (" %s\n", "-m, --metric=METRIC"); |
| 435 | printf (" %s\n", _("Metric to check thresholds against. Available metrics:")); | 465 | printf (" %s\n", _("Metric to check thresholds against. Available metrics:")); |
| 436 | printf (" CONN_TIME - %s\n", _("time used for setting up the database connection")); | 466 | printf (" CONN_TIME - %s\n", _("time used for setting up the database connection")); |
| @@ -481,6 +511,7 @@ print_usage (void) | |||
| 481 | printf ("%s\n", _("Usage:")); | 511 | printf ("%s\n", _("Usage:")); |
| 482 | printf ("%s -d <DBI driver> [-o <DBI driver option> [...]] [-q <query>]\n", progname); | 512 | printf ("%s -d <DBI driver> [-o <DBI driver option> [...]] [-q <query>]\n", progname); |
| 483 | printf (" [-H <host>] [-c <critical range>] [-w <warning range>] [-m <metric>]\n"); | 513 | printf (" [-H <host>] [-c <critical range>] [-w <warning range>] [-m <metric>]\n"); |
| 514 | printf (" [-e <string>]\n"); | ||
| 484 | } | 515 | } |
| 485 | 516 | ||
| 486 | #define CHECK_IGNORE_ERROR(s) \ | 517 | #define CHECK_IGNORE_ERROR(s) \ |
| @@ -489,6 +520,28 @@ print_usage (void) | |||
| 489 | return (s); \ | 520 | return (s); \ |
| 490 | } while (0) | 521 | } while (0) |
| 491 | 522 | ||
| 523 | const char * | ||
| 524 | get_field_str (dbi_conn conn, dbi_result res, unsigned short field_type) | ||
| 525 | { | ||
| 526 | const char *str; | ||
| 527 | |||
| 528 | if (field_type != DBI_TYPE_STRING) { | ||
| 529 | printf ("CRITICAL - result value is not a string\n"); | ||
| 530 | return NULL; | ||
| 531 | } | ||
| 532 | |||
| 533 | str = dbi_result_get_string_idx (res, 1); | ||
| 534 | if ((! str) || (strcmp (str, "ERROR") == 0)) { | ||
| 535 | CHECK_IGNORE_ERROR (NULL); | ||
| 536 | np_dbi_print_error (conn, "CRITICAL - failed to fetch string value"); | ||
| 537 | return NULL; | ||
| 538 | } | ||
| 539 | |||
| 540 | if ((verbose && expect) || (verbose > 2)) | ||
| 541 | printf ("Query returned string '%s'\n", str); | ||
| 542 | return str; | ||
| 543 | } | ||
| 544 | |||
| 492 | double | 545 | double |
| 493 | get_field (dbi_conn conn, dbi_result res, unsigned short *field_type) | 546 | get_field (dbi_conn conn, dbi_result res, unsigned short *field_type) |
| 494 | { | 547 | { |
| @@ -504,17 +557,13 @@ get_field (dbi_conn conn, dbi_result res, unsigned short *field_type) | |||
| 504 | const char *val_str; | 557 | const char *val_str; |
| 505 | char *endptr = NULL; | 558 | char *endptr = NULL; |
| 506 | 559 | ||
| 507 | val_str = dbi_result_get_string_idx (res, 1); | 560 | val_str = get_field_str (conn, res, *field_type); |
| 508 | if ((! val_str) || (strcmp (val_str, "ERROR") == 0)) { | 561 | if (! val_str) { |
| 509 | CHECK_IGNORE_ERROR (NAN); | 562 | CHECK_IGNORE_ERROR (NAN); |
| 510 | np_dbi_print_error (conn, "CRITICAL - failed to fetch string value"); | ||
| 511 | *field_type = DBI_TYPE_ERROR; | 563 | *field_type = DBI_TYPE_ERROR; |
| 512 | return NAN; | 564 | return NAN; |
| 513 | } | 565 | } |
| 514 | 566 | ||
| 515 | if (verbose > 2) | ||
| 516 | printf ("Query returned string '%s'\n", val_str); | ||
| 517 | |||
| 518 | val = strtod (val_str, &endptr); | 567 | val = strtod (val_str, &endptr); |
| 519 | if (endptr == val_str) { | 568 | if (endptr == val_str) { |
| 520 | CHECK_IGNORE_ERROR (NAN); | 569 | CHECK_IGNORE_ERROR (NAN); |
| @@ -543,7 +592,7 @@ get_field (dbi_conn conn, dbi_result res, unsigned short *field_type) | |||
| 543 | } | 592 | } |
| 544 | 593 | ||
| 545 | double | 594 | double |
| 546 | get_query_result (dbi_conn conn, dbi_result res, double *res_val) | 595 | get_query_result (dbi_conn conn, dbi_result res, const char **res_val_str, double *res_val) |
| 547 | { | 596 | { |
| 548 | unsigned short field_type; | 597 | unsigned short field_type; |
| 549 | double val = NAN; | 598 | double val = NAN; |
| @@ -579,8 +628,13 @@ get_query_result (dbi_conn conn, dbi_result res, double *res_val) | |||
| 579 | } | 628 | } |
| 580 | 629 | ||
| 581 | field_type = dbi_result_get_field_type_idx (res, 1); | 630 | field_type = dbi_result_get_field_type_idx (res, 1); |
| 582 | if (field_type != DBI_TYPE_ERROR) | 631 | if (field_type != DBI_TYPE_ERROR) { |
| 583 | val = get_field (conn, res, &field_type); | 632 | if (expect) |
| 633 | /* the value will be freed in dbi_result_free */ | ||
| 634 | *res_val_str = strdup (get_field_str (conn, res, field_type)); | ||
| 635 | else | ||
| 636 | val = get_field (conn, res, &field_type); | ||
| 637 | } | ||
| 584 | 638 | ||
| 585 | *res_val = val; | 639 | *res_val = val; |
| 586 | 640 | ||
| @@ -597,7 +651,7 @@ get_query_result (dbi_conn conn, dbi_result res, double *res_val) | |||
| 597 | #undef CHECK_IGNORE_ERROR | 651 | #undef CHECK_IGNORE_ERROR |
| 598 | 652 | ||
| 599 | int | 653 | int |
| 600 | do_query (dbi_conn conn, double *res_val, double *res_time) | 654 | do_query (dbi_conn conn, const char **res_val_str, double *res_val, double *res_time) |
| 601 | { | 655 | { |
| 602 | dbi_result res; | 656 | dbi_result res; |
| 603 | 657 | ||
| @@ -617,11 +671,14 @@ do_query (dbi_conn conn, double *res_val, double *res_time) | |||
| 617 | return STATE_CRITICAL; | 671 | return STATE_CRITICAL; |
| 618 | } | 672 | } |
| 619 | 673 | ||
| 620 | status = get_query_result (conn, res, res_val); | 674 | status = get_query_result (conn, res, res_val_str, res_val); |
| 621 | 675 | ||
| 622 | gettimeofday (&timeval_end, NULL); | 676 | gettimeofday (&timeval_end, NULL); |
| 623 | *res_time = timediff (timeval_start, timeval_end); | 677 | *res_time = timediff (timeval_start, timeval_end); |
| 624 | 678 | ||
| 679 | if (verbose) | ||
| 680 | printf ("Time elapsed: %f\n", *res_time); | ||
| 681 | |||
| 625 | return status; | 682 | return status; |
| 626 | } | 683 | } |
| 627 | 684 | ||
