diff options
| -rw-r--r-- | plugins/check_mysql_query.c | 105 | ||||
| -rw-r--r-- | plugins/check_mysql_query.d/config.h | 4 | ||||
| -rw-r--r-- | 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..8af378d5 100644 --- a/plugins/check_mysql_query.c +++ b/plugins/check_mysql_query.c | |||
| @@ -29,11 +29,11 @@ | |||
| 29 | * | 29 | * |
| 30 | *****************************************************************************/ | 30 | *****************************************************************************/ |
| 31 | 31 | ||
| 32 | const char *progname = "check_mysql_query"; | ||
| 33 | const char *copyright = "1999-2024"; | ||
| 34 | const char *email = "devel@monitoring-plugins.org"; | ||
| 35 | |||
| 36 | #include "common.h" | 32 | #include "common.h" |
| 33 | #include "output.h" | ||
| 34 | #include "perfdata.h" | ||
| 35 | #include "states.h" | ||
| 36 | #include "thresholds.h" | ||
| 37 | #include "utils.h" | 37 | #include "utils.h" |
| 38 | #include "utils_base.h" | 38 | #include "utils_base.h" |
| 39 | #include "netutils.h" | 39 | #include "netutils.h" |
| @@ -42,6 +42,10 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 42 | #include <mysql.h> | 42 | #include <mysql.h> |
| 43 | #include <errmsg.h> | 43 | #include <errmsg.h> |
| 44 | 44 | ||
| 45 | const char *progname = "check_mysql_query"; | ||
| 46 | const char *copyright = "1999-2024"; | ||
| 47 | const char *email = "devel@monitoring-plugins.org"; | ||
| 48 | |||
| 45 | typedef struct { | 49 | typedef struct { |
| 46 | int errorcode; | 50 | int errorcode; |
| 47 | check_mysql_query_config config; | 51 | check_mysql_query_config config; |
| @@ -83,27 +87,38 @@ int main(int argc, char **argv) { | |||
| 83 | mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); | 87 | mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); |
| 84 | } | 88 | } |
| 85 | 89 | ||
| 90 | mp_check overall = mp_check_init(); | ||
| 91 | mp_subcheck sc_connect = mp_subcheck_init(); | ||
| 92 | |||
| 86 | /* establish a connection to the server and error checking */ | 93 | /* establish a connection to the server and error checking */ |
| 87 | if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, | 94 | if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, |
| 88 | config.db_port, config.db_socket, 0)) { | 95 | config.db_port, config.db_socket, 0)) { |
| 96 | xasprintf(&sc_connect.output, "query failed: %s", mysql_error(&mysql)); | ||
| 97 | |||
| 89 | if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { | 98 | if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { |
| 90 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 99 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 91 | } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { | 100 | } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { |
| 92 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 101 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 93 | } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { | 102 | } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { |
| 94 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 103 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 95 | } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { | 104 | } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { |
| 96 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 105 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 97 | } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { | 106 | } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { |
| 98 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 107 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 99 | } else { | 108 | } else { |
| 100 | die(STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error(&mysql)); | 109 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_CRITICAL); |
| 101 | } | 110 | } |
| 111 | |||
| 112 | mp_add_subcheck_to_check(&overall, sc_connect); | ||
| 113 | mp_exit(overall); | ||
| 102 | } | 114 | } |
| 103 | 115 | ||
| 104 | char *error = NULL; | 116 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_OK); |
| 117 | xasprintf(&sc_connect.output, "query succeeded"); | ||
| 118 | mp_add_subcheck_to_check(&overall, sc_connect); | ||
| 119 | |||
| 105 | if (mysql_query(&mysql, config.sql_query) != 0) { | 120 | if (mysql_query(&mysql, config.sql_query) != 0) { |
| 106 | error = strdup(mysql_error(&mysql)); | 121 | char *error = strdup(mysql_error(&mysql)); |
| 107 | mysql_close(&mysql); | 122 | mysql_close(&mysql); |
| 108 | die(STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error); | 123 | die(STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error); |
| 109 | } | 124 | } |
| @@ -111,7 +126,7 @@ int main(int argc, char **argv) { | |||
| 111 | MYSQL_RES *res; | 126 | MYSQL_RES *res; |
| 112 | /* store the result */ | 127 | /* store the result */ |
| 113 | if ((res = mysql_store_result(&mysql)) == NULL) { | 128 | if ((res = mysql_store_result(&mysql)) == NULL) { |
| 114 | error = strdup(mysql_error(&mysql)); | 129 | char *error = strdup(mysql_error(&mysql)); |
| 115 | mysql_close(&mysql); | 130 | mysql_close(&mysql); |
| 116 | die(STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error); | 131 | die(STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error); |
| 117 | } | 132 | } |
| @@ -122,17 +137,24 @@ int main(int argc, char **argv) { | |||
| 122 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned")); | 137 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned")); |
| 123 | } | 138 | } |
| 124 | 139 | ||
| 140 | mp_subcheck sc_value = mp_subcheck_init(); | ||
| 125 | MYSQL_ROW row; | 141 | MYSQL_ROW row; |
| 126 | /* fetch the first row */ | 142 | /* fetch the first row */ |
| 127 | if ((row = mysql_fetch_row(res)) == NULL) { | 143 | if ((row = mysql_fetch_row(res)) == NULL) { |
| 128 | error = strdup(mysql_error(&mysql)); | 144 | xasprintf(&sc_value.output, "fetch row error - %s", mysql_error(&mysql)); |
| 129 | mysql_free_result(res); | 145 | mysql_free_result(res); |
| 130 | mysql_close(&mysql); | 146 | mysql_close(&mysql); |
| 131 | die(STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error); | 147 | |
| 148 | sc_value = mp_set_subcheck_state(sc_value, STATE_CRITICAL); | ||
| 149 | mp_add_subcheck_to_check(&overall, sc_value); | ||
| 150 | mp_exit(overall); | ||
| 132 | } | 151 | } |
| 133 | 152 | ||
| 134 | if (!is_numeric(row[0])) { | 153 | if (!is_numeric(row[0])) { |
| 135 | die(STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]); | 154 | xasprintf(&sc_value.output, "query result is not numeric"); |
| 155 | sc_value = mp_set_subcheck_state(sc_value, STATE_CRITICAL); | ||
| 156 | mp_add_subcheck_to_check(&overall, sc_value); | ||
| 157 | mp_exit(overall); | ||
| 136 | } | 158 | } |
| 137 | 159 | ||
| 138 | double value = strtod(row[0], NULL); | 160 | double value = strtod(row[0], NULL); |
| @@ -147,24 +169,18 @@ int main(int argc, char **argv) { | |||
| 147 | printf("mysql result: %f\n", value); | 169 | printf("mysql result: %f\n", value); |
| 148 | } | 170 | } |
| 149 | 171 | ||
| 150 | int status = get_status(value, config.my_thresholds); | 172 | mp_perfdata pd_query_result = perfdata_init(); |
| 173 | pd_query_result = mp_set_pd_value(pd_query_result, value); | ||
| 174 | pd_query_result = mp_pd_set_thresholds(pd_query_result, config.thresholds); | ||
| 175 | pd_query_result.label = "result"; | ||
| 176 | mp_add_perfdata_to_subcheck(&sc_value, pd_query_result); | ||
| 151 | 177 | ||
| 152 | if (status == STATE_OK) { | 178 | sc_value = mp_set_subcheck_state(sc_value, mp_get_pd_status(pd_query_result)); |
| 153 | printf("QUERY %s: ", _("OK")); | 179 | xasprintf(&sc_value.output, "'%s' returned '%f'", config.sql_query, value); |
| 154 | } else if (status == STATE_WARNING) { | 180 | |
| 155 | printf("QUERY %s: ", _("WARNING")); | 181 | mp_add_subcheck_to_check(&overall, sc_value); |
| 156 | } else if (status == STATE_CRITICAL) { | ||
| 157 | printf("QUERY %s: ", _("CRITICAL")); | ||
| 158 | } | ||
| 159 | printf(_("'%s' returned %f | %s"), config.sql_query, value, | ||
| 160 | fperfdata("result", value, "", config.my_thresholds->warning, | ||
| 161 | config.my_thresholds->warning ? config.my_thresholds->warning->end : 0, | ||
| 162 | config.my_thresholds->critical, | ||
| 163 | config.my_thresholds->critical ? config.my_thresholds->critical->end : 0, | ||
| 164 | false, 0, false, 0)); | ||
| 165 | printf("\n"); | ||
| 166 | 182 | ||
| 167 | return status; | 183 | mp_exit(overall); |
| 168 | } | 184 | } |
| 169 | 185 | ||
| 170 | /* process command-line arguments */ | 186 | /* process command-line arguments */ |
| @@ -195,9 +211,6 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) { | |||
| 195 | return result; | 211 | return result; |
| 196 | } | 212 | } |
| 197 | 213 | ||
| 198 | char *warning = NULL; | ||
| 199 | char *critical = NULL; | ||
| 200 | |||
| 201 | while (true) { | 214 | while (true) { |
| 202 | int option = 0; | 215 | int option = 0; |
| 203 | int option_char = getopt_long(argc, argv, "hvVP:p:u:d:H:s:q:w:c:f:g:", longopts, &option); | 216 | 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) { | |||
| 253 | case 'q': | 266 | case 'q': |
| 254 | xasprintf(&result.config.sql_query, "%s", optarg); | 267 | xasprintf(&result.config.sql_query, "%s", optarg); |
| 255 | break; | 268 | break; |
| 256 | case 'w': | 269 | case 'w': { |
| 257 | warning = optarg; | 270 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 258 | break; | 271 | if (tmp.error != MP_PARSING_SUCCES) { |
| 259 | case 'c': | 272 | die(STATE_UNKNOWN, "failed to parse warning threshold"); |
| 260 | critical = optarg; | 273 | } |
| 261 | break; | 274 | result.config.thresholds = mp_thresholds_set_warn(result.config.thresholds, tmp.range); |
| 275 | } break; | ||
| 276 | case 'c': { | ||
| 277 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 278 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 279 | die(STATE_UNKNOWN, "failed to parse critical threshold"); | ||
| 280 | } | ||
| 281 | result.config.thresholds = mp_thresholds_set_crit(result.config.thresholds, tmp.range); | ||
| 282 | } break; | ||
| 262 | case '?': /* help */ | 283 | case '?': /* help */ |
| 263 | usage5(); | 284 | usage5(); |
| 264 | } | 285 | } |
| 265 | } | 286 | } |
| 266 | 287 | ||
| 267 | set_thresholds(&result.config.my_thresholds, warning, critical); | ||
| 268 | |||
| 269 | return validate_arguments(result); | 288 | return validate_arguments(result); |
| 270 | } | 289 | } |
| 271 | 290 | ||
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 { | |||
| 15 | unsigned int db_port; | 15 | unsigned int db_port; |
| 16 | 16 | ||
| 17 | char *sql_query; | 17 | char *sql_query; |
| 18 | thresholds *my_thresholds; | 18 | mp_thresholds thresholds; |
| 19 | } check_mysql_query_config; | 19 | } check_mysql_query_config; |
| 20 | 20 | ||
| 21 | check_mysql_query_config check_mysql_query_config_init() { | 21 | check_mysql_query_config check_mysql_query_config_init() { |
| @@ -30,7 +30,7 @@ check_mysql_query_config check_mysql_query_config_init() { | |||
| 30 | .db_port = MYSQL_PORT, | 30 | .db_port = MYSQL_PORT, |
| 31 | 31 | ||
| 32 | .sql_query = NULL, | 32 | .sql_query = NULL, |
| 33 | .my_thresholds = NULL, | 33 | .thresholds = mp_thresholds_init(), |
| 34 | }; | 34 | }; |
| 35 | return tmp; | 35 | return tmp; |
| 36 | } | 36 | } |
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"); | |||
| 54 | 54 | ||
| 55 | $result = NPTest->testCmd("./check_mysql_query -q 'SHOW VARIABLES' -H $mysqlserver $mysql_login_details"); | 55 | $result = NPTest->testCmd("./check_mysql_query -q 'SHOW VARIABLES' -H $mysqlserver $mysql_login_details"); |
| 56 | cmp_ok( $result->return_code, '==', 2, "Data not numeric"); | 56 | cmp_ok( $result->return_code, '==', 2, "Data not numeric"); |
| 57 | like( $result->output, "/Is not a numeric/", "Data not numeric error message"); | 57 | like( $result->output, "/is not numeric/", "Data not numeric error message"); |
| 58 | 58 | ||
