1 /******************************************************************************
5 * Program: Mysql plugin for Nagios
7 * Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)
8 * portions (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net)
14 * This plugin is for testing a mysql server.
15 ******************************************************************************/
17 const char *progname
= "check_mysql";
18 const char *revision
= "$Revision$";
19 const char *copyright
= "1999-2006";
20 const char *email
= "nagiosplug-devel@lists.sourceforge.net";
22 #define SLAVERESULTSIZE 70
35 unsigned int db_port
= MYSQL_PORT
;
36 int check_slave
= 0, warn_sec
= 0, crit_sec
= 0;
39 thresholds
*my_threshold
= NULL
;
41 int process_arguments (int, char **);
42 int validate_arguments (void);
43 void print_help (void);
44 void print_usage (void);
47 main (int argc
, char **argv
)
54 /* should be status */
58 char slaveresult
[SLAVERESULTSIZE
];
60 setlocale (LC_ALL
, "");
61 bindtextdomain (PACKAGE
, LOCALEDIR
);
64 if (process_arguments (argc
, argv
) == ERROR
)
65 usage4 (_("Could not parse arguments"));
67 /* initialize mysql */
70 mysql_options(&mysql
,MYSQL_READ_DEFAULT_GROUP
,"client");
72 /* establish a connection to the server and error checking */
73 if (!mysql_real_connect(&mysql
,db_host
,db_user
,db_pass
,db
,db_port
,NULL
,0)) {
74 if (mysql_errno (&mysql
) == CR_UNKNOWN_HOST
)
75 die (STATE_WARNING
, "%s\n", mysql_error (&mysql
));
76 else if (mysql_errno (&mysql
) == CR_VERSION_ERROR
)
77 die (STATE_WARNING
, "%s\n", mysql_error (&mysql
));
78 else if (mysql_errno (&mysql
) == CR_OUT_OF_MEMORY
)
79 die (STATE_WARNING
, "%s\n", mysql_error (&mysql
));
80 else if (mysql_errno (&mysql
) == CR_IPSOCK_ERROR
)
81 die (STATE_WARNING
, "%s\n", mysql_error (&mysql
));
82 else if (mysql_errno (&mysql
) == CR_SOCKET_CREATE_ERROR
)
83 die (STATE_WARNING
, "%s\n", mysql_error (&mysql
));
85 die (STATE_CRITICAL
, "%s\n", mysql_error (&mysql
));
88 /* get the server stats */
89 result
= strdup (mysql_stat (&mysql
));
91 /* error checking once more */
92 if (mysql_error (&mysql
)) {
93 if (mysql_errno (&mysql
) == CR_SERVER_GONE_ERROR
)
94 die (STATE_CRITICAL
, "%s\n", mysql_error (&mysql
));
95 else if (mysql_errno (&mysql
) == CR_SERVER_LOST
)
96 die (STATE_CRITICAL
, "%s\n", mysql_error (&mysql
));
97 else if (mysql_errno (&mysql
) == CR_UNKNOWN_ERROR
)
98 die (STATE_CRITICAL
, "%s\n", mysql_error (&mysql
));
102 /* check the slave status */
103 if (mysql_query (&mysql
, "show slave status") != 0) {
104 error
= strdup(mysql_error(&mysql
));
105 mysql_close (&mysql
);
106 die (STATE_CRITICAL
, _("slave query error: %s\n"), error
);
109 /* store the result */
110 if ( (res
= mysql_store_result (&mysql
)) == NULL
) {
111 error
= strdup(mysql_error(&mysql
));
112 mysql_close (&mysql
);
113 die (STATE_CRITICAL
, _("slave store_result error: %s\n"), error
);
116 /* Check there is some data */
117 if (mysql_num_rows(res
) == 0) {
119 die (STATE_WARNING
, "%s\n", _("No slaves defined"));
122 /* fetch the first row */
123 if ( (row
= mysql_fetch_row (res
)) == NULL
) {
124 error
= strdup(mysql_error(&mysql
));
125 mysql_free_result (res
);
126 mysql_close (&mysql
);
127 die (STATE_CRITICAL
, _("slave fetch row error: %s\n"), error
);
130 if (mysql_field_count (&mysql
) == 12) {
132 snprintf (slaveresult
, SLAVERESULTSIZE
, _("Slave running: %s"), row
[6]);
133 if (strcmp (row
[6], "Yes") != 0) {
134 mysql_free_result (res
);
135 mysql_close (&mysql
);
136 die (STATE_CRITICAL
, "%s\n", slaveresult
);
141 int slave_io_field
= -1 , slave_sql_field
= -1, seconds_behind_field
= -1, i
, num_fields
;
144 num_fields
= mysql_num_fields(res
);
145 fields
= mysql_fetch_fields(res
);
146 for(i
= 0; i
< num_fields
; i
++) {
147 if (strcmp(fields
[i
].name
, "Slave_IO_Running") == 0) {
151 if (strcmp(fields
[i
].name
, "Slave_SQL_Running") == 0) {
155 if (strcmp(fields
[i
].name
, "Seconds_Behind_Master") == 0) {
156 seconds_behind_field
= i
;
160 if ((slave_io_field
< 0) || (slave_sql_field
< 0) || (num_fields
== 0)) {
161 mysql_free_result (res
);
162 mysql_close (&mysql
);
163 die (STATE_CRITICAL
, "Slave status unavailable\n");
166 snprintf (slaveresult
, SLAVERESULTSIZE
, "Slave IO: %s Slave SQL: %s Seconds Behind Master: %s", row
[slave_io_field
], row
[slave_sql_field
], row
[seconds_behind_field
]);
167 if (strcmp (row
[slave_io_field
], "Yes") != 0 || strcmp (row
[slave_sql_field
], "Yes") != 0) {
168 mysql_free_result (res
);
169 mysql_close (&mysql
);
170 die (STATE_CRITICAL
, "%s\n", slaveresult
);
174 if (seconds_behind_field
== -1) {
175 printf("seconds_behind_field not found\n");
177 printf ("seconds_behind_field(index %d)=%s\n", seconds_behind_field
, row
[seconds_behind_field
]);
181 if ((seconds_behind_field
!= -1) && (strcmp (row
[seconds_behind_field
], "NULL") != 0)) {
182 double value
= atof(row
[seconds_behind_field
]);
185 status
= get_status(value
, my_threshold
);
187 if (status
== STATE_WARNING
) {
188 printf("SLOW_SLAVE %s: %s\n", _("WARNING"), slaveresult
);
190 } else if (status
== STATE_CRITICAL
) {
191 printf("SLOW_SLAVE %s: %s\n", _("CRITICAL"), slaveresult
);
192 exit(STATE_CRITICAL
);
197 /* free the result */
198 mysql_free_result (res
);
201 /* close the connection */
202 mysql_close (&mysql
);
204 /* print out the result of stats */
206 printf ("%s %s\n", result
, slaveresult
);
208 printf ("%s\n", result
);
215 /* process command-line arguments */
217 process_arguments (int argc
, char **argv
)
220 char *warning
= NULL
;
221 char *critical
= NULL
;
224 static struct option longopts
[] = {
225 {"hostname", required_argument
, 0, 'H'},
226 {"database", required_argument
, 0, 'd'},
227 {"username", required_argument
, 0, 'u'},
228 {"password", required_argument
, 0, 'p'},
229 {"port", required_argument
, 0, 'P'},
230 {"critical", required_argument
, 0, 'c'},
231 {"warning", required_argument
, 0, 'w'},
232 {"check-slave", no_argument
, 0, 'S'},
233 {"verbose", no_argument
, 0, 'v'},
234 {"version", no_argument
, 0, 'V'},
235 {"help", no_argument
, 0, 'h'},
243 c
= getopt_long (argc
, argv
, "hvVSP:p:u:d:H:c:w:", longopts
, &option
);
245 if (c
== -1 || c
== EOF
)
249 case 'H': /* hostname */
250 if (is_host (optarg
)) {
254 usage2 (_("Invalid hostname/address"), optarg
);
257 case 'd': /* hostname */
260 case 'u': /* username */
263 case 'p': /* authentication information: password */
266 case 'P': /* critical time threshold */
267 db_port
= atoi (optarg
);
270 check_slave
= 1; /* check-slave */
278 case 'V': /* version */
279 print_revision (progname
, revision
);
288 usage2 (_("Unknown argument"), optarg
);
294 set_thresholds(&my_threshold
, warning
, critical
);
298 if (strlen(db_host
) == 0)
299 if (is_host (argv
[c
])) {
303 usage2 (_("Invalid hostname/address"), optarg
);
305 else if (strlen(db_user
) == 0)
307 else if (strlen(db_pass
) == 0)
309 else if (strlen(db
) == 0)
311 else if (is_intnonneg (argv
[c
]))
312 db_port
= atoi (argv
[c
++]);
317 return validate_arguments ();
322 validate_arguments (void)
325 db_user
= strdup("");
328 db_host
= strdup("");
331 db_pass
== strdup("");
344 asprintf (&myport
, "%d", MYSQL_PORT
);
346 print_revision (progname
, revision
);
348 printf (_(COPYRIGHT
), copyright
, email
);
350 printf (_("This program tests connections to a mysql server\n"));
354 printf (_(UT_HELP_VRSN
));
356 printf (_(UT_HOST_PORT
), 'P', myport
);
359 -d, --database=STRING\n\
360 Check database with indicated name\n\
361 -u, --username=STRING\n\
362 Connect using the indicated username\n\
363 -p, --password=STRING\n\
364 Use the indicated password to authenticate the connection\n\
365 ==> IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!! <==\n\
366 Your clear-text password will be visible as a process table entry\n\
368 Check if the slave thread is running properly.\n\
370 Exit with WARNING status if slave server is more then INTEGER seconds behind master\n\
372 Exit with CRITICAL status if slave server is more then INTEGER seconds behind master\n"));
375 There are no required arguments. By default, the local database with\n\
376 a server listening on MySQL standard port %d will be checked\n"), MYSQL_PORT
);
378 printf (_(UT_SUPPORT
));
386 Usage: %s [-d database] [-H host] [-P port] [-u user] [-p password] [-S]\n",