From b7e661c4ae46cb6a919a5dbf1bfb28c38e409a64 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Mon, 18 Apr 2011 13:04:28 +0200 Subject: 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. --- plugins/check_dbi.c | 101 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file 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"; #include "netutils.h" +#include "regex.h" + /* required for NAN */ #ifndef _ISOC99_SOURCE #define _ISOC99_SOURCE @@ -56,6 +58,11 @@ typedef enum { METRIC_QUERY_TIME, } np_dbi_metric_t; +typedef enum { + TYPE_NUMERIC, + TYPE_STRING, +} np_dbi_type_t; + typedef struct { char *key; char *value; @@ -70,7 +77,12 @@ thresholds *dbi_thresholds = NULL; char *expect = NULL; +regex_t expect_re; +char *expect_re_str = NULL; +int expect_re_cflags = 0; + np_dbi_metric_t metric = METRIC_QUERY_RESULT; +np_dbi_type_t type = TYPE_NUMERIC; char *np_dbi_driver = NULL; driver_option_t *np_dbi_options = NULL; @@ -239,6 +251,22 @@ main (int argc, char **argv) else status = STATE_OK; } + else if (expect_re_str) { + int err; + + err = regexec (&expect_re, query_val_str, 0, NULL, /* flags = */ 0); + if (! err) + status = STATE_OK; + else if (err == REG_NOMATCH) + status = STATE_CRITICAL; + else { + char errmsg[1024]; + regerror (err, &expect_re, errmsg, sizeof (errmsg)); + printf ("ERROR - failed to execute regular expression: %s\n", + errmsg); + status = STATE_CRITICAL; + } + } else status = get_status (query_val, dbi_thresholds); } @@ -251,16 +279,26 @@ main (int argc, char **argv) dbi_conn_close (conn); /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error - * which should have been reported and handled (abort) before */ - assert ((metric != METRIC_QUERY_RESULT) || (! isnan (query_val)) || expect); + * which should have been reported and handled (abort) before + * ... unless we expected a string to be returned */ + assert ((metric != METRIC_QUERY_RESULT) || (! isnan (query_val)) + || (type == TYPE_STRING)); + + assert ((type != TYPE_STRING) || (expect || expect_re_str)); printf ("%s - connection time: %fs", state_text (status), conn_time); if (np_dbi_query) { - if (expect) { + if (type == TYPE_STRING) { + assert (expect || expect_re_str); printf (", '%s' returned '%s' in %fs", np_dbi_query, query_val_str ? query_val_str : "", query_time); - if (status != STATE_OK) - printf (" (expected '%s')", expect); + if (status != STATE_OK) { + if (expect) + printf (" (expected '%s')", expect); + else if (expect_re_str) + printf (" (expected regex /%s/%s)", expect_re_str, + ((expect_re_cflags & REG_ICASE) ? "i" : "")); + } } else if (isnan (query_val)) printf (", '%s' query execution time: %fs", np_dbi_query, query_time); @@ -295,6 +333,8 @@ process_arguments (int argc, char **argv) STD_LONG_OPTS, {"expect", required_argument, 0, 'e'}, + {"regex", required_argument, 0, 'r'}, + {"regexi", required_argument, 0, 'R'}, {"metric", required_argument, 0, 'm'}, {"driver", required_argument, 0, 'd'}, {"option", required_argument, 0, 'o'}, @@ -304,7 +344,7 @@ process_arguments (int argc, char **argv) }; while (1) { - c = getopt_long (argc, argv, "Vvht:c:w:e:m:H:d:o:q:D:", + c = getopt_long (argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", longopts, &option); if (c == EOF) @@ -322,13 +362,38 @@ process_arguments (int argc, char **argv) case 'c': /* critical range */ critical_range = optarg; + type = TYPE_NUMERIC; break; case 'w': /* warning range */ warning_range = optarg; + type = TYPE_NUMERIC; break; case 'e': expect = optarg; + type = TYPE_STRING; break; + case 'R': + expect_re_cflags = REG_ICASE; + /* fall through */ + case 'r': + { + int err; + + expect_re_cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; + expect_re_str = optarg; + type = TYPE_STRING; + + err = regcomp (&expect_re, expect_re_str, expect_re_cflags); + if (err) { + char errmsg[1024]; + regerror (err, &expect_re, errmsg, sizeof (errmsg)); + printf ("ERROR - failed to compile regular expression: %s\n", + errmsg); + return ERROR; + } + break; + } + case 'm': if (! strcasecmp (optarg, "CONN_TIME")) metric = METRIC_CONN_TIME; @@ -417,12 +482,18 @@ validate_arguments () && (metric != METRIC_QUERY_TIME)) usage ("Invalid metric specified"); - if (expect && (warning_range || critical_range)) - usage ("Do not mix -e and -w/-c"); + if (expect && (warning_range || critical_range || expect_re_str)) + usage ("Do not mix -e and -w/-c/-r/-R"); + + if (expect_re_str && (warning_range || critical_range || expect)) + usage ("Do not mix -r/-R and -w/-c/-e"); if (expect && (metric != METRIC_QUERY_RESULT)) usage ("Option -e requires metric QUERY_RESULT"); + if (expect_re_str && (metric != METRIC_QUERY_RESULT)) + usage ("Options -r/-R require metric QUERY_RESULT"); + return OK; } @@ -460,7 +531,13 @@ print_help (void) printf (UT_WARN_CRIT_RANGE); printf (" %s\n", "-e, --expect=STRING"); printf (" %s\n", _("String to expect as query result")); - printf (" %s\n", _("Do not mix with -w or -c!")); + printf (" %s\n", _("Do not mix with -w, -c, -r, or -R!")); + printf (" %s\n", "-r, --regex=REGEX"); + printf (" %s\n", _("Extended POSIX regular expression to check query result against")); + printf (" %s\n", _("Do not mix with -w, -c, -e, or -R!")); + printf (" %s\n", "-R, --regexi=REGEX"); + printf (" %s\n", _("Case-insensitive extended POSIX regex to check query result against")); + printf (" %s\n", _("Do not mix with -w, -c, -e, or -r!")); printf (" %s\n", "-m, --metric=METRIC"); printf (" %s\n", _("Metric to check thresholds against. Available metrics:")); printf (" CONN_TIME - %s\n", _("time used for setting up the database connection")); @@ -511,7 +588,7 @@ print_usage (void) printf ("%s\n", _("Usage:")); printf ("%s -d [-o [...]] [-q ]\n", progname); printf (" [-H ] [-c ] [-w ] [-m ]\n"); - printf (" [-e ]\n"); + printf (" [-e ] [-r|-R ]\n"); } #define CHECK_IGNORE_ERROR(s) \ @@ -537,7 +614,7 @@ get_field_str (dbi_conn conn, dbi_result res, unsigned short field_type) return NULL; } - if ((verbose && expect) || (verbose > 2)) + if ((verbose && (type == TYPE_STRING)) || (verbose > 2)) printf ("Query returned string '%s'\n", str); return str; } @@ -629,7 +706,7 @@ get_query_result (dbi_conn conn, dbi_result res, const char **res_val_str, doubl field_type = dbi_result_get_field_type_idx (res, 1); if (field_type != DBI_TYPE_ERROR) { - if (expect) + if (type == TYPE_STRING) /* the value will be freed in dbi_result_free */ *res_val_str = strdup (get_field_str (conn, res, field_type)); else -- cgit v1.2.3-74-g34f1