From b4e103ced82571efbdec9eb33ba042790abd26e3 Mon Sep 17 00:00:00 2001 From: Jan Kunzmann Date: Sun, 4 Nov 2018 22:58:21 +0100 Subject: [PATCH] Mysql select value check --- CHANGELOG.md | 2 + README.md | 7 ++ bin/check-mysql-select-count.rb | 0 bin/check-mysql-select-value.rb | 131 ++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+) mode change 100644 => 100755 bin/check-mysql-select-count.rb create mode 100755 bin/check-mysql-select-value.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index a970a5e..c8778be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins/community/blob/master/HOW_WE_CHANGELOG.md) ## [Unreleased] +### Added +- check-mysql-select-value.rb script (@DrMurx) ## [2.5.1] - 2018-06-21 ### Fixed diff --git a/README.md b/README.md index 929361f..1bcff58 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ * bin/check-mysql-threads.rb * bin/check-mysql-query-result-count.rb * bin/check-mysql-select-count.rb + * bin/check-mysql-select-value.rb * bin/check-mysql-msr-replication-status.rb * bin/metrics-mysql-graphite.rb * bin/metrics-mysql-processes.rb @@ -93,6 +94,11 @@ $ /opt/sensu/embedded/bin/check-mysql-replication-status.rb --host= --ini /opt/sensu/embedded/bin$ /opt/sensu/embedded/bin/ruby check-mysql-select-count.rb --host=localhost --port=3306 --user=collectd --pass=tflypass --socket=/data/mysql.sock --warning 30000 --critical 50000 --query 'SELECT count(*) FROM table t' ``` +**check-mysql-select-value** example +```bash +/opt/sensu/embedded/bin$ /opt/sensu/embedded/bin/ruby check-mysql-select-value.rb --host=localhost --port=3306 --user=collectd --pass=tflypass --socket=/data/mysql.sock --warning 1 --critical 2 --query 'SELECT MyStoredFunction()' +``` + **metrics-mysql-query-result-count** example ```bash /opt/sensu/embedded/bin$ /opt/sensu/embedded/bin/ruby metrics-mysql-query-result-count.rb --host=localhost --port=3306 --user=collectd --pass=tflypass --socket=/data/mysql.sock --query 'SELECT DISTINCT(t.id) FROM table t where t.failed = true' @@ -110,6 +116,7 @@ In keeping with the principle of least privilege you should create a new user wi | check-mysql-innodb-lock.rb | `PROCESS` | | check-mysql-query-result-count.rb | depends on query | | check-mysql-select-count.rb | `SELECT` | +| check-mysql-select-value.rb | `SELECT` | | check-mysql-replication-status.rb | `SUPER` OR `REPLICATION_CLIENT` (the latter is preferable)| | check-mysql-msr-replication-status.rb | `SELECT` | | check-mysql-status.rb | `SELECT` | diff --git a/bin/check-mysql-select-count.rb b/bin/check-mysql-select-count.rb old mode 100644 new mode 100755 diff --git a/bin/check-mysql-select-value.rb b/bin/check-mysql-select-value.rb new file mode 100755 index 0000000..377b8ef --- /dev/null +++ b/bin/check-mysql-select-value.rb @@ -0,0 +1,131 @@ +#!/usr/bin/env ruby +# +# MySQL Select Count Check +# +# Checks the length of a result set from a MySQL query. +# +# Copyright 2017 Andrew Thal to check-mysql-query-result-count.rb +# Modified by Mutsutoshi Yoshimoto 2018 to select count(*) version +# Modified by Jan Kunzmann 2018 to select value version +# +# Released under the same terms as Sensu (the MIT license); see LICENSE +# for details. + +require 'sensu-plugin/check/cli' +require 'mysql' +require 'inifile' + +class MysqlSelectCountCheck < Sensu::Plugin::Check::CLI + option :host, + short: '-h HOST', + long: '--host HOST', + description: 'MySQL Host to connect to', + required: true + + option :port, + short: '-P PORT', + long: '--port PORT', + description: 'MySQL Port to connect to', + proc: proc(&:to_i), + default: 3306 + + option :username, + short: '-u USERNAME', + long: '--user USERNAME', + description: 'MySQL Username' + + option :password, + short: '-p PASSWORD', + long: '--pass PASSWORD', + description: 'MySQL password' + + option :database, + short: '-d DATABASE', + long: '--database DATABASE', + description: 'MySQL database', + required: true + + option :ini, + short: '-i', + long: '--ini VALUE', + description: 'My.cnf ini file' + + option :ini_section, + description: 'Section in my.cnf ini file', + long: '--ini-section VALUE', + default: 'client' + + option :socket, + short: '-S SOCKET', + long: '--socket SOCKET', + description: 'MySQL Unix socket to connect to' + + option :warn, + short: '-w VALUE', + long: '--warning VALUE', + description: 'Warning when query value exceeds threshold', + proc: proc(&:to_f), + required: true + + option :crit, + short: '-c VALUE', + long: '--critical VALUE', + description: 'Critical when query value exceeds threshold', + proc: proc(&:to_f), + required: true + + option :query, + short: '-q SELECT_VALUE_QUERY', + long: '--query SELECT_VALUE_QUERY', + description: 'Query to execute', + required: true + + + def run + if config[:ini] + ini = IniFile.load(config[:ini]) + section = ini[config[:ini_section]] + db_user = section['user'] + db_pass = section['password'] + else + db_user = config[:username] + db_pass = config[:password] + end + + db = Mysql.real_connect(config[:host], db_user, db_pass, config[:database], config[:port], config[:socket]) + + rs = db.query(config[:query]) + fields = rs.fetch_fields + col_name = fields[0].name.capitalize + + value = rs.fetch_row[0].to_f + + if config[:crit] > config[:warn] + beyond = "above" + beneath = "below" + factor = 1.0 + else + beyond = "below" + beneath = "above" + factor = -1.0 + end + + if value * factor >= config[:crit] * factor + critical "#{col_name} #{value} is #{beyond} the CRITICAL limit of #{config[:crit]}" + elsif value * factor >= config[:warn] * factor + warning "#{col_name} #{value} is #{beyond} the WARNING limit of #{config[:warn]}" + else + ok "#{col_name} #{value} is #{beneath} thresholds" + end + + rescue Mysql::Error => e + errstr = "Error code: #{e.errno} Error message: #{e.error}" + critical "#{errstr} SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate') + + rescue StandardError => e + critical "Unhandled exception: #{e}" + + ensure + db.close if db + end +end