[monitoring-plugins] check_mysql_query: implement modern output

Lorenz Kästle git at monitoring-plugins.org
Fri Nov 7 15:30:11 CET 2025


 Module: monitoring-plugins
 Branch: master
 Commit: 9d827acbe1aac0edaa91a8765a87412a189cadf1
 Author: Lorenz Kästle <12514511+RincewindsHat at users.noreply.github.com>
   Date: Fri Nov  7 15:01:36 2025 +0100
    URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=9d827acb

check_mysql_query: implement modern output

---

 plugins/check_mysql_query.c          | 105 +++++++++++++++++++++--------------
 plugins/check_mysql_query.d/config.h |   4 +-
 plugins/t/check_mysql_query.t        |   2 +-
 3 files changed, 65 insertions(+), 46 deletions(-)

diff --git a/plugins/check_mysql_query.c b/plugins/check_mysql_query.c
index c7e84deb..cb79b4b4 100644
--- a/plugins/check_mysql_query.c
+++ b/plugins/check_mysql_query.c
@@ -29,11 +29,11 @@
  *
  *****************************************************************************/
 
-const char *progname = "check_mysql_query";
-const char *copyright = "1999-2024";
-const char *email = "devel at monitoring-plugins.org";
-
 #include "common.h"
+#include "output.h"
+#include "perfdata.h"
+#include "states.h"
+#include "thresholds.h"
 #include "utils.h"
 #include "utils_base.h"
 #include "netutils.h"
@@ -42,6 +42,10 @@ const char *email = "devel at monitoring-plugins.org";
 #include <mysql.h>
 #include <errmsg.h>
 
+const char *progname = "check_mysql_query";
+const char *copyright = "1999-2024";
+const char *email = "devel at monitoring-plugins.org";
+
 typedef struct {
 	int errorcode;
 	check_mysql_query_config config;
@@ -83,27 +87,38 @@ int main(int argc, char **argv) {
 		mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client");
 	}
 
+	mp_check overall = mp_check_init();
+	mp_subcheck sc_connect = mp_subcheck_init();
+
 	/* establish a connection to the server and error checking */
 	if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db,
 							config.db_port, config.db_socket, 0)) {
+		xasprintf(&sc_connect.output, "query failed: %s", mysql_error(&mysql));
+
 		if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) {
-			die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
+			sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
 		} else if (mysql_errno(&mysql) == CR_VERSION_ERROR) {
-			die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
+			sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
 		} else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) {
-			die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
+			sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
 		} else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) {
-			die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
+			sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
 		} else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) {
-			die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
+			sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
 		} else {
-			die(STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error(&mysql));
+			sc_connect = mp_set_subcheck_state(sc_connect, STATE_CRITICAL);
 		}
+
+		mp_add_subcheck_to_check(&overall, sc_connect);
+		mp_exit(overall);
 	}
 
-	char *error = NULL;
+	sc_connect = mp_set_subcheck_state(sc_connect, STATE_OK);
+	xasprintf(&sc_connect.output, "query succeeded");
+	mp_add_subcheck_to_check(&overall, sc_connect);
+
 	if (mysql_query(&mysql, config.sql_query) != 0) {
-		error = strdup(mysql_error(&mysql));
+		char *error = strdup(mysql_error(&mysql));
 		mysql_close(&mysql);
 		die(STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error);
 	}
@@ -111,7 +126,7 @@ int main(int argc, char **argv) {
 	MYSQL_RES *res;
 	/* store the result */
 	if ((res = mysql_store_result(&mysql)) == NULL) {
-		error = strdup(mysql_error(&mysql));
+		char *error = strdup(mysql_error(&mysql));
 		mysql_close(&mysql);
 		die(STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error);
 	}
@@ -122,17 +137,24 @@ int main(int argc, char **argv) {
 		die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned"));
 	}
 
+	mp_subcheck sc_value = mp_subcheck_init();
 	MYSQL_ROW row;
 	/* fetch the first row */
 	if ((row = mysql_fetch_row(res)) == NULL) {
-		error = strdup(mysql_error(&mysql));
+		xasprintf(&sc_value.output, "fetch row error - %s", mysql_error(&mysql));
 		mysql_free_result(res);
 		mysql_close(&mysql);
-		die(STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error);
+
+		sc_value = mp_set_subcheck_state(sc_value, STATE_CRITICAL);
+		mp_add_subcheck_to_check(&overall, sc_value);
+		mp_exit(overall);
 	}
 
 	if (!is_numeric(row[0])) {
-		die(STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]);
+		xasprintf(&sc_value.output, "query result is not numeric");
+		sc_value = mp_set_subcheck_state(sc_value, STATE_CRITICAL);
+		mp_add_subcheck_to_check(&overall, sc_value);
+		mp_exit(overall);
 	}
 
 	double value = strtod(row[0], NULL);
