From af337a12e6f084556400fa93c71304ad63f1efa6 Mon Sep 17 00:00:00 2001 From: Igor Pashev Date: Fri, 23 Sep 2016 12:41:01 +0300 Subject: Initial commit --- pkgs/monitoringPlugins/default.nix | 37 ++ pkgs/monitoringPlugins/mysql_check_slave.patch | 591 +++++++++++++++++++++++++ 2 files changed, 628 insertions(+) create mode 100644 pkgs/monitoringPlugins/default.nix create mode 100644 pkgs/monitoringPlugins/mysql_check_slave.patch (limited to 'pkgs/monitoringPlugins') diff --git a/pkgs/monitoringPlugins/default.nix b/pkgs/monitoringPlugins/default.nix new file mode 100644 index 0000000..d0f554e --- /dev/null +++ b/pkgs/monitoringPlugins/default.nix @@ -0,0 +1,37 @@ +{ stdenv, fetchurl +, autoreconfHook +, procps, perl +, fping, openssh, bind +, mariadb +, openssl +}: + +stdenv.mkDerivation rec { + version = "2.1.2"; + name = "monitoring-plugins-${version}"; + src = fetchurl { + url = "https://github.com/monitoring-plugins/monitoring-plugins/archive/v${version}.tar.gz"; + sha256 = "0mgs59326yzvx92pdqmn671d40czixd7k60dvsbz89ah2r96vps7"; + }; + + buildInputs = [ + autoreconfHook + procps perl + fping openssh bind + mariadb.lib + openssl + ]; + + patches = [ + ./mysql_check_slave.patch + ]; + + configurePhase = '' + ./configure \ + --prefix=$out \ + --disable-nls \ + --with-ping-command="/var/setuid-wrappers/ping -n -U -w %d -c %d %s" \ + --with-ping6-command="/var/setuid-wrappers/ping6 -n -U -w %d -c %d %s" \ + --with-trusted-path=/var/setuid-wrappers:/run/current-system/sw/bin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin + ''; +} diff --git a/pkgs/monitoringPlugins/mysql_check_slave.patch b/pkgs/monitoringPlugins/mysql_check_slave.patch new file mode 100644 index 0000000..09098f6 --- /dev/null +++ b/pkgs/monitoringPlugins/mysql_check_slave.patch @@ -0,0 +1,591 @@ +commit f1623c0309b35b35a3ff8cab447e9ab06b3497f8 +Author: Igor Pashev +Date: Sun Jan 3 10:59:51 2016 +0300 + + Added check_mysql_slave + + Supports MariaDB multi-source replication + +diff --git a/configure.ac b/configure.ac +index 0a554af..f1a7aac 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -357,7 +357,7 @@ if test $with_mysql = "no" ; then + AC_MSG_WARN([Skipping mysql plugin]) + AC_MSG_WARN([install mysql client libs to compile this plugin (see REQUIREMENTS).]) + else +- EXTRAS="$EXTRAS check_mysql\$(EXEEXT) check_mysql_query\$(EXEEXT)" ++ EXTRAS="$EXTRAS check_mysql\$(EXEEXT) check_mysql_query\$(EXEEXT) check_mysql_slave\$(EXEEXT)" + MYSQLINCLUDE="$np_mysql_include" + MYSQLLIBS="$np_mysql_libs" + MYSQLCFLAGS="$np_mysql_cflags" +diff --git a/plugins/Makefile.am b/plugins/Makefile.am +index 0ddf9bd..fdcb154 100644 +--- a/plugins/Makefile.am ++++ b/plugins/Makefile.am +@@ -38,7 +38,7 @@ check_tcp_programs = check_ftp check_imap check_nntp check_pop \ + EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ + check_swap check_fping check_ldap check_game check_dig \ + check_nagios check_by_ssh check_dns check_nt check_ide_smart \ +- check_procs check_mysql_query check_apt check_dbi ++ check_procs check_mysql_query check_apt check_dbi check_mysql_slave + + EXTRA_DIST = t tests + +@@ -85,6 +85,9 @@ check_mrtgtraf_LDADD = $(BASEOBJS) + check_mysql_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) + check_mysql_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) + check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS) ++check_mysql_slave_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) ++check_mysql_slave_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) ++check_mysql_slave_LDADD = $(NETLIBS) $(MYSQLLIBS) + check_mysql_query_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) + check_mysql_query_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) + check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) +diff --git a/plugins/check_mysql_slave.c b/plugins/check_mysql_slave.c +new file mode 100644 +index 0000000..bc402e0 +--- /dev/null ++++ b/plugins/check_mysql_slave.c +@@ -0,0 +1,541 @@ ++/***************************************************************************** ++* ++* Monitoring check_mysql plugin ++* ++* License: GPL ++* Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) ++* Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) ++* Copyright (c) 1999-2011 Monitoring Plugins Development Team ++* Copyright (c) 2016 Zalora South East Asia Pte. Ltd ++* ++* Description: ++* ++* This file contains the check_mysql_slave plugin ++* ++* This program tests MySQL/MariaDB slaves ++* ++* ++* This program is free software: you can redistribute it and/or modify ++* it under the terms of the GNU General Public License as published by ++* the Free Software Foundation, either version 3 of the License, or ++* (at your option) any later version. ++* ++* This program is distributed in the hope that it will be useful, ++* but WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++* GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License ++* along with this program. If not, see . ++* ++* ++*****************************************************************************/ ++ ++const char *progname = "check_mysql_slave"; ++const char *copyright = "1999-2016"; ++const char *email = "devel@monitoring-plugins.org"; ++ ++#define SLAVERESULTSIZE 256 ++ ++#include "common.h" ++#include "utils.h" ++#include "utils_base.h" ++#include "netutils.h" ++ ++#include ++#include ++#include ++ ++char *db_user = NULL; ++char *db_host = NULL; ++char *db_socket = NULL; ++char *db_pass = NULL; ++char *ca_cert = NULL; ++char *ca_dir = NULL; ++char *cert = NULL; ++char *key = NULL; ++char *ciphers = NULL; ++bool ssl = false; ++char *opt_file = NULL; ++char *opt_group = NULL; ++unsigned int db_port = MYSQL_PORT; ++int warn_sec = 0, crit_sec = 0; ++char *connection_name = NULL; ++char *query; ++ ++static double warning_time = 0; ++static double critical_time = 0; ++ ++thresholds *my_threshold = NULL; ++ ++int process_arguments (int, char **); ++int validate_arguments (void); ++void print_help (void); ++void print_usage (void); ++ ++int ++main (int argc, char **argv) ++{ ++ ++ MYSQL mysql; ++ MYSQL_RES *res; ++ MYSQL_ROW row; ++ char *perf; ++ perf = strdup (""); ++ ++ char *error = NULL; ++ char slaveresult[SLAVERESULTSIZE]; ++ ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ /* Parse extra opts if any */ ++ argv = np_extra_opts (&argc, argv, progname); ++ ++ if (process_arguments (argc, argv) == ERROR) ++ usage4 (_("Could not parse arguments")); ++ ++ /* initialize mysql */ ++ mysql_init (&mysql); ++ ++ if (opt_file != NULL) ++ mysql_options (&mysql, MYSQL_READ_DEFAULT_FILE, opt_file); ++ ++ if (opt_group != NULL) ++ mysql_options (&mysql, MYSQL_READ_DEFAULT_GROUP, opt_group); ++ else ++ mysql_options (&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); ++ ++ if (ssl) ++ mysql_ssl_set (&mysql, key, cert, ca_cert, ca_dir, ciphers); ++ ++ if (!mysql_real_connect ++ (&mysql, db_host, db_user, db_pass, "", db_port, db_socket, 0)) ++ { ++ if (mysql_errno (&mysql) == CR_UNKNOWN_HOST) ++ die (STATE_WARNING, "%s\n", mysql_error (&mysql)); ++ else if (mysql_errno (&mysql) == CR_VERSION_ERROR) ++ die (STATE_WARNING, "%s\n", mysql_error (&mysql)); ++ else if (mysql_errno (&mysql) == CR_OUT_OF_MEMORY) ++ die (STATE_WARNING, "%s\n", mysql_error (&mysql)); ++ else if (mysql_errno (&mysql) == CR_IPSOCK_ERROR) ++ die (STATE_WARNING, "%s\n", mysql_error (&mysql)); ++ else if (mysql_errno (&mysql) == CR_SOCKET_CREATE_ERROR) ++ die (STATE_WARNING, "%s\n", mysql_error (&mysql)); ++ else ++ die (STATE_CRITICAL, "%s\n", mysql_error (&mysql)); ++ } ++ ++ if (connection_name != NULL && strcmp (connection_name, "") != 0) ++ { ++ xasprintf (&query, "show slave '%s' status", connection_name); ++ } ++ else ++ { ++ xasprintf (&query, "show slave status"); ++ } ++ ++ if (mysql_query (&mysql, query) != 0) ++ { ++ error = strdup (mysql_error (&mysql)); ++ mysql_close (&mysql); ++ die (STATE_CRITICAL, _("slave query error: %s\n"), error); ++ } ++ ++ if ((res = mysql_store_result (&mysql)) == NULL) ++ { ++ error = strdup (mysql_error (&mysql)); ++ mysql_close (&mysql); ++ die (STATE_CRITICAL, _("slave store_result error: %s\n"), error); ++ } ++ ++ /* Check there is some data */ ++ if (mysql_num_rows (res) == 0) ++ { ++ mysql_close (&mysql); ++ die (STATE_WARNING, "%s\n", _("No slaves defined")); ++ } ++ ++ /* fetch the first row */ ++ if ((row = mysql_fetch_row (res)) == NULL) ++ { ++ error = strdup (mysql_error (&mysql)); ++ mysql_free_result (res); ++ mysql_close (&mysql); ++ die (STATE_CRITICAL, _("slave fetch row error: %s\n"), error); ++ } ++ ++ const char *last_io_error = NULL; ++ const char *last_sql_error = NULL; ++ const char *seconds_behind_master = NULL; ++ const char *slave_io = NULL; ++ const char *slave_sql = NULL; ++ MYSQL_FIELD *fields; ++ ++ int i, num_fields; ++ num_fields = mysql_num_fields (res); ++ fields = mysql_fetch_fields (res); ++ for (i = 0; i < num_fields; i++) ++ { ++ if (strcmp (fields[i].name, "Last_IO_Error") == 0 && row[i] ++ && row[i][0]) ++ { ++ last_io_error = row[i]; ++ continue; ++ } ++ if (strcmp (fields[i].name, "Last_SQL_Error") == 0 && row[i] ++ && row[i][0]) ++ { ++ last_sql_error = row[i]; ++ continue; ++ } ++ if (strcmp (fields[i].name, "Slave_IO_Running") == 0) ++ { ++ slave_io = row[i]; ++ continue; ++ } ++ if (strcmp (fields[i].name, "Slave_SQL_Running") == 0) ++ { ++ slave_sql = row[i]; ++ continue; ++ } ++ if (strcmp (fields[i].name, "Seconds_Behind_Master") == 0) ++ { ++ seconds_behind_master = row[i]; ++ continue; ++ } ++ } ++ ++ /* Check if slave status is available */ ++ if ((slave_io == NULL) || (slave_sql == NULL)) ++ { ++ mysql_free_result (res); ++ mysql_close (&mysql); ++ die (STATE_CRITICAL, "Slave status unavailable\n"); ++ } ++ ++ const char *last_error; ++ if (last_sql_error) ++ last_error = last_sql_error; ++ else if (last_io_error) ++ last_error = last_io_error; ++ else ++ last_error = NULL; ++ ++ if ((seconds_behind_master == NULL) ++ || (strcmp (seconds_behind_master, "NULL") == 0)) ++ seconds_behind_master = "N/A"; ++ ++ /* Save slave status in slaveresult */ ++ snprintf (slaveresult, SLAVERESULTSIZE, ++ "Slave IO: %s, Slave SQL: %s, %s: %s", ++ slave_io, slave_sql, ++ (last_error ? "Last Error" : "Seconds Behind Master"), ++ (last_error ? last_error : seconds_behind_master)); ++ ++ if (strcmp (slave_io, "Yes") != 0 || strcmp (slave_sql, "Yes") != 0) ++ { ++ mysql_free_result (res); ++ mysql_close (&mysql); ++ if (last_io_error || last_sql_error) ++ { ++ die (STATE_CRITICAL, "%s\n", slaveresult); ++ } ++ else ++ { ++ die (STATE_WARNING, "%s\n", slaveresult); ++ }; ++ } ++ ++ /* Check Seconds Behind against threshold */ ++ if (strcmp (seconds_behind_master, "N/A") != 0) ++ { ++ double value = atof (seconds_behind_master); ++ int status; ++ ++ status = get_status (value, my_threshold); ++ ++ xasprintf (&perf, "%s %s", perf, ++ fperfdata ("lag", value, "s", TRUE, ++ (double) warning_time, TRUE, ++ (double) critical_time, FALSE, 0, FALSE, 0)); ++ ++ if (status == STATE_WARNING) ++ { ++ printf ("LAG %s: %s|%s\n", _("WARNING"), slaveresult, perf); ++ exit (STATE_WARNING); ++ } ++ else if (status == STATE_CRITICAL) ++ { ++ printf ("LAG %s: %s|%s\n", _("CRITICAL"), slaveresult, perf); ++ exit (STATE_CRITICAL); ++ } ++ } ++ ++ mysql_free_result (res); ++ mysql_close (&mysql); ++ ++ printf ("%s|%s\n", slaveresult, perf); ++ return STATE_OK; ++} ++ ++ ++int ++process_arguments (int argc, char **argv) ++{ ++ int c; ++ char *warning = NULL; ++ char *critical = NULL; ++ ++ int option = 0; ++ static struct option longopts[] = { ++ {"ca-cert", optional_argument, 0, 'C'}, ++ {"ca-dir", required_argument, 0, 'D'}, ++ {"cert", required_argument, 0, 'a'}, ++ {"ciphers", required_argument, 0, 'L'}, ++ {"connection-name", required_argument, 0, 'N'}, ++ {"critical", required_argument, 0, 'c'}, ++ {"file", required_argument, 0, 'f'}, ++ {"group", required_argument, 0, 'g'}, ++ {"help", no_argument, 0, 'h'}, ++ {"hostname", required_argument, 0, 'H'}, ++ {"key", required_argument, 0, 'k'}, ++ {"password", required_argument, 0, 'p'}, ++ {"port", required_argument, 0, 'P'}, ++ {"socket", required_argument, 0, 's'}, ++ {"ssl", no_argument, 0, 'l'}, ++ {"username", required_argument, 0, 'u'}, ++ {"version", no_argument, 0, 'V'}, ++ {"warning", required_argument, 0, 'w'}, ++ {0, 0, 0, 0} ++ }; ++ ++ if (argc < 1) ++ return ERROR; ++ ++ while (1) ++ { ++ c = ++ getopt_long (argc, argv, "hlVnSP:p:u:H:s:c:w:a:k:C:D:L:f:g:N:", ++ longopts, &option); ++ ++ if (c == -1 || c == EOF) ++ break; ++ ++ switch (c) ++ { ++ case 'H': /* hostname */ ++ if (is_host (optarg)) ++ { ++ db_host = optarg; ++ } ++ else ++ { ++ usage2 (_("Invalid hostname/address"), optarg); ++ } ++ break; ++ case 's': /* socket */ ++ db_socket = optarg; ++ break; ++ case 'N': ++ connection_name = optarg; ++ break; ++ case 'l': ++ ssl = true; ++ break; ++ case 'C': ++ ca_cert = optarg; ++ break; ++ case 'a': ++ cert = optarg; ++ break; ++ case 'k': ++ key = optarg; ++ break; ++ case 'D': ++ ca_dir = optarg; ++ break; ++ case 'L': ++ ciphers = optarg; ++ break; ++ case 'u': /* username */ ++ db_user = optarg; ++ break; ++ case 'p': /* authentication information: password */ ++ db_pass = strdup (optarg); ++ ++ /* Delete the password from process list */ ++ while (*optarg != '\0') ++ { ++ *optarg = 'X'; ++ optarg++; ++ } ++ break; ++ case 'f': /* client options file */ ++ opt_file = optarg; ++ break; ++ case 'g': /* client options group */ ++ opt_group = optarg; ++ break; ++ case 'P': /* critical time threshold */ ++ db_port = atoi (optarg); ++ break; ++ case 'w': ++ warning = optarg; ++ warning_time = strtod (warning, NULL); ++ break; ++ case 'c': ++ critical = optarg; ++ critical_time = strtod (critical, NULL); ++ break; ++ case 'V': /* version */ ++ print_revision (progname, NP_VERSION); ++ exit (STATE_OK); ++ case 'h': /* help */ ++ print_help (); ++ exit (STATE_OK); ++ case '?': /* help */ ++ usage5 (); ++ } ++ } ++ ++ c = optind; ++ ++ set_thresholds (&my_threshold, warning, critical); ++ ++ while (argc > c) ++ { ++ ++ if (db_host == NULL) ++ if (is_host (argv[c])) ++ { ++ db_host = argv[c++]; ++ } ++ else ++ { ++ usage2 (_("Invalid hostname/address"), argv[c]); ++ } ++ else if (db_user == NULL) ++ db_user = argv[c++]; ++ else if (db_pass == NULL) ++ db_pass = argv[c++]; ++ else if (is_intnonneg (argv[c])) ++ db_port = atoi (argv[c++]); ++ else ++ break; ++ } ++ ++ return validate_arguments (); ++} ++ ++ ++int ++validate_arguments (void) ++{ ++ if (db_user == NULL) ++ db_user = strdup (""); ++ ++ if (db_host == NULL) ++ db_host = strdup (""); ++ ++ return OK; ++} ++ ++ ++void ++print_help (void) ++{ ++ char *myport; ++ xasprintf (&myport, "%d", MYSQL_PORT); ++ ++ print_revision (progname, NP_VERSION); ++ ++ printf (_(COPYRIGHT), copyright, email); ++ ++ printf ("%s\n", _("This program tests MySQL/MariaDB slaves")); ++ ++ printf ("\n\n"); ++ ++ print_usage (); ++ ++ printf (UT_HELP_VRSN); ++ printf (UT_EXTRA_OPTS); ++ ++ printf (UT_HOST_PORT, 'P', myport); ++ ++ printf (" %s\n", "-s, --socket=STRING"); ++ printf (" %s\n", ++ _("Use the specified socket (has no effect if -H is used)")); ++ ++ printf (" %s\n", "-f, --file=STRING"); ++ printf (" %s\n", _("Read from the specified client options file")); ++ printf (" %s\n", "-g, --group=STRING"); ++ printf (" %s\n", _("Use a client options group")); ++ printf (" %s\n", "-u, --username=STRING"); ++ printf (" %s\n", _("Connect using the indicated username")); ++ printf (" %s\n", "-p, --password=STRING"); ++ printf (" %s\n", ++ _("Use the indicated password to authenticate the connection")); ++ printf (" ==> %s <==\n", ++ _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); ++ printf (" %s\n", ++ _ ++ ("Your clear-text password could be visible as a process table entry")); ++ printf (" %s\n", "-N, --connection-name"); ++ printf (" %s\n", _("Connection name if using multi-source replication")); ++ ++ printf (" %s\n", "-w, --warning"); ++ printf (" %s\n", ++ _ ++ ("Exit with WARNING status if slave server is more than INTEGER seconds")); ++ printf (" %s\n", _("behind master")); ++ printf (" %s\n", "-c, --critical"); ++ printf (" %s\n", ++ _ ++ ("Exit with CRITICAL status if slave server is more then INTEGER seconds")); ++ printf (" %s\n", _("behind master")); ++ printf (" %s\n", "-l, --ssl"); ++ printf (" %s\n", _("Use ssl encryptation")); ++ printf (" %s\n", "-C, --ca-cert=STRING"); ++ printf (" %s\n", _("Path to CA signing the cert")); ++ printf (" %s\n", "-a, --cert=STRING"); ++ printf (" %s\n", _("Path to SSL certificate")); ++ printf (" %s\n", "-k, --key=STRING"); ++ printf (" %s\n", _("Path to private SSL key")); ++ printf (" %s\n", "-D, --ca-dir=STRING"); ++ printf (" %s\n", _("Path to CA directory")); ++ printf (" %s\n", "-L, --ciphers=STRING"); ++ printf (" %s\n", _("List of valid SSL ciphers")); ++ ++ ++ printf ("\n"); ++ printf (" %s\n", ++ _ ++ ("There are no required arguments. By default, the local database is checked")); ++ printf (" %s\n", ++ _ ++ ("using the default unix socket. You can force TCP on localhost by using an")); ++ printf (" %s\n", ++ _("IP address or FQDN ('localhost' will use the socket as well).")); ++ ++ printf ("\n"); ++ printf ("%s\n", _("Notes:")); ++ printf (" %s\n", ++ _ ++ ("You must specify -p with an empty string to force an empty password,")); ++ printf (" %s\n", _("overriding any my.cnf settings.")); ++ ++ printf (UT_SUPPORT); ++} ++ ++ ++void ++print_usage (void) ++{ ++ printf ("%s\n", _("Usage:")); ++ printf (" %s [-H host] [-P port] [-s socket]\n", progname); ++ printf (" [-u user] [-p password] [-S] [-l] [-a cert] [-k key]\n"); ++ printf ++ (" [-C ca-cert] [-D ca-dir] [-L ciphers] [-f optfile] [-g group]\n"); ++} -- cgit v1.2.3