bin/check-mysql-disk.rb
#!/usr/bin/env ruby
# frozen_string_literal: false
#
# MySQL Disk Usage Check
# ===
#
# Copyright 2011 Sonian, Inc <chefs@sonian.net>
#
# Released under the same terms as Sensu (the MIT license); see LICENSE
# for details.
#
# Check the size of the database and compare to crit and warn thresholds
require 'sensu-plugin/check/cli'
require 'mysql'
require 'inifile'
class CheckMysqlDisk < Sensu::Plugin::Check::CLI
option :host,
short: '-h',
long: '--host=VALUE',
description: 'Database host'
option :user,
short: '-u',
long: '--username=VALUE',
description: 'Database username'
option :pass,
short: '-p',
long: '--password=VALUE',
description: 'Database password'
option :ini,
description: 'My.cnf ini file',
short: '-i',
long: '--ini VALUE'
option :ini_section,
description: 'Section in my.cnf ini file',
long: '--ini-section VALUE',
default: 'client'
option :size,
short: '-s',
long: '--size=VALUE',
description: 'Database size',
proc: proc(&:to_f),
required: true
option :warn,
short: '-w',
long: '--warning=VALUE',
description: 'Warning threshold',
proc: proc(&:to_f),
default: 85
option :crit,
short: '-c',
long: '--critical=VALUE',
description: 'Critical threshold',
proc: proc(&:to_f),
default: 95
option :port,
description: 'Port to connect to',
short: '-P PORT',
long: '--port PORT',
proc: proc(&:to_i),
default: 3306
option :socket,
description: 'Socket to use',
short: '-S SOCKET',
long: '--socket SOCKET',
default: nil
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[:user]
db_pass = config[:pass]
end
db_host = config[:host]
disk_size = config[:size]
critical_usage = config[:crit]
warning_usage = config[:warn]
if [db_host, db_user, db_pass, disk_size].any?(&:nil?)
unknown 'Must specify host, user, password and size'
end
begin
total_size = 0.0
db = Mysql.real_connect(config[:host], db_user, db_pass, nil, config[:port], config[:socket])
results = db.query <<-SQL
SELECT table_schema,
count(*) TABLES,
concat(round(sum(table_rows)/1000000,2),'M') rows,
round(sum(data_length)/(1024*1024*1024),2) DATA,
round(sum(index_length)/(1024*1024*1024),2) idx,
round(sum(data_length+index_length)/(1024*1024*1024),2) total_size,
round(sum(index_length)/sum(data_length),2) idxfrac
FROM information_schema.TABLES group by table_schema
SQL
results&.each_hash do |row|
# #YELLOW
total_size = total_size + row['total_size'].to_f # rubocop:disable Style/SelfAssignment
end
disk_use_percentage = total_size / disk_size * 100
diskstr = "DB size: #{total_size}, disk use: #{disk_use_percentage}%"
if disk_use_percentage > critical_usage
critical "Database size exceeds critical threshold: #{diskstr}"
elsif disk_use_percentage > warning_usage
warning "Database size exceeds warning threshold: #{diskstr}"
else
ok diskstr
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 e
ensure
db&.close
end
end
end