summaryrefslogtreecommitdiffstats
path: root/plugins/check_pgsql.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_pgsql.c')
-rw-r--r--plugins/check_pgsql.c275
1 files changed, 154 insertions, 121 deletions
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 6613634d..793a686f 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -28,6 +28,7 @@
28 * 28 *
29 *****************************************************************************/ 29 *****************************************************************************/
30 30
31#include "states.h"
31const char *progname = "check_pgsql"; 32const char *progname = "check_pgsql";
32const char *copyright = "1999-2024"; 33const char *copyright = "1999-2024";
33const char *email = "devel@monitoring-plugins.org"; 34const char *email = "devel@monitoring-plugins.org";
@@ -35,51 +36,39 @@ const char *email = "devel@monitoring-plugins.org";
35#include "common.h" 36#include "common.h"
36#include "utils.h" 37#include "utils.h"
37#include "utils_cmd.h" 38#include "utils_cmd.h"
39#include "check_pgsql.d/config.h"
40#include "thresholds.h"
38 41
39#include "netutils.h" 42#include "netutils.h"
40#include <libpq-fe.h> 43#include <libpq-fe.h>
41#include <pg_config_manual.h> 44#include <pg_config_manual.h>
42 45
43#define DEFAULT_DB "template1"
44#define DEFAULT_HOST "127.0.0.1" 46#define DEFAULT_HOST "127.0.0.1"
45 47
46/* return the PSQL server version as a 3-tuple */ 48/* return the PSQL server version as a 3-tuple */
47#define PSQL_SERVER_VERSION3(server_version) \ 49#define PSQL_SERVER_VERSION3(server_version) \
48 (server_version) / 10000, (server_version) / 100 - (int)((server_version) / 10000) * 100, \ 50 (server_version) / 10000, (server_version) / 100 - (int)((server_version) / 10000) * 100, \
49 (server_version) - (int)((server_version) / 100) * 100 51 (server_version) - (int)((server_version) / 100) * 100
50/* return true if the given host is a UNIX domain socket */ 52/* return true if the given host is a UNIX domain socket */
51#define PSQL_IS_UNIX_DOMAIN_SOCKET(host) ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host))) 53#define PSQL_IS_UNIX_DOMAIN_SOCKET(host) ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host)))
52/* return a 3-tuple identifying a host/port independent of the socket type */ 54/* return a 3-tuple identifying a host/port independent of the socket type */
53#define PSQL_SOCKET3(host, port) \ 55#define PSQL_SOCKET3(host, port) \
54 ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port 56 ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, \
57 PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port
55 58
56enum { 59typedef struct {
57 DEFAULT_PORT = 5432, 60 int errorcode;
58 DEFAULT_WARN = 2, 61 check_pgsql_config config;
59 DEFAULT_CRIT = 8 62} check_pgsql_config_wrapper;
60}; 63static check_pgsql_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
61 64
62static int process_arguments(int /*argc*/, char ** /*argv*/);
63static void print_help(void); 65static void print_help(void);
64static bool is_pg_logname(char * /*username*/); 66static bool is_pg_logname(char * /*username*/);
65static int do_query(PGconn * /*conn*/, char * /*query*/); 67static mp_state_enum do_query(PGconn * /*conn*/, char * /*query*/, const char /*pgqueryname*/[],
68 thresholds * /*qthresholds*/, char * /*query_warning*/,
69 char * /*query_critical*/);
66void print_usage(void); 70void print_usage(void);
67 71
68static char *pghost = NULL; /* host name of the backend server */
69static char *pgport = NULL; /* port of the backend server */
70static char *pgoptions = NULL;
71static char *pgtty = NULL;
72static char dbName[NAMEDATALEN] = DEFAULT_DB;
73static char *pguser = NULL;
74static char *pgpasswd = NULL;
75static char *pgparams = NULL;
76static double twarn = (double)DEFAULT_WARN;
77static double tcrit = (double)DEFAULT_CRIT;
78static char *pgquery = NULL;
79static char *pgqueryname = NULL;
80static char *query_warning = NULL;
81static char *query_critical = NULL;
82static thresholds *qthresholds = NULL;
83static int verbose = 0; 72static int verbose = 0;
84 73
85#define OPTID_QUERYNAME -1000 74#define OPTID_QUERYNAME -1000
@@ -139,21 +128,19 @@ int main(int argc, char **argv) {
139 bindtextdomain(PACKAGE, LOCALEDIR); 128 bindtextdomain(PACKAGE, LOCALEDIR);
140 textdomain(PACKAGE); 129 textdomain(PACKAGE);
141 130
142 /* begin, by setting the parameters for a backend connection if the
143 * parameters are null, then the system will try to use reasonable
144 * defaults by looking up environment variables or, failing that,
145 * using hardwired constants */
146
147 pgoptions = NULL; /* special options to start up the backend server */
148 pgtty = NULL; /* debugging tty for the backend server */
149
150 /* Parse extra opts if any */ 131 /* Parse extra opts if any */
151 argv = np_extra_opts(&argc, argv, progname); 132 argv = np_extra_opts(&argc, argv, progname);
152 133
153 if (process_arguments(argc, argv) == ERROR) 134 check_pgsql_config_wrapper tmp_config = process_arguments(argc, argv);
135 if (tmp_config.errorcode == ERROR) {
154 usage4(_("Could not parse arguments")); 136 usage4(_("Could not parse arguments"));
155 if (verbose > 2) 137 }
138
139 const check_pgsql_config config = tmp_config.config;
140
141 if (verbose > 2) {
156 printf("Arguments initialized\n"); 142 printf("Arguments initialized\n");
143 }
157 144
158 /* Set signal handling and alarm */ 145 /* Set signal handling and alarm */
159 if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { 146 if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
@@ -162,25 +149,33 @@ int main(int argc, char **argv) {
162 alarm(timeout_interval); 149 alarm(timeout_interval);
163 150
164 char *conninfo = NULL; 151 char *conninfo = NULL;
165 if (pgparams) 152 if (config.pgparams) {
166 asprintf(&conninfo, "%s ", pgparams); 153 asprintf(&conninfo, "%s ", config.pgparams);
167 154 }
168 asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName); 155
169 if (pghost) 156 asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", config.dbName);
170 asprintf(&conninfo, "%s host = '%s'", conninfo, pghost); 157 if (config.pghost) {
171 if (pgport) 158 asprintf(&conninfo, "%s host = '%s'", conninfo, config.pghost);
172 asprintf(&conninfo, "%s port = '%s'", conninfo, pgport); 159 }
173 if (pgoptions) 160 if (config.pgport) {
174 asprintf(&conninfo, "%s options = '%s'", conninfo, pgoptions); 161 asprintf(&conninfo, "%s port = '%s'", conninfo, config.pgport);
162 }
163 if (config.pgoptions) {
164 asprintf(&conninfo, "%s options = '%s'", conninfo, config.pgoptions);
165 }
175 /* if (pgtty) -- ignored by PQconnectdb */ 166 /* if (pgtty) -- ignored by PQconnectdb */
176 if (pguser) 167 if (config.pguser) {
177 asprintf(&conninfo, "%s user = '%s'", conninfo, pguser); 168 asprintf(&conninfo, "%s user = '%s'", conninfo, config.pguser);
169 }
178 170
179 if (verbose) /* do not include password (see right below) in output */ 171 if (verbose) { /* do not include password (see right below) in output */
180 printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, pgpasswd ? " password = <hidden>" : ""); 172 printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo,
173 config.pgpasswd ? " password = <hidden>" : "");
174 }
181 175
182 if (pgpasswd) 176 if (config.pgpasswd) {
183 asprintf(&conninfo, "%s password = '%s'", conninfo, pgpasswd); 177 asprintf(&conninfo, "%s password = '%s'", conninfo, config.pgpasswd);
178 }
184 179
185 /* make a connection to the database */ 180 /* make a connection to the database */
186 struct timeval start_timeval; 181 struct timeval start_timeval;
@@ -193,25 +188,27 @@ int main(int argc, char **argv) {
193 --end_timeval.tv_sec; 188 --end_timeval.tv_sec;
194 end_timeval.tv_usec += 1000000; 189 end_timeval.tv_usec += 1000000;
195 } 190 }
196 double elapsed_time = 191 double elapsed_time = (double)(end_timeval.tv_sec - start_timeval.tv_sec) +
197 (double)(end_timeval.tv_sec - start_timeval.tv_sec) + (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0; 192 ((double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0);
198 193
199 if (verbose) 194 if (verbose) {
200 printf("Time elapsed: %f\n", elapsed_time); 195 printf("Time elapsed: %f\n", elapsed_time);
196 }
201 197
202 /* check to see that the backend connection was successfully made */ 198 /* check to see that the backend connection was successfully made */
203 if (verbose) 199 if (verbose) {
204 printf("Verifying connection\n"); 200 printf("Verifying connection\n");
201 }
205 if (PQstatus(conn) == CONNECTION_BAD) { 202 if (PQstatus(conn) == CONNECTION_BAD) {
206 printf(_("CRITICAL - no connection to '%s' (%s).\n"), dbName, PQerrorMessage(conn)); 203 printf(_("CRITICAL - no connection to '%s' (%s).\n"), config.dbName, PQerrorMessage(conn));
207 PQfinish(conn); 204 PQfinish(conn);
208 return STATE_CRITICAL; 205 return STATE_CRITICAL;
209 } 206 }
210 207
211 int status = STATE_UNKNOWN; 208 mp_state_enum status = STATE_UNKNOWN;
212 if (elapsed_time > tcrit) { 209 if (elapsed_time > config.tcrit) {
213 status = STATE_CRITICAL; 210 status = STATE_CRITICAL;
214 } else if (elapsed_time > twarn) { 211 } else if (elapsed_time > config.twarn) {
215 status = STATE_WARNING; 212 status = STATE_WARNING;
216 } else { 213 } else {
217 status = STATE_OK; 214 status = STATE_OK;
@@ -224,25 +221,29 @@ int main(int argc, char **argv) {
224 printf("Successfully connected to database %s (user %s) " 221 printf("Successfully connected to database %s (user %s) "
225 "at server %s%s%s (server version: %d.%d.%d, " 222 "at server %s%s%s (server version: %d.%d.%d, "
226 "protocol version: %d, pid: %d)\n", 223 "protocol version: %d, pid: %d)\n",
227 PQdb(conn), PQuser(conn), PSQL_SOCKET3(server_host, PQport(conn)), PSQL_SERVER_VERSION3(server_version), 224 PQdb(conn), PQuser(conn), PSQL_SOCKET3(server_host, PQport(conn)),
228 PQprotocolVersion(conn), PQbackendPID(conn)); 225 PSQL_SERVER_VERSION3(server_version), PQprotocolVersion(conn), PQbackendPID(conn));
229 } 226 }
230 227
231 printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), dbName, elapsed_time, 228 printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), config.dbName, elapsed_time,
232 fperfdata("time", elapsed_time, "s", !!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, true, 0, false, 0)); 229 fperfdata("time", elapsed_time, "s", (config.twarn > 0.0), config.twarn,
230 (config.tcrit > 0.0), config.tcrit, true, 0, false, 0));
233 231
234 int query_status = STATE_UNKNOWN; 232 mp_state_enum query_status = STATE_UNKNOWN;
235 if (pgquery) 233 if (config.pgquery) {
236 query_status = do_query(conn, pgquery); 234 query_status = do_query(conn, config.pgquery, config.pgqueryname, config.qthresholds,
235 config.query_warning, config.query_critical);
236 }
237 237
238 if (verbose) 238 if (verbose) {
239 printf("Closing connection\n"); 239 printf("Closing connection\n");
240 }
240 PQfinish(conn); 241 PQfinish(conn);
241 return (pgquery && query_status > status) ? query_status : status; 242 return (config.pgquery && query_status > status) ? query_status : status;
242} 243}
243 244
244/* process command-line arguments */ 245/* process command-line arguments */
245int process_arguments(int argc, char **argv) { 246check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
246 static struct option longopts[] = {{"help", no_argument, 0, 'h'}, 247 static struct option longopts[] = {{"help", no_argument, 0, 'h'},
247 {"version", no_argument, 0, 'V'}, 248 {"version", no_argument, 0, 'V'},
248 {"timeout", required_argument, 0, 't'}, 249 {"timeout", required_argument, 0, 't'},
@@ -262,12 +263,19 @@ int process_arguments(int argc, char **argv) {
262 {"verbose", no_argument, 0, 'v'}, 263 {"verbose", no_argument, 0, 'v'},
263 {0, 0, 0, 0}}; 264 {0, 0, 0, 0}};
264 265
266 check_pgsql_config_wrapper result = {
267 .errorcode = OK,
268 .config = check_pgsql_config_init(),
269 };
270
265 while (true) { 271 while (true) {
266 int option = 0; 272 int option = 0;
267 int option_char = getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option); 273 int option_char =
274 getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option);
268 275
269 if (option_char == EOF) 276 if (option_char == EOF) {
270 break; 277 break;
278 }
271 279
272 switch (option_char) { 280 switch (option_char) {
273 case '?': /* usage */ 281 case '?': /* usage */
@@ -279,68 +287,75 @@ int process_arguments(int argc, char **argv) {
279 print_revision(progname, NP_VERSION); 287 print_revision(progname, NP_VERSION);
280 exit(STATE_UNKNOWN); 288 exit(STATE_UNKNOWN);
281 case 't': /* timeout period */ 289 case 't': /* timeout period */
282 if (!is_integer(optarg)) 290 if (!is_integer(optarg)) {
283 usage2(_("Timeout interval must be a positive integer"), optarg); 291 usage2(_("Timeout interval must be a positive integer"), optarg);
284 else 292 } else {
285 timeout_interval = atoi(optarg); 293 timeout_interval = atoi(optarg);
294 }
286 break; 295 break;
287 case 'c': /* critical time threshold */ 296 case 'c': /* critical time threshold */
288 if (!is_nonnegative(optarg)) 297 if (!is_nonnegative(optarg)) {
289 usage2(_("Critical threshold must be a positive integer"), optarg); 298 usage2(_("Critical threshold must be a positive integer"), optarg);
290 else 299 } else {
291 tcrit = strtod(optarg, NULL); 300 result.config.tcrit = strtod(optarg, NULL);
301 }
292 break; 302 break;
293 case 'w': /* warning time threshold */ 303 case 'w': /* warning time threshold */
294 if (!is_nonnegative(optarg)) 304 if (!is_nonnegative(optarg)) {
295 usage2(_("Warning threshold must be a positive integer"), optarg); 305 usage2(_("Warning threshold must be a positive integer"), optarg);
296 else 306 } else {
297 twarn = strtod(optarg, NULL); 307 result.config.twarn = strtod(optarg, NULL);
308 }
298 break; 309 break;
299 case 'C': /* critical query threshold */ 310 case 'C': /* critical query threshold */
300 query_critical = optarg; 311 result.config.query_critical = optarg;
301 break; 312 break;
302 case 'W': /* warning query threshold */ 313 case 'W': /* warning query threshold */
303 query_warning = optarg; 314 result.config.query_warning = optarg;
304 break; 315 break;
305 case 'H': /* host */ 316 case 'H': /* host */
306 if ((*optarg != '/') && (!is_host(optarg))) 317 if ((*optarg != '/') && (!is_host(optarg))) {
307 usage2(_("Invalid hostname/address"), optarg); 318 usage2(_("Invalid hostname/address"), optarg);
308 else 319 } else {
309 pghost = optarg; 320 result.config.pghost = optarg;
321 }
310 break; 322 break;
311 case 'P': /* port */ 323 case 'P': /* port */
312 if (!is_integer(optarg)) 324 if (!is_integer(optarg)) {
313 usage2(_("Port must be a positive integer"), optarg); 325 usage2(_("Port must be a positive integer"), optarg);
314 else 326 } else {
315 pgport = optarg; 327 result.config.pgport = optarg;
328 }
316 break; 329 break;
317 case 'd': /* database name */ 330 case 'd': /* database name */
318 if (strlen(optarg) >= NAMEDATALEN) { 331 if (strlen(optarg) >= NAMEDATALEN) {
319 usage2(_("Database name exceeds the maximum length"), optarg); 332 usage2(_("Database name exceeds the maximum length"), optarg);
320 } 333 }
321 snprintf(dbName, NAMEDATALEN, "%s", optarg); 334 snprintf(result.config.dbName, NAMEDATALEN, "%s", optarg);
322 break; 335 break;
323 case 'l': /* login name */ 336 case 'l': /* login name */
324 if (!is_pg_logname(optarg)) 337 if (!is_pg_logname(optarg)) {
325 usage2(_("User name is not valid"), optarg); 338 usage2(_("User name is not valid"), optarg);
326 else 339 } else {
327 pguser = optarg; 340 result.config.pguser = optarg;
341 }
328 break; 342 break;
329 case 'p': /* authentication password */ 343 case 'p': /* authentication password */
330 case 'a': 344 case 'a':
331 pgpasswd = optarg; 345 result.config.pgpasswd = optarg;
332 break; 346 break;
333 case 'o': 347 case 'o':
334 if (pgparams) 348 if (result.config.pgparams) {
335 asprintf(&pgparams, "%s %s", pgparams, optarg); 349 asprintf(&result.config.pgparams, "%s %s", result.config.pgparams, optarg);
336 else 350 } else {
337 asprintf(&pgparams, "%s", optarg); 351 asprintf(&result.config.pgparams, "%s", optarg);
352 }
338 break; 353 break;
339 case 'q': 354 case 'q':
340 pgquery = optarg; 355 result.config.pgquery = optarg;
341 break; 356 break;
342 case OPTID_QUERYNAME: 357 case OPTID_QUERYNAME:
343 pgqueryname = optarg; 358 result.config.pgqueryname = optarg;
344 break; 359 break;
345 case 'v': 360 case 'v':
346 verbose++; 361 verbose++;
@@ -348,9 +363,10 @@ int process_arguments(int argc, char **argv) {
348 } 363 }
349 } 364 }
350 365
351 set_thresholds(&qthresholds, query_warning, query_critical); 366 set_thresholds(&result.config.qthresholds, result.config.query_warning,
367 result.config.query_critical);
352 368
353 return OK; 369 return result;
354} 370}
355 371
356/** 372/**
@@ -378,8 +394,9 @@ should be added.</para>
378******************************************************************************/ 394******************************************************************************/
379 395
380bool is_pg_logname(char *username) { 396bool is_pg_logname(char *username) {
381 if (strlen(username) > NAMEDATALEN - 1) 397 if (strlen(username) > NAMEDATALEN - 1) {
382 return (false); 398 return (false);
399 }
383 return (true); 400 return (true);
384} 401}
385 402
@@ -394,7 +411,7 @@ bool is_pg_logname(char *username) {
394void print_help(void) { 411void print_help(void) {
395 char *myport; 412 char *myport;
396 413
397 xasprintf(&myport, "%d", DEFAULT_PORT); 414 xasprintf(&myport, "%d", 5432);
398 415
399 print_revision(progname, NP_VERSION); 416 print_revision(progname, NP_VERSION);
400 417
@@ -447,29 +464,39 @@ void print_help(void) {
447 464
448 printf(" %s\n", _("If a query is specified using the -q option, it will be executed after")); 465 printf(" %s\n", _("If a query is specified using the -q option, it will be executed after"));
449 printf(" %s\n", _("connecting to the server. The result from the query has to be numeric.")); 466 printf(" %s\n", _("connecting to the server. The result from the query has to be numeric."));
450 printf(" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result ")); 467 printf(" %s\n",
468 _("Multiple SQL commands, separated by semicolon, are allowed but the result "));
451 printf(" %s\n", _("of the last command is taken into account only. The value of the first")); 469 printf(" %s\n", _("of the last command is taken into account only. The value of the first"));
452 printf(" %s\n", _("column in the first row is used as the check result. If a second column is")); 470 printf(" %s\n",
471 _("column in the first row is used as the check result. If a second column is"));
453 printf(" %s\n", _("present in the result set, this is added to the plugin output with a")); 472 printf(" %s\n", _("present in the result set, this is added to the plugin output with a"));
454 printf(" %s\n", _("prefix of \"Extra Info:\". This information can be displayed in the system")); 473 printf(" %s\n",
474 _("prefix of \"Extra Info:\". This information can be displayed in the system"));
455 printf(" %s\n\n", _("executing the plugin.")); 475 printf(" %s\n\n", _("executing the plugin."));
456 476
457 printf(" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual")); 477 printf(" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual"));
458 printf(" %s\n\n", _("for details about how to access internal statistics of the database server.")); 478 printf(" %s\n\n",
479 _("for details about how to access internal statistics of the database server."));
459 480
460 printf(" %s\n", _("For a list of available connection parameters which may be used with the -o")); 481 printf(" %s\n",
461 printf(" %s\n", _("command line option, see the documentation for PQconnectdb() in the chapter")); 482 _("For a list of available connection parameters which may be used with the -o"));
483 printf(" %s\n",
484 _("command line option, see the documentation for PQconnectdb() in the chapter"));
462 printf(" %s\n", _("\"libpq - C Library\" of the PostgreSQL manual. For example, this may be")); 485 printf(" %s\n", _("\"libpq - C Library\" of the PostgreSQL manual. For example, this may be"));
463 printf(" %s\n", _("used to specify a service name in pg_service.conf to be used for additional")); 486 printf(" %s\n",
487 _("used to specify a service name in pg_service.conf to be used for additional"));
464 printf(" %s\n", _("connection parameters: -o 'service=<name>' or to specify the SSL mode:")); 488 printf(" %s\n", _("connection parameters: -o 'service=<name>' or to specify the SSL mode:"));
465 printf(" %s\n\n", _("-o 'sslmode=require'.")); 489 printf(" %s\n\n", _("-o 'sslmode=require'."));
466 490
467 printf(" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To")); 491 printf(" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To"));
468 printf(" %s\n", _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP")); 492 printf(" %s\n",
493 _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP"));
469 printf(" %s\n\n", _("connections (start the postmaster with the -i option).")); 494 printf(" %s\n\n", _("connections (start the postmaster with the -i option)."));
470 495
471 printf(" %s\n", _("Typically, the monitoring user (unless the --logname option is used) should be")); 496 printf(" %s\n",
472 printf(" %s\n", _("able to connect to the database without a password. The plugin can also send")); 497 _("Typically, the monitoring user (unless the --logname option is used) should be"));
498 printf(" %s\n",
499 _("able to connect to the database without a password. The plugin can also send"));
473 printf(" %s\n", _("a password, but no effort is made to obscure or encrypt the password.")); 500 printf(" %s\n", _("a password, but no effort is made to obscure or encrypt the password."));
474 501
475 printf(UT_SUPPORT); 502 printf(UT_SUPPORT);
@@ -482,13 +509,16 @@ void print_usage(void) {
482 "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n"); 509 "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n");
483} 510}
484 511
485int do_query(PGconn *conn, char *query) { 512mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thresholds *qthresholds,
486 if (verbose) 513 char *query_warning, char *query_critical) {
514 if (verbose) {
487 printf("Executing SQL query \"%s\".\n", query); 515 printf("Executing SQL query \"%s\".\n", query);
516 }
488 PGresult *res = PQexec(conn, query); 517 PGresult *res = PQexec(conn, query);
489 518
490 if (PGRES_TUPLES_OK != PQresultStatus(res)) { 519 if (PGRES_TUPLES_OK != PQresultStatus(res)) {
491 printf(_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"), PQerrorMessage(conn)); 520 printf(_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"),
521 PQerrorMessage(conn));
492 return STATE_CRITICAL; 522 return STATE_CRITICAL;
493 } 523 }
494 524
@@ -510,8 +540,9 @@ int do_query(PGconn *conn, char *query) {
510 540
511 char *endptr = NULL; 541 char *endptr = NULL;
512 double value = strtod(val_str, &endptr); 542 double value = strtod(val_str, &endptr);
513 if (verbose) 543 if (verbose) {
514 printf("Query result: %f\n", value); 544 printf("Query result: %f\n", value);
545 }
515 546
516 if (endptr == val_str) { 547 if (endptr == val_str) {
517 printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str); 548 printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str);
@@ -519,11 +550,12 @@ int do_query(PGconn *conn, char *query) {
519 } 550 }
520 551
521 if ((endptr != NULL) && (*endptr != '\0')) { 552 if ((endptr != NULL) && (*endptr != '\0')) {
522 if (verbose) 553 if (verbose) {
523 printf("Garbage after value: %s.\n", endptr); 554 printf("Garbage after value: %s.\n", endptr);
555 }
524 } 556 }
525 557
526 int my_status = get_status(value, qthresholds); 558 mp_state_enum my_status = get_status(value, qthresholds);
527 printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK") 559 printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK")
528 : (my_status == STATE_WARNING) ? _("WARNING") 560 : (my_status == STATE_WARNING) ? _("WARNING")
529 : (my_status == STATE_CRITICAL) ? _("CRITICAL") 561 : (my_status == STATE_CRITICAL) ? _("CRITICAL")
@@ -534,7 +566,8 @@ int do_query(PGconn *conn, char *query) {
534 printf(_("'%s' returned %f"), query, value); 566 printf(_("'%s' returned %f"), query, value);
535 } 567 }
536 568
537 printf("|query=%f;%s;%s;;\n", value, query_warning ? query_warning : "", query_critical ? query_critical : ""); 569 printf("|query=%f;%s;%s;;\n", value, query_warning ? query_warning : "",
570 query_critical ? query_critical : "");
538 if (PQnfields(res) > 1) { 571 if (PQnfields(res) > 1) {
539 char *extra_info = PQgetvalue(res, 0, 1); 572 char *extra_info = PQgetvalue(res, 0, 1);
540 if (extra_info != NULL) { 573 if (extra_info != NULL) {