summaryrefslogtreecommitdiffstats
path: root/plugins/check_dbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_dbi.c')
-rw-r--r--plugins/check_dbi.c95
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;
68char *critical_range = NULL; 68char *critical_range = NULL;
69thresholds *dbi_thresholds = NULL; 69thresholds *dbi_thresholds = NULL;
70 70
71char *expect = NULL;
72
71np_dbi_metric_t metric = METRIC_QUERY_RESULT; 73np_dbi_metric_t metric = METRIC_QUERY_RESULT;
72 74
73char *np_dbi_driver = NULL; 75char *np_dbi_driver = NULL;
@@ -85,7 +87,7 @@ double timediff (struct timeval, struct timeval);
85 87
86void np_dbi_print_error (dbi_conn, char *, ...); 88void np_dbi_print_error (dbi_conn, char *, ...);
87 89
88int do_query (dbi_conn, double *, double *); 90int do_query (dbi_conn, const char **, double *, double *);
89 91
90int 92int
91main (int argc, char **argv) 93main (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
523const char *
524get_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
492double 545double
493get_field (dbi_conn conn, dbi_result res, unsigned short *field_type) 546get_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
545double 594double
546get_query_result (dbi_conn conn, dbi_result res, double *res_val) 595get_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
599int 653int
600do_query (dbi_conn conn, double *res_val, double *res_time) 654do_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