@@ -147,24 +169,18 @@ int main(int argc, char **argv) {
 		printf("mysql result: %f\n", value);
 	}
 
-	int status = get_status(value, config.my_thresholds);
+	mp_perfdata pd_query_result = perfdata_init();
+	pd_query_result = mp_set_pd_value(pd_query_result, value);
+	pd_query_result = mp_pd_set_thresholds(pd_query_result, config.thresholds);
+	pd_query_result.label = "result";
+	mp_add_perfdata_to_subcheck(&sc_value, pd_query_result);
 
-	if (status == STATE_OK) {
-		printf("QUERY %s: ", _("OK"));
-	} else if (status == STATE_WARNING) {
-		printf("QUERY %s: ", _("WARNING"));
-	} else if (status == STATE_CRITICAL) {
-		printf("QUERY %s: ", _("CRITICAL"));
-	}
-	printf(_("'%s' returned %f | %s"), config.sql_query, value,
-		   fperfdata("result", value, "", config.my_thresholds->warning,
-					 config.my_thresholds->warning ? config.my_thresholds->warning->end : 0,
-					 config.my_thresholds->critical,
-					 config.my_thresholds->critical ? config.my_thresholds->critical->end : 0,
-					 false, 0, false, 0));
-	printf("\n");
+	sc_value = mp_set_subcheck_state(sc_value, mp_get_pd_status(pd_query_result));
+	xasprintf(&sc_value.output, "'%s' returned '%f'", config.sql_query, value);
+
+	mp_add_subcheck_to_check(&overall, sc_value);
 
-	return status;
+	mp_exit(overall);
 }
 
 /* process command-line arguments */
@@ -195,9 +211,6 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) {
 		return result;
 	}
 
-	char *warning = NULL;
-	char *critical = NULL;
-
 	while (true) {
 		int option = 0;
 		int option_char = getopt_long(argc, argv, "hvVP:p:u:d:H:s:q:w:c:f:g:", longopts, &option);
@@ -253,19 +266,25 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) {
 		case 'q':
 			xasprintf(&result.config.sql_query, "%s", optarg);
 			break;
-		case 'w':
-			warning = optarg;
-			break;
-		case 'c':
-			critical = optarg;
-			break;
+		case 'w': {
+			mp_range_parsed tmp = mp_parse_range_string(optarg);
+			if (tmp.error != MP_PARSING_SUCCES) {
+				die(STATE_UNKNOWN, "failed to parse warnign threshold");
+			}
+			result.config.thresholds = mp_thresholds_set_warn(result.config.thresholds, tmp.range);
+		} break;
+		case 'c': {
+			mp_range_parsed tmp = mp_parse_range_string(optarg);
+			if (tmp.error != MP_PARSING_SUCCES) {
+				die(STATE_UNKNOWN, "failed to parse critical threshold");
+			}
+			result.config.thresholds = mp_thresholds_set_crit(result.config.thresholds, tmp.range);
+		} break;
 		case '?': /* help */
 			usage5();
 		}
 	}
 
-	set_thresholds(&result.config.my_thresholds, warning, critical);
-
 	return validate_arguments(result);
 }
 
diff --git a/plugins/check_mysql_query.d/config.h b/plugins/check_mysql_query.d/config.h
index be019160..1c9952e5 100644
--- a/plugins/check_mysql_query.d/config.h
+++ b/plugins/check_mysql_query.d/config.h
@@ -15,7 +15,7 @@ typedef struct {
 	unsigned int db_port;
 
 	char *sql_query;
-	thresholds *my_thresholds;
+	mp_thresholds thresholds;
 } check_mysql_query_config;
 
 check_mysql_query_config check_mysql_query_config_init() {
@@ -30,7 +30,7 @@ check_mysql_query_config check_mysql_query_config_init() {
 		.db_port = MYSQL_PORT,
 
 		.sql_query = NULL,
-		.my_thresholds = NULL,
+		.thresholds = mp_thresholds_init(),
 	};
 	return tmp;
 }
diff --git a/plugins/t/check_mysql_query.t b/plugins/t/check_mysql_query.t
index c30245b2..6de48bf6 100644
--- a/plugins/t/check_mysql_query.t
+++ b/plugins/t/check_mysql_query.t
@@ -54,5 +54,5 @@ like( $result->output, "/No rows returned/", "No rows error message");
 
 $result = NPTest->testCmd("./check_mysql_query -q 'SHOW VARIABLES' -H $mysqlserver $mysql_login_details");
 cmp_ok( $result->return_code, '==', 2, "Data not numeric");
-like( $result->output, "/Is not a numeric/", "Data not numeric error message");
+like( $result->output, "/is not numeric/", "Data not numeric error message");
 



More information about the Commits mailing list