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.c80
1 files changed, 33 insertions, 47 deletions
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 5cd4709..6199033 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -34,6 +34,7 @@ const char *email = "devel@monitoring-plugins.org";
34 34
35#include "common.h" 35#include "common.h"
36#include "utils.h" 36#include "utils.h"
37#include "utils_cmd.h"
37 38
38#include "netutils.h" 39#include "netutils.h"
39#include <libpq-fe.h> 40#include <libpq-fe.h>
@@ -68,7 +69,6 @@ int process_arguments (int, char **);
68int validate_arguments (void); 69int validate_arguments (void);
69void print_usage (void); 70void print_usage (void);
70void print_help (void); 71void print_help (void);
71int is_pg_dbname (char *);
72int is_pg_logname (char *); 72int is_pg_logname (char *);
73int do_query (PGconn *, char *); 73int do_query (PGconn *, char *);
74 74
@@ -84,6 +84,8 @@ char *pgparams = NULL;
84double twarn = (double)DEFAULT_WARN; 84double twarn = (double)DEFAULT_WARN;
85double tcrit = (double)DEFAULT_CRIT; 85double tcrit = (double)DEFAULT_CRIT;
86char *pgquery = NULL; 86char *pgquery = NULL;
87#define OPTID_QUERYNAME -1000
88char *pgqueryname = NULL;
87char *query_warning = NULL; 89char *query_warning = NULL;
88char *query_critical = NULL; 90char *query_critical = NULL;
89thresholds *qthresholds = NULL; 91thresholds *qthresholds = NULL;
@@ -91,7 +93,7 @@ int verbose = 0;
91 93
92/****************************************************************************** 94/******************************************************************************
93 95
94The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ 96The (pseudo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
95tags in the comments. With in the tags, the XML is assembled sequentially. 97tags in the comments. With in the tags, the XML is assembled sequentially.
96You can define entities in tags. You also have all the #defines available as 98You can define entities in tags. You also have all the #defines available as
97entities. 99entities.
@@ -284,6 +286,7 @@ process_arguments (int argc, char **argv)
284 {"database", required_argument, 0, 'd'}, 286 {"database", required_argument, 0, 'd'},
285 {"option", required_argument, 0, 'o'}, 287 {"option", required_argument, 0, 'o'},
286 {"query", required_argument, 0, 'q'}, 288 {"query", required_argument, 0, 'q'},
289 {"queryname", required_argument, 0, OPTID_QUERYNAME},
287 {"query_critical", required_argument, 0, 'C'}, 290 {"query_critical", required_argument, 0, 'C'},
288 {"query_warning", required_argument, 0, 'W'}, 291 {"query_warning", required_argument, 0, 'W'},
289 {"verbose", no_argument, 0, 'v'}, 292 {"verbose", no_argument, 0, 'v'},
@@ -343,10 +346,10 @@ process_arguments (int argc, char **argv)
343 pgport = optarg; 346 pgport = optarg;
344 break; 347 break;
345 case 'd': /* database name */ 348 case 'd': /* database name */
346 if (!is_pg_dbname (optarg)) /* checks length and valid chars */ 349 if (strlen(optarg) >= NAMEDATALEN) {
347 usage2 (_("Database name is not valid"), optarg); 350 usage2 (_("Database name exceeds the maximum length"), optarg);
348 else /* we know length, and know optarg is terminated, so us strcpy */ 351 }
349 strcpy (dbName, optarg); 352 snprintf(dbName, NAMEDATALEN, "%s", optarg);
350 break; 353 break;
351 case 'l': /* login name */ 354 case 'l': /* login name */
352 if (!is_pg_logname (optarg)) 355 if (!is_pg_logname (optarg))
@@ -367,6 +370,9 @@ process_arguments (int argc, char **argv)
367 case 'q': 370 case 'q':
368 pgquery = optarg; 371 pgquery = optarg;
369 break; 372 break;
373 case OPTID_QUERYNAME:
374 pgqueryname = optarg;
375 break;
370 case 'v': 376 case 'v':
371 verbose++; 377 verbose++;
372 break; 378 break;
@@ -407,45 +413,6 @@ validate_arguments ()
407 return OK; 413 return OK;
408} 414}
409 415
410
411/******************************************************************************
412
413@@-
414<sect3>
415<title>is_pg_dbname</title>
416
417<para>&PROTO_is_pg_dbname;</para>
418
419<para>Given a database name, this function returns TRUE if the string
420is a valid PostgreSQL database name, and returns false if it is
421not.</para>
422
423<para>Valid PostgreSQL database names are less than &NAMEDATALEN;
424characters long and consist of letters, numbers, and underscores. The
425first character cannot be a number, however.</para>
426
427</sect3>
428-@@
429******************************************************************************/
430
431
432
433int
434is_pg_dbname (char *dbname)
435{
436 char txt[NAMEDATALEN];
437 char tmp[NAMEDATALEN];
438 if (strlen (dbname) > NAMEDATALEN - 1)
439 return (FALSE);
440 strncpy (txt, dbname, NAMEDATALEN - 1);
441 txt[NAMEDATALEN - 1] = 0;
442 if (sscanf (txt, "%[_a-zA-Z]%[^_a-zA-Z0-9-]", tmp, tmp) == 1)
443 return (TRUE);
444 if (sscanf (txt, "%[_a-zA-Z]%[_a-zA-Z0-9-]%[^_a-zA-Z0-9-]", tmp, tmp, tmp) ==
445 2) return (TRUE);
446 return (FALSE);
447}
448
449/** 416/**
450 417
451the tango program should eventually create an entity here based on the 418the tango program should eventually create an entity here based on the
@@ -528,6 +495,9 @@ print_help (void)
528 495
529 printf (" %s\n", "-q, --query=STRING"); 496 printf (" %s\n", "-q, --query=STRING");
530 printf (" %s\n", _("SQL query to run. Only first column in first row will be read")); 497 printf (" %s\n", _("SQL query to run. Only first column in first row will be read"));
498 printf (" %s\n", "--queryname=STRING");
499 printf (" %s\n", _("A name for the query, this string is used instead of the query"));
500 printf (" %s\n", _("in the long output of the plugin"));
531 printf (" %s\n", "-W, --query-warning=RANGE"); 501 printf (" %s\n", "-W, --query-warning=RANGE");
532 printf (" %s\n", _("SQL query value to result in warning status (double)")); 502 printf (" %s\n", _("SQL query value to result in warning status (double)"));
533 printf (" %s\n", "-C, --query-critical=RANGE"); 503 printf (" %s\n", "-C, --query-critical=RANGE");
@@ -547,7 +517,10 @@ print_help (void)
547 printf (" %s\n", _("connecting to the server. The result from the query has to be numeric.")); 517 printf (" %s\n", _("connecting to the server. The result from the query has to be numeric."));
548 printf (" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result ")); 518 printf (" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result "));
549 printf (" %s\n", _("of the last command is taken into account only. The value of the first")); 519 printf (" %s\n", _("of the last command is taken into account only. The value of the first"));
550 printf (" %s\n\n", _("column in the first row is used as the check result.")); 520 printf (" %s\n", _("column in the first row is used as the check result. If a second column is"));
521 printf (" %s\n", _("present in the result set, this is added to the plugin output with a"));
522 printf (" %s\n", _("prefix of \"Extra Info:\". This information can be displayed in the system"));
523 printf (" %s\n\n", _("executing the plugin."));
551 524
552 printf (" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual")); 525 printf (" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual"));
553 printf (" %s\n\n", _("for details about how to access internal statistics of the database server.")); 526 printf (" %s\n\n", _("for details about how to access internal statistics of the database server."));
@@ -587,6 +560,7 @@ do_query (PGconn *conn, char *query)
587 PGresult *res; 560 PGresult *res;
588 561
589 char *val_str; 562 char *val_str;
563 char *extra_info;
590 double value; 564 double value;
591 565
592 char *endptr = NULL; 566 char *endptr = NULL;
@@ -641,10 +615,22 @@ do_query (PGconn *conn, char *query)
641 : (my_status == STATE_CRITICAL) 615 : (my_status == STATE_CRITICAL)
642 ? _("CRITICAL") 616 ? _("CRITICAL")
643 : _("UNKNOWN")); 617 : _("UNKNOWN"));
644 printf (_("'%s' returned %f"), query, value); 618 if(pgqueryname) {
619 printf (_("%s returned %f"), pgqueryname, value);
620 }
621 else {
622 printf (_("'%s' returned %f"), query, value);
623 }
624
645 printf ("|query=%f;%s;%s;;\n", value, 625 printf ("|query=%f;%s;%s;;\n", value,
646 query_warning ? query_warning : "", 626 query_warning ? query_warning : "",
647 query_critical ? query_critical : ""); 627 query_critical ? query_critical : "");
628 if (PQnfields (res) > 1) {
629 extra_info = PQgetvalue (res, 0, 1);
630 if (extra_info != NULL) {
631 printf ("Extra Info: %s\n", extra_info);
632 }
633 }
648 return my_status; 634 return my_status;
649} 635}
650 636