summaryrefslogtreecommitdiffstats
path: root/plugins/check_mysql_query.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_mysql_query.c')
-rw-r--r--plugins/check_mysql_query.c132
1 files changed, 83 insertions, 49 deletions
diff --git a/plugins/check_mysql_query.c b/plugins/check_mysql_query.c
index 5e04a94b..8af378d5 100644
--- a/plugins/check_mysql_query.c
+++ b/plugins/check_mysql_query.c
@@ -29,11 +29,11 @@
29 * 29 *
30 *****************************************************************************/ 30 *****************************************************************************/
31 31
32const char *progname = "check_mysql_query";
33const char *copyright = "1999-2024";
34const 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,12 +42,17 @@ 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
45const char *progname = "check_mysql_query";
46const char *copyright = "1999-2024";
47const char *email = "devel@monitoring-plugins.org";
48
45typedef struct { 49typedef struct {
46 int errorcode; 50 int errorcode;
47 check_mysql_query_config config; 51 check_mysql_query_config config;
48} check_mysql_query_config_wrapper; 52} check_mysql_query_config_wrapper;
49static check_mysql_query_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); 53static check_mysql_query_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
50static check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper /*config_wrapper*/); 54static check_mysql_query_config_wrapper
55 validate_arguments(check_mysql_query_config_wrapper /*config_wrapper*/);
51static void print_help(void); 56static void print_help(void);
52void print_usage(void); 57void print_usage(void);
53 58
@@ -82,26 +87,38 @@ int main(int argc, char **argv) {
82 mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); 87 mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client");
83 } 88 }
84 89
90 mp_check overall = mp_check_init();
91 mp_subcheck sc_connect = mp_subcheck_init();
92
85 /* establish a connection to the server and error checking */ 93 /* establish a connection to the server and error checking */
86 if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, config.db_port, config.db_socket, 0)) { 94 if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db,
95 config.db_port, config.db_socket, 0)) {
96 xasprintf(&sc_connect.output, "query failed: %s", mysql_error(&mysql));
97
87 if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { 98 if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) {
88 die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); 99 sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
89 } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { 100 } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) {
90 die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); 101 sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
91 } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { 102 } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) {
92 die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); 103 sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
93 } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { 104 } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) {
94 die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); 105 sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
95 } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { 106 } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) {
96 die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); 107 sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING);
97 } else { 108 } else {
98 die(STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error(&mysql)); 109 sc_connect = mp_set_subcheck_state(sc_connect, STATE_CRITICAL);
99 } 110 }
111
112 mp_add_subcheck_to_check(&overall, sc_connect);
113 mp_exit(overall);
100 } 114 }
101 115
102 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
103 if (mysql_query(&mysql, config.sql_query) != 0) { 120 if (mysql_query(&mysql, config.sql_query) != 0) {
104 error = strdup(mysql_error(&mysql)); 121 char *error = strdup(mysql_error(&mysql));
105 mysql_close(&mysql); 122 mysql_close(&mysql);
106 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);
107 } 124 }
@@ -109,7 +126,7 @@ int main(int argc, char **argv) {
109 MYSQL_RES *res; 126 MYSQL_RES *res;
110 /* store the result */ 127 /* store the result */
111 if ((res = mysql_store_result(&mysql)) == NULL) { 128 if ((res = mysql_store_result(&mysql)) == NULL) {
112 error = strdup(mysql_error(&mysql)); 129 char *error = strdup(mysql_error(&mysql));
113 mysql_close(&mysql); 130 mysql_close(&mysql);
114 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);
115 } 132 }
@@ -120,17 +137,24 @@ int main(int argc, char **argv) {
120 die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned")); 137 die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned"));
121 } 138 }
122 139
140 mp_subcheck sc_value = mp_subcheck_init();
123 MYSQL_ROW row; 141 MYSQL_ROW row;
124 /* fetch the first row */ 142 /* fetch the first row */
125 if ((row = mysql_fetch_row(res)) == NULL) { 143 if ((row = mysql_fetch_row(res)) == NULL) {
126 error = strdup(mysql_error(&mysql)); 144 xasprintf(&sc_value.output, "fetch row error - %s", mysql_error(&mysql));
127 mysql_free_result(res); 145 mysql_free_result(res);
128 mysql_close(&mysql); 146 mysql_close(&mysql);
129 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);
130 } 151 }
131 152
132 if (!is_numeric(row[0])) { 153 if (!is_numeric(row[0])) {
133 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);
134 } 158 }
135 159
136 double value = strtod(row[0], NULL); 160 double value = strtod(row[0], NULL);
@@ -145,31 +169,37 @@ int main(int argc, char **argv) {
145 printf("mysql result: %f\n", value); 169 printf("mysql result: %f\n", value);
146 } 170 }
147 171
148 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);
149 177
150 if (status == STATE_OK) { 178 sc_value = mp_set_subcheck_state(sc_value, mp_get_pd_status(pd_query_result));
151 printf("QUERY %s: ", _("OK")); 179 xasprintf(&sc_value.output, "'%s' returned '%f'", config.sql_query, value);
152 } else if (status == STATE_WARNING) { 180
153 printf("QUERY %s: ", _("WARNING")); 181 mp_add_subcheck_to_check(&overall, sc_value);
154 } else if (status == STATE_CRITICAL) {
155 printf("QUERY %s: ", _("CRITICAL"));
156 }
157 printf(_("'%s' returned %f | %s"), config.sql_query, value,
158 fperfdata("result", value, "", config.my_thresholds->warning, config.my_thresholds->warning ? config.my_thresholds->warning->end : 0,
159 config.my_thresholds->critical, config.my_thresholds->critical ? config.my_thresholds->critical->end : 0, false, 0, false, 0));
160 printf("\n");
161 182
162 return status; 183 mp_exit(overall);
163} 184}
164 185
165/* process command-line arguments */ 186/* process command-line arguments */
166check_mysql_query_config_wrapper process_arguments(int argc, char **argv) { 187check_mysql_query_config_wrapper process_arguments(int argc, char **argv) {
167 static struct option longopts[] = { 188 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
168 {"hostname", required_argument, 0, 'H'}, {"socket", required_argument, 0, 's'}, {"database", required_argument, 0, 'd'}, 189 {"socket", required_argument, 0, 's'},
169 {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"file", required_argument, 0, 'f'}, 190 {"database", required_argument, 0, 'd'},
170 {"group", required_argument, 0, 'g'}, {"port", required_argument, 0, 'P'}, {"verbose", no_argument, 0, 'v'}, 191 {"username", required_argument, 0, 'u'},
171 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"query", required_argument, 0, 'q'}, 192 {"password", required_argument, 0, 'p'},
172 {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {0, 0, 0, 0}}; 193 {"file", required_argument, 0, 'f'},
194 {"group", required_argument, 0, 'g'},
195 {"port", required_argument, 0, 'P'},
196 {"verbose", no_argument, 0, 'v'},
197 {"version", no_argument, 0, 'V'},
198 {"help", no_argument, 0, 'h'},
199 {"query", required_argument, 0, 'q'},
200 {"warning", required_argument, 0, 'w'},
201 {"critical", required_argument, 0, 'c'},
202 {0, 0, 0, 0}};
173 203
174 check_mysql_query_config_wrapper result = { 204 check_mysql_query_config_wrapper result = {
175 .errorcode = OK, 205 .errorcode = OK,
@@ -181,9 +211,6 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) {
181 return result; 211 return result;
182 } 212 }
183 213
184 char *warning = NULL;
185 char *critical = NULL;
186
187 while (true) { 214 while (true) {
188 int option = 0; 215 int option = 0;
189 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);
@@ -239,23 +266,30 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) {
239 case 'q': 266 case 'q':
240 xasprintf(&result.config.sql_query, "%s", optarg); 267 xasprintf(&result.config.sql_query, "%s", optarg);
241 break; 268 break;
242 case 'w': 269 case 'w': {
243 warning = optarg; 270 mp_range_parsed tmp = mp_parse_range_string(optarg);
244 break; 271 if (tmp.error != MP_PARSING_SUCCES) {
245 case 'c': 272 die(STATE_UNKNOWN, "failed to parse warning threshold");
246 critical = optarg; 273 }
247 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;
248 case '?': /* help */ 283 case '?': /* help */
249 usage5(); 284 usage5();
250 } 285 }
251 } 286 }
252 287
253 set_thresholds(&result.config.my_thresholds, warning, critical);
254
255 return validate_arguments(result); 288 return validate_arguments(result);
256} 289}
257 290
258check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper config_wrapper) { 291check_mysql_query_config_wrapper
292validate_arguments(check_mysql_query_config_wrapper config_wrapper) {
259 if (config_wrapper.config.sql_query == NULL) { 293 if (config_wrapper.config.sql_query == NULL) {
260 usage("Must specify a SQL query to run"); 294 usage("Must specify a SQL query to run");
261 } 295 }