[monitoring-plugins] Refactor check_pgsql
Lorenz Kästle
git at monitoring-plugins.org
Wed Mar 12 11:10:12 CET 2025
Module: monitoring-plugins
Branch: master
Commit: de392a81ede00fef1c25e220ee253d487453f6cd
Author: Lorenz Kästle <12514511+RincewindsHat at users.noreply.github.com>
Date: Wed Mar 12 02:16:41 2025 +0100
URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=de392a81
Refactor check_pgsql
---
plugins/Makefile.am | 1 +
plugins/check_pgsql.c | 143 +++++++++++++++++++----------------------
plugins/check_pgsql.d/config.h | 61 ++++++++++++++++++
3 files changed, 128 insertions(+), 77 deletions(-)
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 5d4449bf..6ee121ba 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -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 \
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 0c0ef415..84305adb 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -28,6 +28,7 @@
*
*****************************************************************************/
+#include "states.h"
const char *progname = "check_pgsql";
const char *copyright = "1999-2024";
const char *email = "devel at monitoring-plugins.org";
@@ -35,12 +36,13 @@ const char *email = "devel at 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 at 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")
diff --git a/plugins/check_pgsql.d/config.h b/plugins/check_pgsql.d/config.h
new file mode 100644
index 00000000..2d4b8b89
--- /dev/null
+++ b/plugins/check_pgsql.d/config.h
@@ -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;
+}
More information about the Commits
mailing list