Back to index

nagios-plugins  1.4.16
check_mysql_query.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * 
00003 * Nagios check_mysql_query plugin
00004 * 
00005 * License: GPL
00006 * Copyright (c) 2006-2009 Nagios Plugins Development Team
00007 * Original code from check_mysql, copyright 1999 Didi Rieder
00008 * 
00009 * Description:
00010 * 
00011 * This file contains the check_mysql_query plugin
00012 * 
00013 * This plugin is for running arbitrary SQL and checking the results
00014 * 
00015 * 
00016 * This program is free software: you can redistribute it and/or modify
00017 * it under the terms of the GNU General Public License as published by
00018 * the Free Software Foundation, either version 3 of the License, or
00019 * (at your option) any later version.
00020 * 
00021 * This program is distributed in the hope that it will be useful,
00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 * GNU General Public License for more details.
00025 * 
00026 * You should have received a copy of the GNU General Public License
00027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00028 * 
00029 * 
00030 *****************************************************************************/
00031 
00032 const char *progname = "check_mysql_query";
00033 const char *copyright = "1999-2007";
00034 const char *email = "nagiosplug-devel@lists.sourceforge.net";
00035 
00036 #include "common.h"
00037 #include "utils.h"
00038 #include "utils_base.h"
00039 #include "netutils.h"
00040 
00041 #include <mysql.h>
00042 #include <errmsg.h>
00043 
00044 char *db_user = NULL;
00045 char *db_host = NULL;
00046 char *db_socket = NULL;
00047 char *db_pass = NULL;
00048 char *db = NULL;
00049 unsigned int db_port = MYSQL_PORT;
00050 
00051 int process_arguments (int, char **);
00052 int validate_arguments (void);
00053 void print_help (void);
00054 void print_usage (void);
00055 
00056 char *sql_query = NULL;
00057 int verbose = 0;
00058 thresholds *my_thresholds = NULL;
00059 
00060 
00061 int
00062 main (int argc, char **argv)
00063 {
00064 
00065        MYSQL mysql;
00066        MYSQL_RES *res;
00067        MYSQL_ROW row;
00068        
00069        double value;
00070        char *error = NULL;
00071        int status;
00072 
00073        setlocale (LC_ALL, "");
00074        bindtextdomain (PACKAGE, LOCALEDIR);
00075        textdomain (PACKAGE);
00076 
00077        /* Parse extra opts if any */
00078        argv=np_extra_opts (&argc, argv, progname);
00079 
00080        if (process_arguments (argc, argv) == ERROR)
00081               usage4 (_("Could not parse arguments"));
00082 
00083        /* initialize mysql  */
00084        mysql_init (&mysql);
00085 
00086        mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");
00087 
00088        /* establish a connection to the server and error checking */
00089        if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) {
00090               if (mysql_errno (&mysql) == CR_UNKNOWN_HOST)
00091                      die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
00092               else if (mysql_errno (&mysql) == CR_VERSION_ERROR)
00093                      die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
00094               else if (mysql_errno (&mysql) == CR_OUT_OF_MEMORY)
00095                      die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
00096               else if (mysql_errno (&mysql) == CR_IPSOCK_ERROR)
00097                      die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
00098               else if (mysql_errno (&mysql) == CR_SOCKET_CREATE_ERROR)
00099                      die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
00100               else
00101                      die (STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error (&mysql));
00102        }
00103 
00104        if (mysql_query (&mysql, sql_query) != 0) {
00105               error = strdup(mysql_error(&mysql));
00106               mysql_close (&mysql);
00107               die (STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error);
00108        }
00109 
00110        /* store the result */
00111        if ( (res = mysql_store_result (&mysql)) == NULL) {
00112               error = strdup(mysql_error(&mysql));
00113               mysql_close (&mysql);
00114               die (STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error);
00115        }
00116 
00117        /* Check there is some data */
00118        if (mysql_num_rows(res) == 0) {
00119               mysql_close(&mysql);
00120               die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned"));
00121        }
00122 
00123        /* fetch the first row */
00124        if ( (row = mysql_fetch_row (res)) == NULL) {
00125               error = strdup(mysql_error(&mysql));
00126               mysql_free_result (res);
00127               mysql_close (&mysql);
00128               die (STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error);
00129        }
00130 
00131        /* free the result */
00132        mysql_free_result (res);
00133 
00134        /* close the connection */
00135        mysql_close (&mysql);
00136 
00137        if (! is_numeric(row[0])) {
00138               die (STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]);
00139        }
00140 
00141        value = strtod(row[0], NULL);
00142 
00143        if (verbose >= 3)
00144               printf("mysql result: %f\n", value);
00145 
00146        status = get_status(value, my_thresholds);
00147 
00148        if (status == STATE_OK) {
00149               printf("QUERY %s: ", _("OK"));
00150        } else if (status == STATE_WARNING) {
00151               printf("QUERY %s: ", _("WARNING"));
00152        } else if (status == STATE_CRITICAL) {
00153               printf("QUERY %s: ", _("CRITICAL"));
00154        }
00155        printf(_("'%s' returned %f"), sql_query, value);
00156        printf("\n");
00157 
00158        return status;
00159 }
00160 
00161 
00162 /* process command-line arguments */
00163 int
00164 process_arguments (int argc, char **argv)
00165 {
00166        int c;
00167        char *warning = NULL;
00168        char *critical = NULL;
00169 
00170        int option = 0;
00171        static struct option longopts[] = {
00172               {"hostname", required_argument, 0, 'H'},
00173               {"socket", required_argument, 0, 's'},
00174               {"database", required_argument, 0, 'd'},
00175               {"username", required_argument, 0, 'u'},
00176               {"password", required_argument, 0, 'p'},
00177               {"port", required_argument, 0, 'P'},
00178               {"verbose", no_argument, 0, 'v'},
00179               {"version", no_argument, 0, 'V'},
00180               {"help", no_argument, 0, 'h'},
00181               {"query", required_argument, 0, 'q'},
00182               {"warning", required_argument, 0, 'w'},
00183               {"critical", required_argument, 0, 'c'},
00184               {0, 0, 0, 0}
00185        };
00186 
00187        if (argc < 1)
00188               return ERROR;
00189 
00190        while (1) {
00191               c = getopt_long (argc, argv, "hvVP:p:u:d:H:s:q:w:c:", longopts, &option);
00192 
00193               if (c == -1 || c == EOF)
00194                      break;
00195 
00196               switch (c) {
00197               case 'H':                                                             /* hostname */
00198                      if (is_host (optarg)) {
00199                             db_host = optarg;
00200                      }
00201                      else {
00202                             usage2 (_("Invalid hostname/address"), optarg);
00203                      }
00204                      break;
00205               case 's':                                                             /* socket */
00206                      db_socket = optarg;
00207                      break;
00208               case 'd':                                                             /* database */
00209                      db = optarg;
00210                      break;
00211               case 'u':                                                             /* username */
00212                      db_user = optarg;
00213                      break;
00214               case 'p':                                                             /* authentication information: password */
00215                      db_pass = strdup(optarg);
00216 
00217                      /* Delete the password from process list */
00218                      while (*optarg != '\0') {
00219                             *optarg = 'X';
00220                             optarg++;
00221                      }
00222                      break;
00223               case 'P':                                                             /* critical time threshold */
00224                      db_port = atoi (optarg);
00225                      break;
00226               case 'v':
00227                      verbose++;
00228                      break;
00229               case 'V':                                                             /* version */
00230                      print_revision (progname, NP_VERSION);
00231                      exit (STATE_OK);
00232               case 'h':                                                             /* help */
00233                      print_help ();
00234                      exit (STATE_OK);
00235               case 'q':
00236                      asprintf(&sql_query, "%s", optarg);
00237                      break;
00238               case 'w':
00239                      warning = optarg;
00240                      break;
00241               case 'c':
00242                      critical = optarg;
00243                      break;
00244               case '?':                                                             /* help */
00245                      usage5 ();
00246               }
00247        }
00248 
00249        c = optind;
00250 
00251        set_thresholds(&my_thresholds, warning, critical);
00252 
00253        return validate_arguments ();
00254 }
00255 
00256 
00257 int
00258 validate_arguments (void)
00259 {
00260        if (sql_query == NULL)
00261               usage("Must specify a SQL query to run");
00262 
00263        if (db_user == NULL)
00264               db_user = strdup("");
00265 
00266        if (db_host == NULL)
00267               db_host = strdup("");
00268 
00269        if (db == NULL)
00270               db = strdup("");
00271 
00272        return OK;
00273 }
00274 
00275 
00276 void
00277 print_help (void)
00278 {
00279        char *myport;
00280        asprintf (&myport, "%d", MYSQL_PORT);
00281 
00282        print_revision (progname, NP_VERSION);
00283 
00284        printf (_(COPYRIGHT), copyright, email);
00285 
00286        printf ("%s\n", _("This program checks a query result against threshold levels"));
00287 
00288   printf ("\n\n");
00289 
00290        print_usage ();
00291 
00292        printf (UT_HELP_VRSN);
00293        printf (UT_EXTRA_OPTS);
00294        printf (" -q, --query=STRING\n");
00295        printf ("    %s\n", _("SQL query to run. Only first column in first row will be read"));
00296        printf (UT_WARN_CRIT_RANGE);
00297        printf (UT_HOST_PORT, 'P', myport);
00298        printf (" %s\n", "-s, --socket=STRING");
00299        printf ("    %s\n", _("Use the specified socket (has no effect if -H is used)"));
00300        printf (" -d, --database=STRING\n");
00301        printf ("    %s\n", _("Database to check"));
00302        printf (" -u, --username=STRING\n");
00303        printf ("    %s\n", _("Username to login with"));
00304        printf (" -p, --password=STRING\n");
00305        printf ("    %s\n", _("Password to login with"));
00306        printf ("    ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!"));
00307        printf ("    %s\n", _("Your clear-text password could be visible as a process table entry"));
00308 
00309        printf ("\n");
00310        printf (" %s\n", _("A query is required. The result from the query should be numeric."));
00311        printf (" %s\n", _("For extra security, create a user with minimal access."));
00312 
00313        printf ("\n");
00314        printf ("%s\n", _("Notes:"));
00315        printf (" %s\n", _("You must specify -p with an empty string to force an empty password,"));
00316        printf (" %s\n", _("overriding any my.cnf settings."));
00317 
00318        printf (UT_SUPPORT);
00319 }
00320 
00321 
00322 void
00323 print_usage (void)
00324 {
00325   printf ("%s\n", _("Usage:"));
00326   printf (" %s -q SQL_query [-w warn] [-c crit] [-H host] [-P port] [-s socket]\n",progname);
00327   printf ("       [-d database] [-u user] [-p password]\n");
00328 }