diff options
-rw-r--r-- | plugins/check_dbi.c | 131 |
1 files changed, 70 insertions, 61 deletions
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index 611e0e7..f009944 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * | 10 | * |
11 | * This file contains the check_dbi plugin | 11 | * This file contains the check_dbi plugin |
12 | * | 12 | * |
13 | * Runs an arbitrary SQL command and checks the result. | 13 | * Runs an arbitrary (SQL) command and checks the result. |
14 | * | 14 | * |
15 | * | 15 | * |
16 | * This program is free software: you can redistribute it and/or modify | 16 | * This program is free software: you can redistribute it and/or modify |
@@ -38,10 +38,17 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
38 | 38 | ||
39 | #include "netutils.h" | 39 | #include "netutils.h" |
40 | 40 | ||
41 | #include <assert.h> | ||
42 | |||
41 | #include <dbi/dbi.h> | 43 | #include <dbi/dbi.h> |
42 | 44 | ||
43 | #include <stdarg.h> | 45 | #include <stdarg.h> |
44 | 46 | ||
47 | typedef enum { | ||
48 | METRIC_CONN_TIME, | ||
49 | METRIC_QUERY_RESULT, | ||
50 | } np_dbi_metric_t; | ||
51 | |||
45 | typedef struct { | 52 | typedef struct { |
46 | char *key; | 53 | char *key; |
47 | char *value; | 54 | char *value; |
@@ -52,11 +59,9 @@ int verbose = 0; | |||
52 | 59 | ||
53 | char *warning_range = NULL; | 60 | char *warning_range = NULL; |
54 | char *critical_range = NULL; | 61 | char *critical_range = NULL; |
55 | thresholds *query_thresholds = NULL; | 62 | thresholds *dbi_thresholds = NULL; |
56 | 63 | ||
57 | char *conntime_warning_range = NULL; | 64 | np_dbi_metric_t metric = METRIC_QUERY_RESULT; |
58 | char *conntime_critical_range = NULL; | ||
59 | thresholds *conntime_thresholds = NULL; | ||
60 | 65 | ||
61 | char *np_dbi_driver = NULL; | 66 | char *np_dbi_driver = NULL; |
62 | driver_option_t *np_dbi_options = NULL; | 67 | driver_option_t *np_dbi_options = NULL; |
@@ -78,11 +83,8 @@ int do_query (dbi_conn, double *, double *); | |||
78 | int | 83 | int |
79 | main (int argc, char **argv) | 84 | main (int argc, char **argv) |
80 | { | 85 | { |
81 | int conntime_status = STATE_UNKNOWN; | ||
82 | int status = STATE_UNKNOWN; | 86 | int status = STATE_UNKNOWN; |
83 | 87 | ||
84 | int exit_status = STATE_UNKNOWN; | ||
85 | |||
86 | dbi_driver driver; | 88 | dbi_driver driver; |
87 | dbi_conn conn; | 89 | dbi_conn conn; |
88 | 90 | ||
@@ -198,7 +200,8 @@ main (int argc, char **argv) | |||
198 | if (verbose) | 200 | if (verbose) |
199 | printf("Time elapsed: %f\n", conn_time); | 201 | printf("Time elapsed: %f\n", conn_time); |
200 | 202 | ||
201 | conntime_status = get_status (conn_time, conntime_thresholds); | 203 | if (metric == METRIC_CONN_TIME) |
204 | status = get_status (conn_time, dbi_thresholds); | ||
202 | 205 | ||
203 | /* select a database */ | 206 | /* select a database */ |
204 | if (np_dbi_database) { | 207 | if (np_dbi_database) { |
@@ -212,36 +215,35 @@ main (int argc, char **argv) | |||
212 | } | 215 | } |
213 | } | 216 | } |
214 | 217 | ||
215 | /* execute query */ | 218 | if (np_dbi_query) { |
216 | status = do_query (conn, &query_val, &query_time); | 219 | /* execute query */ |
217 | if (status != STATE_OK) | 220 | status = do_query (conn, &query_val, &query_time); |
218 | /* do_query prints an error message in this case */ | 221 | if (status != STATE_OK) |
219 | return status; | 222 | /* do_query prints an error message in this case */ |
223 | return status; | ||
220 | 224 | ||
221 | status = get_status (query_val, query_thresholds); | 225 | if (metric == METRIC_QUERY_RESULT) |
226 | status = get_status (query_val, dbi_thresholds); | ||
227 | } | ||
222 | 228 | ||
223 | if (verbose) | 229 | if (verbose) |
224 | printf("Closing connection\n"); | 230 | printf("Closing connection\n"); |
225 | dbi_conn_close (conn); | 231 | dbi_conn_close (conn); |
226 | 232 | ||
227 | /* 'conntime_status' is worse than 'status' (but not UNKOWN) */ | 233 | printf ("%s - connection time: %fs", state_text (status), conn_time); |
228 | if (((conntime_status < STATE_UNKNOWN) && (conntime_status > status)) | 234 | if (np_dbi_query) |
229 | /* 'status' is UNKNOWN and 'conntime_status' is not OK */ | 235 | printf (", '%s' returned %f in %fs", np_dbi_query, query_val, query_time); |
230 | || ((status >= STATE_UNKNOWN) && (conntime_status != STATE_OK))) | 236 | |
231 | exit_status = conntime_status; | 237 | printf (" | conntime=%fs;%s;%s;0;", conn_time, |
232 | else | 238 | ((metric == METRIC_CONN_TIME) && warning_range) ? warning_range : "", |
233 | exit_status = status; | 239 | ((metric == METRIC_CONN_TIME) && critical_range) ? critical_range : ""); |
234 | 240 | if (np_dbi_query) | |
235 | printf ("%s - %s: connection time: %fs, %s: '%s' returned %f in %fs", | 241 | printf (" query=%f;%s;%s;; querytime=%fs;;;0;", query_val, |
236 | state_text (exit_status), | 242 | ((metric == METRIC_QUERY_RESULT) && warning_range) ? warning_range : "", |
237 | state_text (conntime_status), conn_time, | 243 | ((metric == METRIC_QUERY_RESULT) && critical_range) ? critical_range : "", |
238 | state_text (status), np_dbi_query, query_val, query_time); | 244 | query_time); |
239 | printf (" | conntime=%fs;%s;%s;0; query=%f;%s;%s;; querytime=%fs;;;0;\n", conn_time, | 245 | printf ("\n"); |
240 | conntime_warning_range ? conntime_warning_range : "", | 246 | return status; |
241 | conntime_critical_range ? conntime_critical_range : "", | ||
242 | query_val, warning_range ? warning_range : "", critical_range ? critical_range : "", | ||
243 | query_time); | ||
244 | return exit_status; | ||
245 | } | 247 | } |
246 | 248 | ||
247 | /* process command-line arguments */ | 249 | /* process command-line arguments */ |
@@ -254,9 +256,7 @@ process_arguments (int argc, char **argv) | |||
254 | static struct option longopts[] = { | 256 | static struct option longopts[] = { |
255 | STD_LONG_OPTS, | 257 | STD_LONG_OPTS, |
256 | 258 | ||
257 | {"conntime-warning", required_argument, 0, 'W'}, | 259 | {"metric", required_argument, 0, 'm'}, |
258 | {"conntime-critical", required_argument, 0, 'C'}, | ||
259 | |||
260 | {"driver", required_argument, 0, 'd'}, | 260 | {"driver", required_argument, 0, 'd'}, |
261 | {"option", required_argument, 0, 'o'}, | 261 | {"option", required_argument, 0, 'o'}, |
262 | {"query", required_argument, 0, 'q'}, | 262 | {"query", required_argument, 0, 'q'}, |
@@ -265,7 +265,7 @@ process_arguments (int argc, char **argv) | |||
265 | }; | 265 | }; |
266 | 266 | ||
267 | while (1) { | 267 | while (1) { |
268 | c = getopt_long (argc, argv, "Vvht:c:w:H:W:C:d:o:q:D:", | 268 | c = getopt_long (argc, argv, "Vvht:c:w:m:H:d:o:q:D:", |
269 | longopts, &option); | 269 | longopts, &option); |
270 | 270 | ||
271 | if (c == EOF) | 271 | if (c == EOF) |
@@ -287,19 +287,20 @@ process_arguments (int argc, char **argv) | |||
287 | case 'w': /* warning range */ | 287 | case 'w': /* warning range */ |
288 | warning_range = optarg; | 288 | warning_range = optarg; |
289 | break; | 289 | break; |
290 | case 'm': | ||
291 | if (! strcasecmp (optarg, "CONN_TIME")) | ||
292 | metric = METRIC_CONN_TIME; | ||
293 | else if (! strcasecmp (optarg, "QUERY_RESULT")) | ||
294 | metric = METRIC_QUERY_RESULT; | ||
295 | else | ||
296 | usage2 (_("Invalid metric"), optarg); | ||
297 | break; | ||
290 | case 't': /* timeout */ | 298 | case 't': /* timeout */ |
291 | if (!is_intnonneg (optarg)) | 299 | if (!is_intnonneg (optarg)) |
292 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 300 | usage2 (_("Timeout interval must be a positive integer"), optarg); |
293 | else | 301 | else |
294 | timeout_interval = atoi (optarg); | 302 | timeout_interval = atoi (optarg); |
295 | 303 | ||
296 | case 'C': /* critical conntime range */ | ||
297 | conntime_critical_range = optarg; | ||
298 | break; | ||
299 | case 'W': /* warning conntime range */ | ||
300 | conntime_warning_range = optarg; | ||
301 | break; | ||
302 | |||
303 | case 'H': /* host */ | 304 | case 'H': /* host */ |
304 | if (!is_host (optarg)) | 305 | if (!is_host (optarg)) |
305 | usage2 (_("Invalid hostname/address"), optarg); | 306 | usage2 (_("Invalid hostname/address"), optarg); |
@@ -352,8 +353,7 @@ process_arguments (int argc, char **argv) | |||
352 | } | 353 | } |
353 | } | 354 | } |
354 | 355 | ||
355 | set_thresholds (&query_thresholds, warning_range, critical_range); | 356 | set_thresholds (&dbi_thresholds, warning_range, critical_range); |
356 | set_thresholds (&conntime_thresholds, conntime_warning_range, conntime_critical_range); | ||
357 | 357 | ||
358 | return validate_arguments (); | 358 | return validate_arguments (); |
359 | } | 359 | } |
@@ -364,8 +364,12 @@ validate_arguments () | |||
364 | if (! np_dbi_driver) | 364 | if (! np_dbi_driver) |
365 | usage ("Must specify a DBI driver"); | 365 | usage ("Must specify a DBI driver"); |
366 | 366 | ||
367 | if (! np_dbi_query) | 367 | if ((metric == METRIC_QUERY_RESULT) && (! np_dbi_query)) |
368 | usage ("Must specify an SQL query to execute"); | 368 | usage ("Must specify a query to execute (metric == QUERY_RESULT)"); |
369 | |||
370 | if ((metric != METRIC_CONN_TIME) | ||
371 | && (metric != METRIC_QUERY_RESULT)) | ||
372 | usage ("Invalid metric specified"); | ||
369 | 373 | ||
370 | return OK; | 374 | return OK; |
371 | } | 375 | } |
@@ -377,7 +381,9 @@ print_help (void) | |||
377 | 381 | ||
378 | printf (COPYRIGHT, copyright, email); | 382 | printf (COPYRIGHT, copyright, email); |
379 | 383 | ||
380 | printf (_("This program checks a query result against threshold levels")); | 384 | printf (_("This program connects to an (SQL) database using DBI and checks the\n" |
385 | "specified metric against threshold levels. The default metric is\n" | ||
386 | "the result of the specified query.\n")); | ||
381 | 387 | ||
382 | printf ("\n\n"); | 388 | printf ("\n\n"); |
383 | 389 | ||
@@ -396,14 +402,14 @@ print_help (void) | |||
396 | printf (" %s\n", "-o, --option=STRING"); | 402 | printf (" %s\n", "-o, --option=STRING"); |
397 | printf (" %s\n", _("DBI driver options")); | 403 | printf (" %s\n", _("DBI driver options")); |
398 | printf (" %s\n", "-q, --query=STRING"); | 404 | printf (" %s\n", "-q, --query=STRING"); |
399 | printf (" %s\n", _("SQL query to execute")); | 405 | printf (" %s\n", _("query to execute")); |
400 | printf ("\n"); | 406 | printf ("\n"); |
401 | 407 | ||
402 | printf (UT_WARN_CRIT_RANGE); | 408 | printf (UT_WARN_CRIT_RANGE); |
403 | printf (" %s\n", "-W, --conntime-warning=RANGE"); | 409 | printf (" %s\n", "-m, --metric=METRIC"); |
404 | printf (" %s\n", _("Connection time warning range")); | 410 | printf (" %s\n", _("Metric to check thresholds against. Available metrics:")); |
405 | printf (" %s\n", "-C, --conntime-critical=RANGE"); | 411 | printf (" CONN_TIME - %s\n", _("time used for setting up the database connection")); |
406 | printf (" %s\n", _("Connection time critical range")); | 412 | printf (" QUERY_RESULT - %s\n", _("result (first column of first row) of the query")); |
407 | printf ("\n"); | 413 | printf ("\n"); |
408 | 414 | ||
409 | printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 415 | printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
@@ -411,10 +417,12 @@ print_help (void) | |||
411 | printf (UT_VERBOSE); | 417 | printf (UT_VERBOSE); |
412 | 418 | ||
413 | printf ("\n"); | 419 | printf ("\n"); |
414 | printf (" %s\n", _("A DBI driver (-d option) and a query (-q option) are required.")); | 420 | printf (" %s\n", _("A DBI driver (-d option) is required. If the specified metric operates")); |
415 | printf (" %s\n", _("This plugin connects to an SQL database using libdbi and executes the")); | 421 | printf (" %s\n\n", _("on a query, one has to be specified (-q option).")); |
416 | printf (" %s\n", _("specified SQL query. The first column of the first row of the result")); | 422 | |
417 | printf (" %s\n", _("will be used as the check result and, if specified, compared with the")); | 423 | printf (" %s\n", _("This plugin connects to an (SQL) database using libdbi and, optionally,")); |
424 | printf (" %s\n", _("executes the specified query. The first column of the first row of the")); | ||
425 | printf (" %s\n", _("result will be parsed and, in QUERY_RESULT mode, compared with the")); | ||
418 | printf (" %s\n", _("warning and critical ranges. The result from the query has to be numeric")); | 426 | printf (" %s\n", _("warning and critical ranges. The result from the query has to be numeric")); |
419 | printf (" %s\n\n", _("(strings representing numbers are fine).")); | 427 | printf (" %s\n\n", _("(strings representing numbers are fine).")); |
420 | 428 | ||
@@ -429,9 +437,8 @@ void | |||
429 | print_usage (void) | 437 | print_usage (void) |
430 | { | 438 | { |
431 | printf ("%s\n", _("Usage:")); | 439 | printf ("%s\n", _("Usage:")); |
432 | printf ("%s -d <DBI driver> [-o <DBI driver option> [...]] -q <SQL query>\n", progname); | 440 | printf ("%s -d <DBI driver> [-o <DBI driver option> [...]] [-q <query>]\n", progname); |
433 | printf (" [-H <host>] [-c <critical range>] [-w <warning range>]\n"); | 441 | printf (" [-H <host>] [-c <critical range>] [-w <warning range>] [-m <metric>]\n"); |
434 | printf (" [-C <critical conntime range>] [-W <warning conntime range>]\n"); | ||
435 | } | 442 | } |
436 | 443 | ||
437 | double | 444 | double |
@@ -494,6 +501,8 @@ do_query (dbi_conn conn, double *res_val, double *res_time) | |||
494 | 501 | ||
495 | struct timeval timeval_start, timeval_end; | 502 | struct timeval timeval_start, timeval_end; |
496 | 503 | ||
504 | assert (np_dbi_query); | ||
505 | |||
497 | if (verbose) | 506 | if (verbose) |
498 | printf ("Executing query '%s'\n", np_dbi_query); | 507 | printf ("Executing query '%s'\n", np_dbi_query); |
499 | 508 | ||