mirror of
https://github.com/monitoring-plugins/monitoring-plugins.git
synced 2026-06-14 19:19:59 -04:00
Refactor check_pgsql
This commit is contained in:
parent
003b96741d
commit
de392a81ed
3 changed files with 128 additions and 77 deletions
|
|
@ -61,6 +61,7 @@ EXTRA_DIST = t \
|
|||
check_mysql_query.d \
|
||||
check_mrtg.d \
|
||||
check_apt.d \
|
||||
check_pgsql.d \
|
||||
check_by_ssh.d \
|
||||
check_smtp.d \
|
||||
check_mysql.d \
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "states.h"
|
||||
const char *progname = "check_pgsql";
|
||||
const char *copyright = "1999-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
|
@ -35,12 +36,13 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "utils_cmd.h"
|
||||
#include "check_pgsql.d/config.h"
|
||||
#include "thresholds.h"
|
||||
|
||||
#include "netutils.h"
|
||||
#include <libpq-fe.h>
|
||||
#include <pg_config_manual.h>
|
||||
|
||||
#define DEFAULT_DB "template1"
|
||||
#define DEFAULT_HOST "127.0.0.1"
|
||||
|
||||
/* return the PSQL server version as a 3-tuple */
|
||||
|
|
@ -53,33 +55,18 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#define PSQL_SOCKET3(host, port) \
|
||||
((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port
|
||||
|
||||
enum {
|
||||
DEFAULT_PORT = 5432,
|
||||
DEFAULT_WARN = 2,
|
||||
DEFAULT_CRIT = 8
|
||||
};
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_pgsql_config config;
|
||||
} check_pgsql_config_wrapper;
|
||||
static check_pgsql_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
static bool is_pg_logname(char * /*username*/);
|
||||
static int do_query(PGconn * /*conn*/, char * /*query*/);
|
||||
static mp_state_enum do_query(PGconn * /*conn*/, char * /*query*/, const char /*pgqueryname*/[], thresholds * /*qthresholds*/,
|
||||
char * /*query_warning*/, char * /*query_critical*/);
|
||||
void print_usage(void);
|
||||
|
||||
static char *pghost = NULL; /* host name of the backend server */
|
||||
static char *pgport = NULL; /* port of the backend server */
|
||||
static char *pgoptions = NULL;
|
||||
static char *pgtty = NULL;
|
||||
static char dbName[NAMEDATALEN] = DEFAULT_DB;
|
||||
static char *pguser = NULL;
|
||||
static char *pgpasswd = NULL;
|
||||
static char *pgparams = NULL;
|
||||
static double twarn = (double)DEFAULT_WARN;
|
||||
static double tcrit = (double)DEFAULT_CRIT;
|
||||
static char *pgquery = NULL;
|
||||
static char *pgqueryname = NULL;
|
||||
static char *query_warning = NULL;
|
||||
static char *query_critical = NULL;
|
||||
static thresholds *qthresholds = NULL;
|
||||
static int verbose = 0;
|
||||
|
||||
#define OPTID_QUERYNAME -1000
|
||||
|
|
@ -139,20 +126,16 @@ int main(int argc, char **argv) {
|
|||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
/* begin, by setting the parameters for a backend connection if the
|
||||
* parameters are null, then the system will try to use reasonable
|
||||
* defaults by looking up environment variables or, failing that,
|
||||
* using hardwired constants */
|
||||
|
||||
pgoptions = NULL; /* special options to start up the backend server */
|
||||
pgtty = NULL; /* debugging tty for the backend server */
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR) {
|
||||
check_pgsql_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_pgsql_config config = tmp_config.config;
|
||||
|
||||
if (verbose > 2) {
|
||||
printf("Arguments initialized\n");
|
||||
}
|
||||
|
|
@ -164,31 +147,31 @@ int main(int argc, char **argv) {
|
|||
alarm(timeout_interval);
|
||||
|
||||
char *conninfo = NULL;
|
||||
if (pgparams) {
|
||||
asprintf(&conninfo, "%s ", pgparams);
|
||||
if (config.pgparams) {
|
||||
asprintf(&conninfo, "%s ", config.pgparams);
|
||||
}
|
||||
|
||||
asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName);
|
||||
if (pghost) {
|
||||
asprintf(&conninfo, "%s host = '%s'", conninfo, pghost);
|
||||
asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", config.dbName);
|
||||
if (config.pghost) {
|
||||
asprintf(&conninfo, "%s host = '%s'", conninfo, config.pghost);
|
||||
}
|
||||
if (pgport) {
|
||||
asprintf(&conninfo, "%s port = '%s'", conninfo, pgport);
|
||||
if (config.pgport) {
|
||||
asprintf(&conninfo, "%s port = '%s'", conninfo, config.pgport);
|
||||
}
|
||||
if (pgoptions) {
|
||||
asprintf(&conninfo, "%s options = '%s'", conninfo, pgoptions);
|
||||
if (config.pgoptions) {
|
||||
asprintf(&conninfo, "%s options = '%s'", conninfo, config.pgoptions);
|
||||
}
|
||||
/* if (pgtty) -- ignored by PQconnectdb */
|
||||
if (pguser) {
|
||||
asprintf(&conninfo, "%s user = '%s'", conninfo, pguser);
|
||||
if (config.pguser) {
|
||||
asprintf(&conninfo, "%s user = '%s'", conninfo, config.pguser);
|
||||
}
|
||||
|
||||
if (verbose) { /* do not include password (see right below) in output */
|
||||
printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, pgpasswd ? " password = <hidden>" : "");
|
||||
printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, config.pgpasswd ? " password = <hidden>" : "");
|
||||
}
|
||||
|
||||
if (pgpasswd) {
|
||||
asprintf(&conninfo, "%s password = '%s'", conninfo, pgpasswd);
|
||||
if (config.pgpasswd) {
|
||||
asprintf(&conninfo, "%s password = '%s'", conninfo, config.pgpasswd);
|
||||
}
|
||||
|
||||
/* make a connection to the database */
|
||||
|
|
@ -203,7 +186,7 @@ int main(int argc, char **argv) {
|
|||
end_timeval.tv_usec += 1000000;
|
||||
}
|
||||
double elapsed_time =
|
||||
(double)(end_timeval.tv_sec - start_timeval.tv_sec) + (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0;
|
||||
(double)(end_timeval.tv_sec - start_timeval.tv_sec) + ((double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0);
|
||||
|
||||
if (verbose) {
|
||||
printf("Time elapsed: %f\n", elapsed_time);
|
||||
|
|
@ -214,15 +197,15 @@ int main(int argc, char **argv) {
|
|||
printf("Verifying connection\n");
|
||||
}
|
||||
if (PQstatus(conn) == CONNECTION_BAD) {
|
||||
printf(_("CRITICAL - no connection to '%s' (%s).\n"), dbName, PQerrorMessage(conn));
|
||||
printf(_("CRITICAL - no connection to '%s' (%s).\n"), config.dbName, PQerrorMessage(conn));
|
||||
PQfinish(conn);
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
int status = STATE_UNKNOWN;
|
||||
if (elapsed_time > tcrit) {
|
||||
mp_state_enum status = STATE_UNKNOWN;
|
||||
if (elapsed_time > config.tcrit) {
|
||||
status = STATE_CRITICAL;
|
||||
} else if (elapsed_time > twarn) {
|
||||
} else if (elapsed_time > config.twarn) {
|
||||
status = STATE_WARNING;
|
||||
} else {
|
||||
status = STATE_OK;
|
||||
|
|
@ -239,23 +222,23 @@ int main(int argc, char **argv) {
|
|||
PQprotocolVersion(conn), PQbackendPID(conn));
|
||||
}
|
||||
|
||||
printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), dbName, elapsed_time,
|
||||
fperfdata("time", elapsed_time, "s", !!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, true, 0, false, 0));
|
||||
printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), config.dbName, elapsed_time,
|
||||
fperfdata("time", elapsed_time, "s", (config.twarn > 0.0), config.twarn, (config.tcrit > 0.0), config.tcrit, true, 0, false, 0));
|
||||
|
||||
int query_status = STATE_UNKNOWN;
|
||||
if (pgquery) {
|
||||
query_status = do_query(conn, pgquery);
|
||||
mp_state_enum query_status = STATE_UNKNOWN;
|
||||
if (config.pgquery) {
|
||||
query_status = do_query(conn, config.pgquery, config.pgqueryname, config.qthresholds, config.query_warning, config.query_critical);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
printf("Closing connection\n");
|
||||
}
|
||||
PQfinish(conn);
|
||||
return (pgquery && query_status > status) ? query_status : status;
|
||||
return (config.pgquery && query_status > status) ? query_status : status;
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"timeout", required_argument, 0, 't'},
|
||||
|
|
@ -275,6 +258,11 @@ int process_arguments(int argc, char **argv) {
|
|||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
check_pgsql_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_pgsql_config_init(),
|
||||
};
|
||||
|
||||
while (true) {
|
||||
int option = 0;
|
||||
int option_char = getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option);
|
||||
|
|
@ -303,65 +291,65 @@ int process_arguments(int argc, char **argv) {
|
|||
if (!is_nonnegative(optarg)) {
|
||||
usage2(_("Critical threshold must be a positive integer"), optarg);
|
||||
} else {
|
||||
tcrit = strtod(optarg, NULL);
|
||||
result.config.tcrit = strtod(optarg, NULL);
|
||||
}
|
||||
break;
|
||||
case 'w': /* warning time threshold */
|
||||
if (!is_nonnegative(optarg)) {
|
||||
usage2(_("Warning threshold must be a positive integer"), optarg);
|
||||
} else {
|
||||
twarn = strtod(optarg, NULL);
|
||||
result.config.twarn = strtod(optarg, NULL);
|
||||
}
|
||||
break;
|
||||
case 'C': /* critical query threshold */
|
||||
query_critical = optarg;
|
||||
result.config.query_critical = optarg;
|
||||
break;
|
||||
case 'W': /* warning query threshold */
|
||||
query_warning = optarg;
|
||||
result.config.query_warning = optarg;
|
||||
break;
|
||||
case 'H': /* host */
|
||||
if ((*optarg != '/') && (!is_host(optarg))) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
} else {
|
||||
pghost = optarg;
|
||||
result.config.pghost = optarg;
|
||||
}
|
||||
break;
|
||||
case 'P': /* port */
|
||||
if (!is_integer(optarg)) {
|
||||
usage2(_("Port must be a positive integer"), optarg);
|
||||
} else {
|
||||
pgport = optarg;
|
||||
result.config.pgport = optarg;
|
||||
}
|
||||
break;
|
||||
case 'd': /* database name */
|
||||
if (strlen(optarg) >= NAMEDATALEN) {
|
||||
usage2(_("Database name exceeds the maximum length"), optarg);
|
||||
}
|
||||
snprintf(dbName, NAMEDATALEN, "%s", optarg);
|
||||
snprintf(result.config.dbName, NAMEDATALEN, "%s", optarg);
|
||||
break;
|
||||
case 'l': /* login name */
|
||||
if (!is_pg_logname(optarg)) {
|
||||
usage2(_("User name is not valid"), optarg);
|
||||
} else {
|
||||
pguser = optarg;
|
||||
result.config.pguser = optarg;
|
||||
}
|
||||
break;
|
||||
case 'p': /* authentication password */
|
||||
case 'a':
|
||||
pgpasswd = optarg;
|
||||
result.config.pgpasswd = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
if (pgparams) {
|
||||
asprintf(&pgparams, "%s %s", pgparams, optarg);
|
||||
if (result.config.pgparams) {
|
||||
asprintf(&result.config.pgparams, "%s %s", result.config.pgparams, optarg);
|
||||
} else {
|
||||
asprintf(&pgparams, "%s", optarg);
|
||||
asprintf(&result.config.pgparams, "%s", optarg);
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
pgquery = optarg;
|
||||
result.config.pgquery = optarg;
|
||||
break;
|
||||
case OPTID_QUERYNAME:
|
||||
pgqueryname = optarg;
|
||||
result.config.pgqueryname = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
|
|
@ -369,9 +357,9 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
set_thresholds(&qthresholds, query_warning, query_critical);
|
||||
set_thresholds(&result.config.qthresholds, result.config.query_warning, result.config.query_critical);
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -416,7 +404,7 @@ bool is_pg_logname(char *username) {
|
|||
void print_help(void) {
|
||||
char *myport;
|
||||
|
||||
xasprintf(&myport, "%d", DEFAULT_PORT);
|
||||
xasprintf(&myport, "%d", 5432);
|
||||
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
||||
|
|
@ -504,7 +492,8 @@ void print_usage(void) {
|
|||
"[-q <query>] [-C <critical query range>] [-W <warning query range>]\n");
|
||||
}
|
||||
|
||||
int do_query(PGconn *conn, char *query) {
|
||||
mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thresholds *qthresholds, char *query_warning,
|
||||
char *query_critical) {
|
||||
if (verbose) {
|
||||
printf("Executing SQL query \"%s\".\n", query);
|
||||
}
|
||||
|
|
@ -548,7 +537,7 @@ int do_query(PGconn *conn, char *query) {
|
|||
}
|
||||
}
|
||||
|
||||
int my_status = get_status(value, qthresholds);
|
||||
mp_state_enum my_status = get_status(value, qthresholds);
|
||||
printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK")
|
||||
: (my_status == STATE_WARNING) ? _("WARNING")
|
||||
: (my_status == STATE_CRITICAL) ? _("CRITICAL")
|
||||
|
|
|
|||
61
plugins/check_pgsql.d/config.h
Normal file
61
plugins/check_pgsql.d/config.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "thresholds.h"
|
||||
#include <stddef.h>
|
||||
#include <pg_config_manual.h>
|
||||
|
||||
#define DEFAULT_DB "template1"
|
||||
|
||||
enum {
|
||||
DEFAULT_WARN = 2,
|
||||
DEFAULT_CRIT = 8,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *pghost; /* host name of the backend server */
|
||||
char *pgport; /* port of the backend server */
|
||||
char *pgoptions; /* special options to start up the backend server */
|
||||
char *pgtty; /* debugging tty for the backend server */
|
||||
char dbName[NAMEDATALEN];
|
||||
char *pguser;
|
||||
char *pgpasswd;
|
||||
char *pgparams;
|
||||
char *pgquery;
|
||||
char *pgqueryname;
|
||||
|
||||
double twarn;
|
||||
double tcrit;
|
||||
thresholds *qthresholds;
|
||||
char *query_warning;
|
||||
char *query_critical;
|
||||
} check_pgsql_config;
|
||||
|
||||
/* begin, by setting the parameters for a backend connection if the
|
||||
* parameters are null, then the system will try to use reasonable
|
||||
* defaults by looking up environment variables or, failing that,
|
||||
* using hardwired constants
|
||||
* this targets .pgoptions and .pgtty
|
||||
*/
|
||||
|
||||
check_pgsql_config check_pgsql_config_init() {
|
||||
check_pgsql_config tmp = {
|
||||
.pghost = NULL,
|
||||
.pgport = NULL,
|
||||
.pgoptions = NULL,
|
||||
.pgtty = NULL,
|
||||
.dbName = DEFAULT_DB,
|
||||
.pguser = NULL,
|
||||
.pgpasswd = NULL,
|
||||
.pgparams = NULL,
|
||||
.pgquery = NULL,
|
||||
.pgqueryname = NULL,
|
||||
|
||||
.twarn = (double)DEFAULT_WARN,
|
||||
.tcrit = (double)DEFAULT_CRIT,
|
||||
.qthresholds = NULL,
|
||||
.query_warning = NULL,
|
||||
.query_critical = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
Loading…
Reference in a new issue