summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_dbi.c101
1 files changed, 89 insertions, 12 deletions
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c
index 94c6b15f..39898cfa 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
61typedef enum {
62 TYPE_NUMERIC,
63 TYPE_STRING,
64} np_dbi_type_t;
65
59typedef struct { 66typedef struct {
60 char *key; 67 char *key;
61 char *value; 68 char *value;
@@ -70,7 +77,12 @@ thresholds *dbi_thresholds = NULL;
70 77
71char *expect = NULL; 78char *expect = NULL;
72 79
80regex_t expect_re;
81char *expect_re_str = NULL;
82int expect_re_cflags = 0;
83
73np_dbi_metric_t metric = METRIC_QUERY_RESULT; 84np_dbi_metric_t metric = METRIC_QUERY_RESULT;
85np_dbi_type_t type = TYPE_NUMERIC;
74 86
75char *np_dbi_driver = NULL; 87char *np_dbi_driver = NULL;
76driver_option_t *np_dbi_options = NULL; 88driver_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