summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_dbi.c430
-rw-r--r--plugins/t/check_dbi.t10
2 files changed, 295 insertions, 145 deletions
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c
index 786fc1b6..84e3cb5b 100644
--- a/plugins/check_dbi.c
+++ b/plugins/check_dbi.c
@@ -29,12 +29,14 @@
29 * 29 *
30 *****************************************************************************/ 30 *****************************************************************************/
31 31
32#include "states.h"
33const char *progname = "check_dbi"; 32const char *progname = "check_dbi";
34const char *copyright = "2011-2024"; 33const char *copyright = "2011-2024";
35const char *email = "devel@monitoring-plugins.org"; 34const char *email = "devel@monitoring-plugins.org";
36 35
37#include "../lib/monitoringplug.h" 36#include "../lib/monitoringplug.h"
37#include "perfdata.h"
38#include "output.h"
39#include "states.h"
38#include "check_dbi.d/config.h" 40#include "check_dbi.d/config.h"
39#include "common.h" 41#include "common.h"
40#include "utils.h" 42#include "utils.h"
@@ -72,9 +74,15 @@ static double timediff(struct timeval /*start*/, struct timeval /*end*/);
72 74
73static void np_dbi_print_error(dbi_conn /*conn*/, char * /*fmt*/, ...); 75static void np_dbi_print_error(dbi_conn /*conn*/, char * /*fmt*/, ...);
74 76
75static mp_state_enum do_query(dbi_conn /*conn*/, const char ** /*res_val_str*/, 77typedef struct {
76 double * /*res_val*/, double * /*res_time*/, mp_dbi_metric /*metric*/, 78 char *result_string;
77 mp_dbi_type /*type*/, char * /*np_dbi_query*/); 79 double result_number;
80 double query_duration;
81 int error_code;
82 const char *error_string;
83 mp_state_enum query_processing_status;
84} do_query_result;
85static do_query_result do_query(dbi_conn conn, mp_dbi_metric metric, mp_dbi_type type, char *query);
78 86
79int main(int argc, char **argv) { 87int main(int argc, char **argv) {
80 setlocale(LC_ALL, ""); 88 setlocale(LC_ALL, "");
@@ -104,16 +112,17 @@ int main(int argc, char **argv) {
104 112
105 dbi_inst instance_p = NULL; 113 dbi_inst instance_p = NULL;
106 if (dbi_initialize_r(NULL, &instance_p) < 0) { 114 if (dbi_initialize_r(NULL, &instance_p) < 0) {
107 printf( 115 printf("failed to initialize DBI; possibly you don't have any drivers installed.\n");
108 "UNKNOWN - failed to initialize DBI; possibly you don't have any drivers installed.\n"); 116 exit(STATE_UNKNOWN);
109 return STATE_UNKNOWN;
110 } 117 }
111 118
119 // Try to prevent libdbi from printing stuff on stderr
120 // Who thought that would be a good idea anyway?
112 dbi_set_verbosity_r(0, instance_p); 121 dbi_set_verbosity_r(0, instance_p);
113 122
114 if (instance_p == NULL) { 123 if (instance_p == NULL) {
115 printf("UNKNOWN - failed to initialize DBI.\n"); 124 printf("failed to initialize DBI.\n");
116 return STATE_UNKNOWN; 125 exit(STATE_UNKNOWN);
117 } 126 }
118 127
119 if (verbose) { 128 if (verbose) {
@@ -122,15 +131,14 @@ int main(int argc, char **argv) {
122 131
123 dbi_driver driver = dbi_driver_open_r(config.dbi_driver, instance_p); 132 dbi_driver driver = dbi_driver_open_r(config.dbi_driver, instance_p);
124 if (!driver) { 133 if (!driver) {
125 printf("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", 134 printf("failed to open DBI driver '%s'; possibly it's not installed.\n", config.dbi_driver);
126 config.dbi_driver);
127 135
128 printf("Known drivers:\n"); 136 printf("Known drivers:\n");
129 for (driver = dbi_driver_list_r(NULL, instance_p); driver; 137 for (driver = dbi_driver_list_r(NULL, instance_p); driver;
130 driver = dbi_driver_list_r(driver, instance_p)) { 138 driver = dbi_driver_list_r(driver, instance_p)) {
131 printf(" - %s\n", dbi_driver_get_name(driver)); 139 printf(" - %s\n", dbi_driver_get_name(driver));
132 } 140 }
133 return STATE_UNKNOWN; 141 exit(STATE_UNKNOWN);
134 } 142 }
135 143
136 /* make a connection to the database */ 144 /* make a connection to the database */
@@ -141,7 +149,7 @@ int main(int argc, char **argv) {
141 if (!conn) { 149 if (!conn) {
142 printf("UNKNOWN - failed top open connection object.\n"); 150 printf("UNKNOWN - failed top open connection object.\n");
143 dbi_conn_close(conn); 151 dbi_conn_close(conn);
144 return STATE_UNKNOWN; 152 exit(STATE_UNKNOWN);
145 } 153 }
146 154
147 for (size_t i = 0; i < config.dbi_options_num; ++i) { 155 for (size_t i = 0; i < config.dbi_options_num; ++i) {
@@ -155,10 +163,10 @@ int main(int argc, char **argv) {
155 if (!dbi_conn_set_option(conn, config.dbi_options[i].key, config.dbi_options[i].value)) { 163 if (!dbi_conn_set_option(conn, config.dbi_options[i].key, config.dbi_options[i].value)) {
156 continue; 164 continue;
157 } 165 }
158 /* else: status != 0 */
159 166
160 np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", 167 // Failing to set option
161 config.dbi_options[i].key, config.dbi_options[i].value); 168 np_dbi_print_error(conn, "failed to set option '%s' to '%s'", config.dbi_options[i].key,
169 config.dbi_options[i].value);
162 printf("Known driver options:\n"); 170 printf("Known driver options:\n");
163 171
164 for (opt = dbi_conn_get_option_list(conn, NULL); opt; 172 for (opt = dbi_conn_get_option_list(conn, NULL); opt;
@@ -166,7 +174,7 @@ int main(int argc, char **argv) {
166 printf(" - %s\n", opt); 174 printf(" - %s\n", opt);
167 } 175 }
168 dbi_conn_close(conn); 176 dbi_conn_close(conn);
169 return STATE_UNKNOWN; 177 exit(STATE_UNKNOWN);
170 } 178 }
171 179
172 if (config.host) { 180 if (config.host) {
@@ -194,31 +202,60 @@ int main(int argc, char **argv) {
194 } 202 }
195 203
196 if (dbi_conn_connect(conn) < 0) { 204 if (dbi_conn_connect(conn) < 0) {
197 np_dbi_print_error(conn, "UNKNOWN - failed to connect to database"); 205 np_dbi_print_error(conn, "failed to connect to database");
198 return STATE_UNKNOWN; 206 exit(STATE_UNKNOWN);
199 } 207 }
200 208
201 struct timeval end_timeval; 209 struct timeval end_timeval;
202 gettimeofday(&end_timeval, NULL); 210 gettimeofday(&end_timeval, NULL);
203 double conn_time = timediff(start_timeval, end_timeval); 211 double conn_time = timediff(start_timeval, end_timeval);
212 if (verbose) {
213 printf("Time elapsed: %f\n", conn_time);
214 }
215
216 mp_check overall = mp_check_init();
217
218 mp_subcheck sc_connection_time = mp_subcheck_init();
219 sc_connection_time = mp_set_subcheck_default_state(sc_connection_time, STATE_OK);
220 xasprintf(&sc_connection_time.output, "Connection time: %f", conn_time);
221
222 mp_perfdata pd_conn_duration = perfdata_init();
223 pd_conn_duration.label = "conntime";
224 pd_conn_duration = mp_set_pd_value(pd_conn_duration, conn_time);
225
226 if (config.metric == METRIC_CONN_TIME) {
227 // TODO set pd thresholds
228 mp_state_enum status = get_status(conn_time, config.dbi_thresholds);
229 sc_connection_time = mp_set_subcheck_state(sc_connection_time, status);
230 if (status != STATE_OK) {
231 xasprintf(&sc_connection_time.output, "%s violates thresholds",
232 sc_connection_time.output);
233 }
234 }
235
236 mp_add_perfdata_to_subcheck(&sc_connection_time, pd_conn_duration);
237 mp_add_subcheck_to_check(&overall, sc_connection_time);
204 238
205 unsigned int server_version = dbi_conn_get_engine_version(conn); 239 unsigned int server_version = dbi_conn_get_engine_version(conn);
206 if (verbose) { 240 if (verbose) {
207 printf("Connected to server version %u\n", server_version); 241 printf("Connected to server version %u\n", server_version);
208 } 242 }
209 243
210 int status = STATE_UNKNOWN; 244 mp_subcheck sc_server_version = mp_subcheck_init();
245 sc_server_version = mp_set_subcheck_default_state(sc_server_version, STATE_OK);
246 xasprintf(&sc_server_version.output, "Connected to server version %u", server_version);
247
211 if (config.metric == METRIC_SERVER_VERSION) { 248 if (config.metric == METRIC_SERVER_VERSION) {
212 status = get_status(server_version, config.dbi_thresholds); 249 mp_state_enum status = get_status(server_version, config.dbi_thresholds);
213 }
214 250
215 if (verbose) { 251 sc_server_version = mp_set_subcheck_state(sc_server_version, status);
216 printf("Time elapsed: %f\n", conn_time);
217 }
218 252
219 if (config.metric == METRIC_CONN_TIME) { 253 if (status != STATE_OK) {
220 status = get_status(conn_time, config.dbi_thresholds); 254 xasprintf(&sc_server_version.output, "%s violates thresholds",
221 } 255 sc_server_version.output);
256 }
257 };
258 mp_add_subcheck_to_check(&overall, sc_server_version);
222 259
223 /* select a database */ 260 /* select a database */
224 if (config.dbi_database) { 261 if (config.dbi_database) {
@@ -226,58 +263,152 @@ int main(int argc, char **argv) {
226 printf("Selecting database '%s'\n", config.dbi_database); 263 printf("Selecting database '%s'\n", config.dbi_database);
227 } 264 }
228 265
266 mp_subcheck sc_select_db = mp_subcheck_init();
267 sc_select_db = mp_set_subcheck_default_state(sc_select_db, STATE_OK);
268
229 if (dbi_conn_select_db(conn, config.dbi_database)) { 269 if (dbi_conn_select_db(conn, config.dbi_database)) {
230 np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", 270 np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'",
231 config.dbi_database); 271 config.dbi_database);
232 return STATE_UNKNOWN; 272 exit(STATE_UNKNOWN);
273 } else {
274 mp_add_subcheck_to_check(&overall, sc_select_db);
233 } 275 }
234 } 276 }
235 277
236 const char *query_val_str = NULL; 278 // Do a query (if configured)
237 double query_val = 0.0;
238 double query_time = 0.0;
239 if (config.dbi_query) { 279 if (config.dbi_query) {
280 mp_subcheck sc_query = mp_subcheck_init();
281 sc_query = mp_set_subcheck_default_state(sc_query, STATE_UNKNOWN);
282
240 /* execute query */ 283 /* execute query */
241 status = do_query(conn, &query_val_str, &query_val, &query_time, config.metric, config.type, 284 do_query_result query_res = do_query(conn, config.metric, config.type, config.dbi_query);
242 config.dbi_query); 285
243 if (status != STATE_OK) { 286 if (query_res.error_code != 0) {
244 /* do_query prints an error message in this case */ 287 xasprintf(&sc_query.output, "Query failed: %s", query_res.error_string);
245 return status; 288 sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL);
246 } 289 } else if (query_res.query_processing_status != STATE_OK) {
290 if (query_res.error_string) {
291 xasprintf(&sc_query.output, "Failed to process query: %s", query_res.error_string);
292 } else {
293 xasprintf(&sc_query.output, "Failed to process query");
294 }
295 sc_query = mp_set_subcheck_state(sc_query, query_res.query_processing_status);
296 } else {
297 // query succeeded in general
298 xasprintf(&sc_query.output, "Query '%s' succeeded", config.dbi_query);
299
300 // that's a OK by default now
301 sc_query = mp_set_subcheck_default_state(sc_query, STATE_OK);
302
303 // query duration first
304 mp_perfdata pd_query_duration = perfdata_init();
305 pd_query_duration = mp_set_pd_value(pd_query_duration, query_res.query_duration);
306 pd_query_duration.label = "querytime";
307 if (config.metric == METRIC_QUERY_TIME) {
308 // TODO set thresholds
309 }
310
311 mp_add_perfdata_to_subcheck(&sc_query, pd_query_duration);
247 312
248 if (config.metric == METRIC_QUERY_RESULT) { 313 if (config.metric == METRIC_QUERY_RESULT) {
249 if (config.expect) { 314 if (config.expect) {
250 if ((!query_val_str) || strcmp(query_val_str, config.expect)) { 315 if ((!query_res.result_string) ||
251 status = STATE_CRITICAL; 316 strcmp(query_res.result_string, config.expect)) {
317 xasprintf(&sc_query.output, "Found string '%s' in query result",
318 config.expect);
319 sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL);
320 } else {
321 xasprintf(&sc_query.output, "Did not find string '%s' in query result",
322 config.expect);
323 sc_query = mp_set_subcheck_state(sc_query, STATE_OK);
324 }
325 } else if (config.expect_re_str) {
326 int comp_err;
327 regex_t expect_re = {};
328 comp_err = regcomp(&expect_re, config.expect_re_str, config.expect_re_cflags);
329 if (comp_err != 0) {
330 // TODO error, failed to compile regex
331 // TODO move this to config sanitatisation
332 printf("Failed to compile regex from string '%s'", config.expect_re_str);
333 exit(STATE_UNKNOWN);
334 }
335
336 int err =
337 regexec(&expect_re, query_res.result_string, 0, NULL, /* flags = */ 0);
338 if (!err) {
339 sc_query = mp_set_subcheck_state(sc_query, STATE_OK);
340 xasprintf(&sc_query.output, "Found regular expression '%s' in query result",
341 config.expect_re_str);
342 } else if (err == REG_NOMATCH) {
343 sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL);
344 xasprintf(&sc_query.output,
345 "Did not find regular expression '%s' in query result",
346 config.expect_re_str);
347 } else {
348 char errmsg[1024];
349 regerror(err, &expect_re, errmsg, sizeof(errmsg));
350 xasprintf(&sc_query.output,
351 "ERROR - failed to execute regular expression: %s\n", errmsg);
352 sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL);
353 }
252 } else { 354 } else {
253 status = STATE_OK; 355 // no string matching
254 } 356 if (isnan(query_res.result_number)) {
255 } else if (config.expect_re_str) { 357 // The query result is not a number, but no string checking was configured
256 int comp_err; 358 // so we expected a number
257 regex_t expect_re = {}; 359 // this is a CRITICAL
258 comp_err = regcomp(&expect_re, config.expect_re_str, config.expect_re_cflags); 360 xasprintf(&sc_query.output, "Query '%s' result is not numeric",
259 if (comp_err != 0) { 361 config.dbi_query, query_res.result_string);
260 // TODO error, failed to compile regex 362 sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL);
261 return STATE_UNKNOWN; 363
364 } else {
365 mp_state_enum query_numerical_result =
366 get_status(query_res.result_number, config.dbi_thresholds);
367 sc_query = mp_set_subcheck_state(sc_query, query_numerical_result);
368
369 mp_perfdata pd_query_val = perfdata_init();
370 pd_query_val = mp_set_pd_value(pd_query_val, query_res.result_number);
371 pd_query_val.label = "query";
372 mp_add_perfdata_to_subcheck(&sc_query, pd_query_val);
373
374 // TODO set pd thresholds
375 // if (config.dbi_thresholds->warning) {
376 // pd_query_val.warn= config.dbi_thresholds->warning
377 // } else {
378 // }
379
380 if (query_numerical_result == STATE_OK) {
381 xasprintf(&sc_query.output,
382 "Query result '%f' is within given thresholds",
383 query_res.result_number);
384 } else {
385 xasprintf(&sc_query.output,
386 "Query result '%f' violates the given thresholds",
387 query_res.result_number);
388 }
389 }
262 } 390 }
263 391 } else if (config.metric == METRIC_QUERY_TIME) {
264 int err = regexec(&expect_re, query_val_str, 0, NULL, /* flags = */ 0); 392 mp_state_enum query_time_status =
265 if (!err) { 393 get_status(query_res.query_duration, config.dbi_thresholds);
266 status = STATE_OK; 394 mp_set_subcheck_state(sc_query, query_time_status);
267 } else if (err == REG_NOMATCH) { 395
268 status = STATE_CRITICAL; 396 if (query_time_status == STATE_OK) {
397 xasprintf(&sc_query.output, "Query duration '%f' is withing given thresholds",
398 query_res.query_duration);
269 } else { 399 } else {
270 char errmsg[1024]; 400 xasprintf(&sc_query.output, "Query duration '%f' violates the given thresholds",
271 regerror(err, &expect_re, errmsg, sizeof(errmsg)); 401 query_res.query_duration);
272 printf("ERROR - failed to execute regular expression: %s\n", errmsg);
273 status = STATE_CRITICAL;
274 } 402 }
275 } else { 403 } else {
276 status = get_status(query_val, config.dbi_thresholds); 404 /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error
405 * which should have been reported and handled (abort) before
406 * ... unless we expected a string to be returned */
407 assert((!isnan(query_res.result_number)) || (config.type == TYPE_STRING));
277 } 408 }
278 } else if (config.metric == METRIC_QUERY_TIME) {
279 status = get_status(query_time, config.dbi_thresholds);
280 } 409 }
410
411 mp_add_subcheck_to_check(&overall, sc_query);
281 } 412 }
282 413
283 if (verbose) { 414 if (verbose) {
@@ -285,63 +416,7 @@ int main(int argc, char **argv) {
285 } 416 }
286 dbi_conn_close(conn); 417 dbi_conn_close(conn);
287 418
288 /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error 419 mp_exit(overall);
289 * which should have been reported and handled (abort) before
290 * ... unless we expected a string to be returned */
291 assert((config.metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) ||
292 (config.type == TYPE_STRING));
293
294 assert((config.type != TYPE_STRING) || (config.expect || config.expect_re_str));
295
296 printf("%s - connection time: %fs", state_text(status), conn_time);
297 if (config.dbi_query) {
298 if (config.type == TYPE_STRING) {
299 assert(config.expect || config.expect_re_str);
300 printf(", '%s' returned '%s' in %fs", config.dbi_query,
301 query_val_str ? query_val_str : "<nothing>", query_time);
302 if (status != STATE_OK) {
303 if (config.expect) {
304 printf(" (expected '%s')", config.expect);
305 } else if (config.expect_re_str) {
306 printf(" (expected regex /%s/%s)", config.expect_re_str,
307 ((config.expect_re_cflags & REG_ICASE) ? "i" : ""));
308 }
309 }
310 } else if (isnan(query_val)) {
311 printf(", '%s' query execution time: %fs", config.dbi_query, query_time);
312 } else {
313 printf(", '%s' returned %f in %fs", config.dbi_query, query_val, query_time);
314 }
315 }
316
317 printf(
318 " | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time,
319 ((config.metric == METRIC_CONN_TIME) && config.warning_range) ? config.warning_range : "",
320 ((config.metric == METRIC_CONN_TIME) && config.critical_range) ? config.critical_range : "",
321 server_version,
322 ((config.metric == METRIC_SERVER_VERSION) && config.warning_range) ? config.warning_range
323 : "",
324 ((config.metric == METRIC_SERVER_VERSION) && config.critical_range) ? config.critical_range
325 : "");
326 if (config.dbi_query) {
327 if (!isnan(query_val)) { /* this is also true when -e is used */
328 printf(" query=%f;%s;%s;;", query_val,
329 ((config.metric == METRIC_QUERY_RESULT) && config.warning_range)
330 ? config.warning_range
331 : "",
332 ((config.metric == METRIC_QUERY_RESULT) && config.critical_range)
333 ? config.critical_range
334 : "");
335 }
336 printf(" querytime=%fs;%s;%s;0;", query_time,
337 ((config.metric == METRIC_QUERY_TIME) && config.warning_range) ? config.warning_range
338 : "",
339 ((config.metric == METRIC_QUERY_TIME) && config.critical_range)
340 ? config.critical_range
341 : "");
342 }
343 printf("\n");
344 return status;
345} 420}
346 421
347/* process command-line arguments */ 422/* process command-line arguments */
@@ -349,7 +424,6 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) {
349 424
350 int option = 0; 425 int option = 0;
351 static struct option longopts[] = {STD_LONG_OPTS, 426 static struct option longopts[] = {STD_LONG_OPTS,
352
353 {"expect", required_argument, 0, 'e'}, 427 {"expect", required_argument, 0, 'e'},
354 {"regex", required_argument, 0, 'r'}, 428 {"regex", required_argument, 0, 'r'},
355 {"regexi", required_argument, 0, 'R'}, 429 {"regexi", required_argument, 0, 'R'},
@@ -533,6 +607,10 @@ check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper config_wrap
533 usage("Options -r/-R require metric QUERY_RESULT"); 607 usage("Options -r/-R require metric QUERY_RESULT");
534 } 608 }
535 609
610 if (config_wrapper.config.type == TYPE_STRING) {
611 assert(config_wrapper.config.expect || config_wrapper.config.expect_re_str);
612 }
613
536 config_wrapper.errorcode = OK; 614 config_wrapper.errorcode = OK;
537 return config_wrapper; 615 return config_wrapper;
538} 616}
@@ -783,38 +861,110 @@ mp_state_enum get_query_result(dbi_conn conn, dbi_result res, const char **res_v
783 return STATE_OK; 861 return STATE_OK;
784} 862}
785 863
786mp_state_enum do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *res_time, 864static do_query_result do_query(dbi_conn conn, mp_dbi_metric metric, mp_dbi_type type,
787 mp_dbi_metric metric, mp_dbi_type type, char *np_dbi_query) { 865 char *query) {
788 dbi_result res; 866 assert(query);
789
790 struct timeval timeval_start;
791 struct timeval timeval_end;
792 mp_state_enum status = STATE_OK;
793
794 assert(np_dbi_query);
795 867
796 if (verbose) { 868 if (verbose) {
797 printf("Executing query '%s'\n", np_dbi_query); 869 printf("Executing query '%s'\n", query);
798 } 870 }
799 871
872 do_query_result result = {
873 .query_duration = 0,
874 .result_string = NULL,
875 .result_number = 0,
876 .error_code = 0,
877 .query_processing_status = STATE_UNKNOWN,
878 };
879
880 struct timeval timeval_start;
800 gettimeofday(&timeval_start, NULL); 881 gettimeofday(&timeval_start, NULL);
801 882
802 res = dbi_conn_query(conn, np_dbi_query); 883 dbi_result res = dbi_conn_query(conn, query);
803 if (!res) { 884 if (!res) {
804 np_dbi_print_error(conn, "CRITICAL - failed to execute query '%s'", np_dbi_query); 885 dbi_conn_error(conn, &result.error_string);
805 return STATE_CRITICAL; 886 result.error_code = 1;
887 return result;
806 } 888 }
807 889
808 status = get_query_result(conn, res, res_val_str, res_val, metric, type); 890 struct timeval timeval_end;
809
810 gettimeofday(&timeval_end, NULL); 891 gettimeofday(&timeval_end, NULL);
811 *res_time = timediff(timeval_start, timeval_end); 892 result.query_duration = timediff(timeval_start, timeval_end);
812 893
813 if (verbose) { 894 if (verbose) {
814 printf("Time elapsed: %f\n", *res_time); 895 printf("Query duration: %f\n", result.query_duration);
896 }
897
898 // Default state is OK, all error will be set explicitely
899 mp_state_enum query_processing_state = STATE_OK;
900 {
901
902 if (dbi_result_get_numrows(res) == DBI_ROW_ERROR) {
903 if (metric != METRIC_QUERY_RESULT) {
904 query_processing_state = STATE_OK;
905 } else {
906 dbi_conn_error(conn, &result.error_string);
907 query_processing_state = STATE_CRITICAL;
908 }
909 } else if (dbi_result_get_numrows(res) < 1) {
910 if (metric != METRIC_QUERY_RESULT) {
911 query_processing_state = STATE_OK;
912 } else {
913 result.error_string = "no rows returned";
914 // printf("WARNING - no rows returned\n");
915 query_processing_state = STATE_WARNING;
916 }
917 } else if (dbi_result_get_numfields(res) == DBI_FIELD_ERROR) {
918 if (metric != METRIC_QUERY_RESULT) {
919 query_processing_state = STATE_OK;
920 } else {
921 dbi_conn_error(conn, &result.error_string);
922 // np_dbi_print_error(conn, "CRITICAL - failed to fetch fields");
923 query_processing_state = STATE_CRITICAL;
924 }
925 } else if (dbi_result_get_numfields(res) < 1) {
926 if (metric != METRIC_QUERY_RESULT) {
927 query_processing_state = STATE_OK;
928 } else {
929 result.error_string = "no fields returned";
930 // printf("WARNING - no fields returned\n");
931 query_processing_state = STATE_WARNING;
932 }
933 } else if (dbi_result_first_row(res) != 1) {
934 if (metric != METRIC_QUERY_RESULT) {
935 query_processing_state = STATE_OK;
936 } else {
937 dbi_conn_error(conn, &result.error_string);
938 // np_dbi_print_error(conn, "CRITICAL - failed to fetch first row");
939 query_processing_state = STATE_CRITICAL;
940 }
941 } else {
942 unsigned short field_type = dbi_result_get_field_type_idx(res, 1);
943 if (field_type != DBI_TYPE_ERROR) {
944 if (type == TYPE_STRING) {
945 result.result_string =
946 strdup(get_field_str(conn, res, field_type, metric, type));
947 } else {
948 result.result_number = get_field(conn, res, &field_type, metric, type);
949 }
950 } else {
951 // Error when retrieving the field, that is OK if the Query result is not of
952 // interest
953 if (metric != METRIC_QUERY_RESULT) {
954 query_processing_state = STATE_OK;
955 } else {
956 dbi_conn_error(conn, &result.error_string);
957 // np_dbi_print_error(conn, "CRITICAL - failed to fetch data");
958 query_processing_state = STATE_CRITICAL;
959 }
960 }
961 }
815 } 962 }
963 dbi_result_free(res);
964
965 result.query_processing_status = query_processing_state;
816 966
817 return status; 967 return result;
818} 968}
819 969
820double timediff(struct timeval start, struct timeval end) { 970double timediff(struct timeval start, struct timeval end) {
diff --git a/plugins/t/check_dbi.t b/plugins/t/check_dbi.t
index c24b5a8c..75444de4 100644
--- a/plugins/t/check_dbi.t
+++ b/plugins/t/check_dbi.t
@@ -21,12 +21,12 @@ plan tests => $tests;
21my $missing_driver_output = "failed to open DBI driver 'sqlite3'"; 21my $missing_driver_output = "failed to open DBI driver 'sqlite3'";
22 22
23my $bad_driver_output = "/failed to open DBI driver 'nodriver'/"; 23my $bad_driver_output = "/failed to open DBI driver 'nodriver'/";
24my $conn_time_output = "/OK - connection time: [0-9\.]+s \|/"; 24my $conn_time_output = "/connection time: [0-9\.]+s \|/";
25my $missing_query_output = "/Must specify a query to execute/"; 25my $missing_query_output = "/Must specify a query to execute/";
26my $no_rows_output = "/WARNING - no rows returned/"; 26my $no_rows_output = "/no rows returned/";
27my $not_numeric_output = "/CRITICAL - result value is not a numeric:/"; 27my $not_numeric_output = "/result value is not a numeric:/";
28my $query_time_output = "/OK - connection time: [0-9\.]+s, 'SELECT 1' returned 1.000000 in [0-9\.]+s \|/"; 28my $query_time_output = "/connection time: [0-9\.]+s, 'SELECT 1' returned 1.000000 in [0-9\.]+s \|/";
29my $syntax_error_output = "/CRITICAL - failed to execute query 'GET ALL FROM test': 1: near \"GET\": syntax error/"; 29my $syntax_error_output = "/1: near \"GET\": syntax error/";
30 30
31my $result; 31my $result;
32 32