diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-11-05 14:17:37 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-05 14:17:37 +0100 |
| commit | 7240eae6ef5b66f26967ab6e236ae3ebe7448efc (patch) | |
| tree | 9c291501740090ac3ca1dd7c0a7047cbefb0aa3b /plugins/check_pgsql.c | |
| parent | ad7acf4618f1ac8a49277a482fb4ca391a26f584 (diff) | |
| parent | 36ac312e07f6b0ff214b21783f42131b90aa553f (diff) | |
| download | monitoring-plugins-7240eae6ef5b66f26967ab6e236ae3ebe7448efc.tar.gz | |
Modern output/check pgsql
Diffstat (limited to 'plugins/check_pgsql.c')
| -rw-r--r-- | plugins/check_pgsql.c | 292 |
1 files changed, 203 insertions, 89 deletions
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c index 793a686f..0ce75e0a 100644 --- a/plugins/check_pgsql.c +++ b/plugins/check_pgsql.c | |||
| @@ -28,27 +28,29 @@ | |||
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | #include "output.h" | ||
| 32 | #include "perfdata.h" | ||
| 31 | #include "states.h" | 33 | #include "states.h" |
| 32 | const char *progname = "check_pgsql"; | ||
| 33 | const char *copyright = "1999-2024"; | ||
| 34 | const char *email = "devel@monitoring-plugins.org"; | ||
| 35 | |||
| 36 | #include "common.h" | 34 | #include "common.h" |
| 37 | #include "utils.h" | 35 | #include "utils.h" |
| 38 | #include "utils_cmd.h" | 36 | #include "utils_cmd.h" |
| 39 | #include "check_pgsql.d/config.h" | 37 | #include "check_pgsql.d/config.h" |
| 40 | #include "thresholds.h" | 38 | #include "thresholds.h" |
| 41 | |||
| 42 | #include "netutils.h" | 39 | #include "netutils.h" |
| 43 | #include <libpq-fe.h> | 40 | #include <libpq-fe.h> |
| 44 | #include <pg_config_manual.h> | 41 | #include <pg_config_manual.h> |
| 45 | 42 | ||
| 43 | const char *progname = "check_pgsql"; | ||
| 44 | const char *copyright = "1999-2024"; | ||
| 45 | const char *email = "devel@monitoring-plugins.org"; | ||
| 46 | |||
| 46 | #define DEFAULT_HOST "127.0.0.1" | 47 | #define DEFAULT_HOST "127.0.0.1" |
| 47 | 48 | ||
| 48 | /* return the PSQL server version as a 3-tuple */ | 49 | /* return the PSQL server version as a 3-tuple */ |
| 49 | #define PSQL_SERVER_VERSION3(server_version) \ | 50 | #define PSQL_SERVER_VERSION3(server_version) \ |
| 50 | (server_version) / 10000, (server_version) / 100 - (int)((server_version) / 10000) * 100, \ | 51 | ((server_version) / 10000), \ |
| 51 | (server_version) - (int)((server_version) / 100) * 100 | 52 | (((server_version) / 100) - (int)(((server_version) / 10000) * 100)), \ |
| 53 | (server_version) - (int)(((server_version) / 100) * 100) | ||
| 52 | /* return true if the given host is a UNIX domain socket */ | 54 | /* return true if the given host is a UNIX domain socket */ |
| 53 | #define PSQL_IS_UNIX_DOMAIN_SOCKET(host) ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host))) | 55 | #define PSQL_IS_UNIX_DOMAIN_SOCKET(host) ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host))) |
| 54 | /* return a 3-tuple identifying a host/port independent of the socket type */ | 56 | /* return a 3-tuple identifying a host/port independent of the socket type */ |
| @@ -64,15 +66,25 @@ static check_pgsql_config_wrapper process_arguments(int /*argc*/, char ** /*argv | |||
| 64 | 66 | ||
| 65 | static void print_help(void); | 67 | static void print_help(void); |
| 66 | static bool is_pg_logname(char * /*username*/); | 68 | static bool is_pg_logname(char * /*username*/); |
| 67 | static mp_state_enum do_query(PGconn * /*conn*/, char * /*query*/, const char /*pgqueryname*/[], | 69 | |
| 68 | thresholds * /*qthresholds*/, char * /*query_warning*/, | 70 | typedef enum { |
| 69 | char * /*query_critical*/); | 71 | QUERY_OK, |
| 72 | ERROR_WITH_QUERY, // critical | ||
| 73 | NO_ROWS_RETURNED, // warning | ||
| 74 | NO_COLUMNS_RETURNED, // warning | ||
| 75 | NO_DATA_RETURNED, // critica/ | ||
| 76 | RESULT_IS_NOT_NUMERIC // critical | ||
| 77 | } do_query_errorcode; | ||
| 78 | |||
| 79 | typedef struct { | ||
| 80 | do_query_errorcode error_code; | ||
| 81 | double numerical_result; | ||
| 82 | } do_query_wrapper; | ||
| 83 | static do_query_wrapper do_query(PGconn * /*conn*/, char * /*query*/); | ||
| 70 | void print_usage(void); | 84 | void print_usage(void); |
| 71 | 85 | ||
| 72 | static int verbose = 0; | 86 | static int verbose = 0; |
| 73 | 87 | ||
| 74 | #define OPTID_QUERYNAME -1000 | ||
| 75 | |||
| 76 | /****************************************************************************** | 88 | /****************************************************************************** |
| 77 | 89 | ||
| 78 | The (pseudo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ | 90 | The (pseudo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ |
| @@ -138,8 +150,8 @@ int main(int argc, char **argv) { | |||
| 138 | 150 | ||
| 139 | const check_pgsql_config config = tmp_config.config; | 151 | const check_pgsql_config config = tmp_config.config; |
| 140 | 152 | ||
| 141 | if (verbose > 2) { | 153 | if (config.output_format_is_set) { |
| 142 | printf("Arguments initialized\n"); | 154 | mp_set_format(config.output_format); |
| 143 | } | 155 | } |
| 144 | 156 | ||
| 145 | /* Set signal handling and alarm */ | 157 | /* Set signal handling and alarm */ |
| @@ -199,21 +211,41 @@ int main(int argc, char **argv) { | |||
| 199 | if (verbose) { | 211 | if (verbose) { |
| 200 | printf("Verifying connection\n"); | 212 | printf("Verifying connection\n"); |
| 201 | } | 213 | } |
| 214 | |||
| 215 | mp_check overall = mp_check_init(); | ||
| 216 | |||
| 217 | mp_subcheck sc_connection = mp_subcheck_init(); | ||
| 218 | |||
| 202 | if (PQstatus(conn) == CONNECTION_BAD) { | 219 | if (PQstatus(conn) == CONNECTION_BAD) { |
| 203 | printf(_("CRITICAL - no connection to '%s' (%s).\n"), config.dbName, PQerrorMessage(conn)); | 220 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_CRITICAL); |
| 221 | xasprintf(&sc_connection.output, "no connection to '%s' (%s)", config.dbName, | ||
| 222 | PQerrorMessage(conn)); | ||
| 204 | PQfinish(conn); | 223 | PQfinish(conn); |
| 205 | return STATE_CRITICAL; | 224 | mp_add_subcheck_to_check(&overall, sc_connection); |
| 206 | } | 225 | mp_exit(overall); |
| 207 | |||
| 208 | mp_state_enum status = STATE_UNKNOWN; | ||
| 209 | if (elapsed_time > config.tcrit) { | ||
| 210 | status = STATE_CRITICAL; | ||
| 211 | } else if (elapsed_time > config.twarn) { | ||
| 212 | status = STATE_WARNING; | ||
| 213 | } else { | 226 | } else { |
| 214 | status = STATE_OK; | 227 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_OK); |
| 228 | xasprintf(&sc_connection.output, "connected to '%s'", config.dbName); | ||
| 229 | mp_add_subcheck_to_check(&overall, sc_connection); | ||
| 215 | } | 230 | } |
| 216 | 231 | ||
| 232 | mp_subcheck sc_connection_time = mp_subcheck_init(); | ||
| 233 | sc_connection_time = mp_set_subcheck_default_state(sc_connection_time, STATE_UNKNOWN); | ||
| 234 | |||
| 235 | xasprintf(&sc_connection_time.output, "connection time: %.10g", elapsed_time); | ||
| 236 | |||
| 237 | mp_perfdata pd_connection_time = perfdata_init(); | ||
| 238 | pd_connection_time.label = "time"; | ||
| 239 | pd_connection_time.uom = "s"; | ||
| 240 | pd_connection_time = mp_set_pd_value(pd_connection_time, elapsed_time); | ||
| 241 | pd_connection_time = mp_pd_set_thresholds(pd_connection_time, config.time_thresholds); | ||
| 242 | |||
| 243 | mp_add_perfdata_to_subcheck(&sc_connection_time, pd_connection_time); | ||
| 244 | sc_connection_time = | ||
| 245 | mp_set_subcheck_state(sc_connection_time, mp_get_pd_status(pd_connection_time)); | ||
| 246 | |||
| 247 | mp_add_subcheck_to_check(&overall, sc_connection_time); | ||
| 248 | |||
| 217 | if (verbose) { | 249 | if (verbose) { |
| 218 | char *server_host = PQhost(conn); | 250 | char *server_host = PQhost(conn); |
| 219 | int server_version = PQserverVersion(conn); | 251 | int server_version = PQserverVersion(conn); |
| @@ -225,25 +257,87 @@ int main(int argc, char **argv) { | |||
| 225 | PSQL_SERVER_VERSION3(server_version), PQprotocolVersion(conn), PQbackendPID(conn)); | 257 | PSQL_SERVER_VERSION3(server_version), PQprotocolVersion(conn), PQbackendPID(conn)); |
| 226 | } | 258 | } |
| 227 | 259 | ||
| 228 | printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), config.dbName, elapsed_time, | ||
| 229 | fperfdata("time", elapsed_time, "s", (config.twarn > 0.0), config.twarn, | ||
| 230 | (config.tcrit > 0.0), config.tcrit, true, 0, false, 0)); | ||
| 231 | |||
| 232 | mp_state_enum query_status = STATE_UNKNOWN; | ||
| 233 | if (config.pgquery) { | 260 | if (config.pgquery) { |
| 234 | query_status = do_query(conn, config.pgquery, config.pgqueryname, config.qthresholds, | 261 | mp_subcheck sc_query = mp_subcheck_init(); |
| 235 | config.query_warning, config.query_critical); | 262 | sc_query = mp_set_subcheck_default_state(sc_query, STATE_UNKNOWN); |
| 263 | if (config.pgqueryname) { | ||
| 264 | xasprintf(&sc_query.output, "query '%s'", config.pgqueryname); | ||
| 265 | } else { | ||
| 266 | xasprintf(&sc_query.output, "query '%s'", config.pgquery); | ||
| 267 | } | ||
| 268 | |||
| 269 | do_query_wrapper query_result = do_query(conn, config.pgquery); | ||
| 270 | |||
| 271 | switch (query_result.error_code) { | ||
| 272 | case QUERY_OK: { | ||
| 273 | // Query was successful and there is a numerical result | ||
| 274 | sc_query = mp_set_subcheck_state(sc_query, STATE_OK); | ||
| 275 | xasprintf(&sc_query.output, "%s succeeded", sc_query.output); | ||
| 276 | |||
| 277 | mp_perfdata pd_query = perfdata_init(); | ||
| 278 | pd_query = mp_set_pd_value(pd_query, query_result.numerical_result); | ||
| 279 | pd_query = mp_pd_set_thresholds(pd_query, config.qthresholds); | ||
| 280 | pd_query.label = "query"; | ||
| 281 | |||
| 282 | mp_subcheck sc_query_compare = mp_subcheck_init(); | ||
| 283 | mp_state_enum query_compare_state = mp_get_pd_status(pd_query); | ||
| 284 | |||
| 285 | sc_query_compare = mp_set_subcheck_state(sc_query_compare, query_compare_state); | ||
| 286 | mp_add_perfdata_to_subcheck(&sc_query_compare, pd_query); | ||
| 287 | |||
| 288 | if (query_compare_state == STATE_OK) { | ||
| 289 | xasprintf(&sc_query_compare.output, "query result '%f' is within thresholds", | ||
| 290 | query_result.numerical_result); | ||
| 291 | } else { | ||
| 292 | xasprintf(&sc_query_compare.output, "query result '%f' is violating thresholds", | ||
| 293 | query_result.numerical_result); | ||
| 294 | } | ||
| 295 | mp_add_subcheck_to_check(&overall, sc_query_compare); | ||
| 296 | |||
| 297 | } break; | ||
| 298 | case ERROR_WITH_QUERY: | ||
| 299 | xasprintf(&sc_query.output, "%s - Error with query: %s", sc_query.output, | ||
| 300 | PQerrorMessage(conn)); | ||
| 301 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 302 | break; | ||
| 303 | case NO_ROWS_RETURNED: | ||
| 304 | xasprintf(&sc_query.output, "%s - no rows were returned by the query", sc_query.output); | ||
| 305 | sc_query = mp_set_subcheck_state(sc_query, STATE_WARNING); | ||
| 306 | break; | ||
| 307 | case NO_COLUMNS_RETURNED: | ||
| 308 | xasprintf(&sc_query.output, "%s - no columns were returned by the query", | ||
| 309 | sc_query.output); | ||
| 310 | sc_query = mp_set_subcheck_state(sc_query, STATE_WARNING); | ||
| 311 | break; | ||
| 312 | case NO_DATA_RETURNED: | ||
| 313 | xasprintf(&sc_query.output, "%s - no data was returned by the query", sc_query.output); | ||
| 314 | sc_query = mp_set_subcheck_state(sc_query, STATE_WARNING); | ||
| 315 | break; | ||
| 316 | case RESULT_IS_NOT_NUMERIC: | ||
| 317 | xasprintf(&sc_query.output, "%s - result of the query is not numeric", sc_query.output); | ||
| 318 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 319 | break; | ||
| 320 | }; | ||
| 321 | |||
| 322 | mp_add_subcheck_to_check(&overall, sc_query); | ||
| 236 | } | 323 | } |
| 237 | 324 | ||
| 238 | if (verbose) { | 325 | if (verbose) { |
| 239 | printf("Closing connection\n"); | 326 | printf("Closing connection\n"); |
| 240 | } | 327 | } |
| 241 | PQfinish(conn); | 328 | PQfinish(conn); |
| 242 | return (config.pgquery && query_status > status) ? query_status : status; | 329 | |
| 330 | mp_exit(overall); | ||
| 243 | } | 331 | } |
| 244 | 332 | ||
| 245 | /* process command-line arguments */ | 333 | /* process command-line arguments */ |
| 246 | check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | 334 | static check_pgsql_config_wrapper process_arguments(int argc, char **argv) { |
| 335 | |||
| 336 | enum { | ||
| 337 | OPTID_QUERYNAME = CHAR_MAX + 1, | ||
| 338 | output_format_index, | ||
| 339 | }; | ||
| 340 | |||
| 247 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, | 341 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, |
| 248 | {"version", no_argument, 0, 'V'}, | 342 | {"version", no_argument, 0, 'V'}, |
| 249 | {"timeout", required_argument, 0, 't'}, | 343 | {"timeout", required_argument, 0, 't'}, |
| @@ -261,6 +355,7 @@ check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 261 | {"query_critical", required_argument, 0, 'C'}, | 355 | {"query_critical", required_argument, 0, 'C'}, |
| 262 | {"query_warning", required_argument, 0, 'W'}, | 356 | {"query_warning", required_argument, 0, 'W'}, |
| 263 | {"verbose", no_argument, 0, 'v'}, | 357 | {"verbose", no_argument, 0, 'v'}, |
| 358 | {"output-format", required_argument, 0, output_format_index}, | ||
| 264 | {0, 0, 0, 0}}; | 359 | {0, 0, 0, 0}}; |
| 265 | 360 | ||
| 266 | check_pgsql_config_wrapper result = { | 361 | check_pgsql_config_wrapper result = { |
| @@ -278,6 +373,17 @@ check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 278 | } | 373 | } |
| 279 | 374 | ||
| 280 | switch (option_char) { | 375 | switch (option_char) { |
| 376 | case output_format_index: { | ||
| 377 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 378 | if (!parser.parsing_success) { | ||
| 379 | printf("Invalid output format: %s\n", optarg); | ||
| 380 | exit(STATE_UNKNOWN); | ||
| 381 | } | ||
| 382 | |||
| 383 | result.config.output_format_is_set = true; | ||
| 384 | result.config.output_format = parser.output_format; | ||
| 385 | break; | ||
| 386 | } | ||
| 281 | case '?': /* usage */ | 387 | case '?': /* usage */ |
| 282 | usage5(); | 388 | usage5(); |
| 283 | case 'h': /* help */ | 389 | case 'h': /* help */ |
| @@ -293,26 +399,40 @@ check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 293 | timeout_interval = atoi(optarg); | 399 | timeout_interval = atoi(optarg); |
| 294 | } | 400 | } |
| 295 | break; | 401 | break; |
| 296 | case 'c': /* critical time threshold */ | 402 | case 'c': /* critical time threshold */ { |
| 297 | if (!is_nonnegative(optarg)) { | 403 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 298 | usage2(_("Critical threshold must be a positive integer"), optarg); | 404 | if (tmp.error != MP_PARSING_SUCCES) { |
| 299 | } else { | 405 | die(STATE_UNKNOWN, "failed to parse critical time threshold"); |
| 300 | result.config.tcrit = strtod(optarg, NULL); | ||
| 301 | } | 406 | } |
| 302 | break; | 407 | result.config.time_thresholds = |
| 303 | case 'w': /* warning time threshold */ | 408 | mp_thresholds_set_crit(result.config.time_thresholds, tmp.range); |
| 304 | if (!is_nonnegative(optarg)) { | 409 | } break; |
| 305 | usage2(_("Warning threshold must be a positive integer"), optarg); | 410 | case 'w': /* warning time threshold */ { |
| 306 | } else { | 411 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 307 | result.config.twarn = strtod(optarg, NULL); | 412 | if (tmp.error != MP_PARSING_SUCCES) { |
| 413 | die(STATE_UNKNOWN, "failed to parse warning time threshold"); | ||
| 308 | } | 414 | } |
| 309 | break; | 415 | result.config.time_thresholds = |
| 310 | case 'C': /* critical query threshold */ | 416 | mp_thresholds_set_warn(result.config.time_thresholds, tmp.range); |
| 311 | result.config.query_critical = optarg; | 417 | } break; |
| 312 | break; | 418 | case 'C': /* critical query threshold */ { |
| 313 | case 'W': /* warning query threshold */ | 419 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 314 | result.config.query_warning = optarg; | 420 | if (tmp.error != MP_PARSING_SUCCES) { |
| 315 | break; | 421 | die(STATE_UNKNOWN, "failed to parse critical query threshold"); |
| 422 | } | ||
| 423 | |||
| 424 | result.config.qthresholds = | ||
| 425 | mp_thresholds_set_crit(result.config.qthresholds, tmp.range); | ||
| 426 | |||
| 427 | } break; | ||
| 428 | case 'W': /* warning query threshold */ { | ||
| 429 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 430 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 431 | die(STATE_UNKNOWN, "failed to parse warning query threshold"); | ||
| 432 | } | ||
| 433 | result.config.qthresholds = | ||
| 434 | mp_thresholds_set_warn(result.config.qthresholds, tmp.range); | ||
| 435 | } break; | ||
| 316 | case 'H': /* host */ | 436 | case 'H': /* host */ |
| 317 | if ((*optarg != '/') && (!is_host(optarg))) { | 437 | if ((*optarg != '/') && (!is_host(optarg))) { |
| 318 | usage2(_("Invalid hostname/address"), optarg); | 438 | usage2(_("Invalid hostname/address"), optarg); |
| @@ -363,9 +483,6 @@ check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 363 | } | 483 | } |
| 364 | } | 484 | } |
| 365 | 485 | ||
| 366 | set_thresholds(&result.config.qthresholds, result.config.query_warning, | ||
| 367 | result.config.query_critical); | ||
| 368 | |||
| 369 | return result; | 486 | return result; |
| 370 | } | 487 | } |
| 371 | 488 | ||
| @@ -393,7 +510,7 @@ should be added.</para> | |||
| 393 | -@@ | 510 | -@@ |
| 394 | ******************************************************************************/ | 511 | ******************************************************************************/ |
| 395 | 512 | ||
| 396 | bool is_pg_logname(char *username) { | 513 | static bool is_pg_logname(char *username) { |
| 397 | if (strlen(username) > NAMEDATALEN - 1) { | 514 | if (strlen(username) > NAMEDATALEN - 1) { |
| 398 | return (false); | 515 | return (false); |
| 399 | } | 516 | } |
| @@ -447,12 +564,13 @@ void print_help(void) { | |||
| 447 | printf(" %s\n", "--queryname=STRING"); | 564 | printf(" %s\n", "--queryname=STRING"); |
| 448 | printf(" %s\n", _("A name for the query, this string is used instead of the query")); | 565 | printf(" %s\n", _("A name for the query, this string is used instead of the query")); |
| 449 | printf(" %s\n", _("in the long output of the plugin")); | 566 | printf(" %s\n", _("in the long output of the plugin")); |
| 450 | printf(" %s\n", "-W, --query-warning=RANGE"); | 567 | printf(" %s\n", "-W, --query_warning=RANGE"); |
| 451 | printf(" %s\n", _("SQL query value to result in warning status (double)")); | 568 | printf(" %s\n", _("SQL query value to result in warning status (double)")); |
| 452 | printf(" %s\n", "-C, --query-critical=RANGE"); | 569 | printf(" %s\n", "-C, --query_critical=RANGE"); |
| 453 | printf(" %s\n", _("SQL query value to result in critical status (double)")); | 570 | printf(" %s\n", _("SQL query value to result in critical status (double)")); |
| 454 | 571 | ||
| 455 | printf(UT_VERBOSE); | 572 | printf(UT_VERBOSE); |
| 573 | printf(UT_OUTPUT_FORMAT); | ||
| 456 | 574 | ||
| 457 | printf("\n"); | 575 | printf("\n"); |
| 458 | printf(" %s\n", _("All parameters are optional.")); | 576 | printf(" %s\n", _("All parameters are optional.")); |
| @@ -509,33 +627,44 @@ void print_usage(void) { | |||
| 509 | "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n"); | 627 | "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n"); |
| 510 | } | 628 | } |
| 511 | 629 | ||
| 512 | mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thresholds *qthresholds, | 630 | static do_query_wrapper do_query(PGconn *conn, char *query) { |
| 513 | char *query_warning, char *query_critical) { | ||
| 514 | if (verbose) { | 631 | if (verbose) { |
| 515 | printf("Executing SQL query \"%s\".\n", query); | 632 | printf("Executing SQL query \"%s\".\n", query); |
| 516 | } | 633 | } |
| 517 | PGresult *res = PQexec(conn, query); | 634 | PGresult *res = PQexec(conn, query); |
| 518 | 635 | ||
| 636 | do_query_wrapper result = { | ||
| 637 | .error_code = QUERY_OK, | ||
| 638 | }; | ||
| 639 | |||
| 519 | if (PGRES_TUPLES_OK != PQresultStatus(res)) { | 640 | if (PGRES_TUPLES_OK != PQresultStatus(res)) { |
| 520 | printf(_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"), | 641 | // TODO |
| 521 | PQerrorMessage(conn)); | 642 | // printf(_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"), |
| 522 | return STATE_CRITICAL; | 643 | // PQerrorMessage(conn)); |
| 644 | result.error_code = ERROR_WITH_QUERY; | ||
| 645 | return result; | ||
| 523 | } | 646 | } |
| 524 | 647 | ||
| 525 | if (PQntuples(res) < 1) { | 648 | if (PQntuples(res) < 1) { |
| 526 | printf("QUERY %s - %s.\n", _("WARNING"), _("No rows returned")); | 649 | // TODO |
| 527 | return STATE_WARNING; | 650 | // printf("QUERY %s - %s.\n", _("WARNING"), _("No rows returned")); |
| 651 | result.error_code = NO_ROWS_RETURNED; | ||
| 652 | return result; | ||
| 528 | } | 653 | } |
| 529 | 654 | ||
| 530 | if (PQnfields(res) < 1) { | 655 | if (PQnfields(res) < 1) { |
| 531 | printf("QUERY %s - %s.\n", _("WARNING"), _("No columns returned")); | 656 | // TODO |
| 532 | return STATE_WARNING; | 657 | // printf("QUERY %s - %s.\n", _("WARNING"), _("No columns returned")); |
| 658 | result.error_code = NO_COLUMNS_RETURNED; | ||
| 659 | return result; | ||
| 533 | } | 660 | } |
| 534 | 661 | ||
| 535 | char *val_str = PQgetvalue(res, 0, 0); | 662 | char *val_str = PQgetvalue(res, 0, 0); |
| 536 | if (!val_str) { | 663 | if (!val_str) { |
| 537 | printf("QUERY %s - %s.\n", _("CRITICAL"), _("No data returned")); | 664 | // TODO |
| 538 | return STATE_CRITICAL; | 665 | // printf("QUERY %s - %s.\n", _("CRITICAL"), _("No data returned")); |
| 666 | result.error_code = NO_DATA_RETURNED; | ||
| 667 | return result; | ||
| 539 | } | 668 | } |
| 540 | 669 | ||
| 541 | char *endptr = NULL; | 670 | char *endptr = NULL; |
| @@ -545,8 +674,10 @@ mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thre | |||
| 545 | } | 674 | } |
| 546 | 675 | ||
| 547 | if (endptr == val_str) { | 676 | if (endptr == val_str) { |
| 548 | printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str); | 677 | // TODO |
| 549 | return STATE_CRITICAL; | 678 | // printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str); |
| 679 | result.error_code = RESULT_IS_NOT_NUMERIC; | ||
| 680 | return result; | ||
| 550 | } | 681 | } |
| 551 | 682 | ||
| 552 | if ((endptr != NULL) && (*endptr != '\0')) { | 683 | if ((endptr != NULL) && (*endptr != '\0')) { |
| @@ -555,24 +686,7 @@ mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thre | |||
| 555 | } | 686 | } |
| 556 | } | 687 | } |
| 557 | 688 | ||
| 558 | mp_state_enum my_status = get_status(value, qthresholds); | 689 | result.numerical_result = value; |
| 559 | printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK") | ||
| 560 | : (my_status == STATE_WARNING) ? _("WARNING") | ||
| 561 | : (my_status == STATE_CRITICAL) ? _("CRITICAL") | ||
| 562 | : _("UNKNOWN")); | ||
| 563 | if (pgqueryname) { | ||
| 564 | printf(_("%s returned %f"), pgqueryname, value); | ||
| 565 | } else { | ||
| 566 | printf(_("'%s' returned %f"), query, value); | ||
| 567 | } | ||
| 568 | 690 | ||
| 569 | printf("|query=%f;%s;%s;;\n", value, query_warning ? query_warning : "", | 691 | return result; |
| 570 | query_critical ? query_critical : ""); | ||
| 571 | if (PQnfields(res) > 1) { | ||
| 572 | char *extra_info = PQgetvalue(res, 0, 1); | ||
| 573 | if (extra_info != NULL) { | ||
| 574 | printf("Extra Info: %s\n", extra_info); | ||
| 575 | } | ||
| 576 | } | ||
| 577 | return my_status; | ||
| 578 | } | 692 | } |
