sensu-plugins-mysql 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2610f5b94c75984ca59d7f366360c2b323597ff2
4
+ data.tar.gz: 1311e95e8a892397cab04bd766a9050453384351
5
+ SHA512:
6
+ metadata.gz: 18c32290b777d18ac8419d75d8cd4089477f2c7f631b68db07c1426a414db9d62df0dc45a5fc2c279b435fdadd87adea5f73f7497f3601a212c068b3260a4ec9
7
+ data.tar.gz: 7360349ac47a884f9ab3a5d9fd388f9d7a93e40082e437b94e0906352a9fc53a31232e263533e8c13fda4e8f71a22c7590791af358e730f8692f6c6d073f3518
Binary file
Binary file
@@ -0,0 +1,11 @@
1
+ #Change Log
2
+ This project adheres to [Semantic Versioning](http://semver.org/).
3
+
4
+ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachangelog.com/)
5
+
6
+ ## Unreleased][unreleased]
7
+
8
+ ## 0.0.1 - 2015-05-29
9
+
10
+ ### Added
11
+ - initial release
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Sensu-Plugins
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ ## Sensu-Plugins-mysql
2
+
3
+ [![Build Status](https://travis-ci.org/sensu-plugins/sensu-plugins-mysql.svg?branch=master)](https://travis-ci.org/sensu-plugins/sensu-plugins-mysql)
4
+ [![Gem Version](https://badge.fury.io/rb/sensu-plugins-mysql.svg)](http://badge.fury.io/rb/sensu-plugins-mysql)
5
+ [![Code Climate](https://codeclimate.com/github/sensu-plugins/sensu-plugins-mysql/badges/gpa.svg)](https://codeclimate.com/github/sensu-plugins/sensu-plugins-mysql)
6
+ [![Test Coverage](https://codeclimate.com/github/sensu-plugins/sensu-plugins-mysql/badges/coverage.svg)](https://codeclimate.com/github/sensu-plugins/sensu-plugins-mysql)
7
+ [![Dependency Status](https://gemnasium.com/sensu-plugins/sensu-plugins-mysql.svg)](https://gemnasium.com/sensu-plugins/sensu-plugins-mysql)
8
+ [![Codeship Status for sensu-plugins/sensu-plugins-mysql](https://codeship.com/projects/266116c0-e896-0132-af9a-62885e5c211b/status?branch=master)](https://codeship.com/projects/82837)
9
+
10
+ ## Functionality
11
+
12
+ ## Files
13
+ * bin/check-cloudwatch-mysql-sensu.rb
14
+ * bin/check-mysql-alive.rb
15
+ * bin/check-mysql-connections.rb
16
+ * bin/check-mysql-disk.rb
17
+ * bin/check-mysql-innodb-lock.rb
18
+ * bin/metrics-mysql-graphite.rb
19
+ * bin/metrics-mysql.rb
20
+ * bin/mysql-metrics.sql
21
+
22
+ ## Usage
23
+
24
+ **metrics-mysql**
25
+ ```
26
+ {
27
+ "mysql":{
28
+ "hostname": "localhost",
29
+ "username": "sensu_user",
30
+ "password": "sensu_user_pass"
31
+ }
32
+ }
33
+ ```
34
+
35
+ ## Installation
36
+
37
+ [Installation and Setup](https://github.com/sensu-plugins/documentation/blob/master/user_docs/installation_instructions.md)
38
+
39
+
40
+ ## Notes
41
+
@@ -0,0 +1,157 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # <script name>
4
+ #
5
+ # DESCRIPTION:
6
+ # what is this thing supposed to do, monitor? How do alerts or
7
+ # alarms work?
8
+ #
9
+ # OUTPUT:
10
+ # plain text, metric data, etc
11
+ #
12
+ # PLATFORMS:
13
+ # Linux, Windows, BSD, Solaris, etc
14
+ #
15
+ # DEPENDENCIES:
16
+ # gem: sensu-plugin
17
+ # gem: aws
18
+ #
19
+ # USAGE:
20
+ # example commands
21
+ #
22
+ # NOTES:
23
+ # Does it behave differently on specific platforms, specific use cases, etc
24
+ #
25
+ # LICENSE:
26
+ # <your name> <your email>
27
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
28
+ # for details.
29
+ #
30
+
31
+ # !/usr/bin/env ruby
32
+ #
33
+ # Amazon RDS cloudwatch sensu plugin
34
+ # ===
35
+ #
36
+ # Dependencies
37
+ # -----------
38
+ # - http://docs.aws.amazon.com/AmazonRDS/latest/CommandLineReference/StartCLI.html
39
+ #
40
+ #
41
+ # Authors: Micah Hoffmann <https://github.com/SeattleMicah> Kristopher Zentner <https://github.com/kaezi>
42
+ #
43
+ #
44
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
45
+ # for details.
46
+
47
+ require 'aws/cloud_watch'
48
+ require 'optparse'
49
+ require 'pp'
50
+
51
+ aws_access_key_id = ''
52
+ aws_secret_key = ''
53
+ aws_region = ''
54
+ aws_debug = false
55
+
56
+ options = {}
57
+ optparse = OptionParser.new do|opts|
58
+ opts.on('-h', '--help', '') do
59
+ puts opts
60
+ exit
61
+ end
62
+
63
+ opts.on('-H', '--host HOST', 'Hostname') do |host|
64
+ options[:host] = host
65
+ end
66
+
67
+ opts.on('-w', '--warn WARN', 'Warning threshold') do |warn|
68
+ options[:warn] = warn
69
+ end
70
+
71
+ opts.on('-c', '--crit CRIT', 'Critical threshold') do |crit|
72
+ options[:crit] = crit
73
+ end
74
+
75
+ opts.on('-s', '--stat STAT', 'Statistic') do|stat|
76
+ options[:stat] = stat
77
+ end
78
+
79
+ opts.on('-l', '--lessthan', 'Threshold is less than') do|lessthan|
80
+ options[:lessthan] = lessthan
81
+ end
82
+ end
83
+ begin
84
+ optparse.parse!
85
+ mandatory = [:warn, :crit, :stat, :host] # Enforce the presence of
86
+ missing = mandatory.select { |param| options[param].nil? } # the -t and -f switches
87
+ unless missing.empty? #
88
+ puts "Missing options: #{missing.join(', ')}" #
89
+ puts optparse #
90
+ exit #
91
+ end #
92
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument #
93
+ puts $ERROR_INFO.to_s # Friendly output when parsing fails
94
+ puts optparse #
95
+ exit #
96
+ end
97
+
98
+ AWS.config(access_key_id: aws_access_key_id,
99
+ secret_access_key: aws_secret_key,
100
+ region: aws_region,
101
+ http_wire_trace: aws_debug)
102
+
103
+ metric = AWS::CloudWatch::Metric.new('AWS/RDS', "#{options[:stat]}",
104
+ dimensions: [
105
+ { name: 'DBInstanceIdentifier', value: "#{options[:host]}" }
106
+ ])
107
+ stats = metric.statistics(
108
+ start_time: Time.now - 600,
109
+ end_time: Time.now,
110
+ statistics: ['Average'])
111
+ latest = stats.first
112
+ # puts "#{stats.metric.name}: #{latest[:average]} #{latest[:unit]}"
113
+ # puts "#{options[:crit].to_f}"
114
+ if latest.nil?
115
+ msg = "WARNING: #{options[:host]} is not returning data! Is it deleted? Slave dead? "
116
+ msg += 'It could possibly mean there is no data to return, but make sure host is alive!'
117
+ puts msg
118
+ exit 2
119
+ end
120
+
121
+ average = latest[:average]
122
+ unit = latest[:unit]
123
+
124
+ # Determine the unit for the average returned and convert if needed
125
+ if unit == 'Bytes' && options[:stat] == 'FreeStorageSpace'
126
+ average = (latest[:average] / 1_073_741_824).round(0)
127
+ unit = 'GigaBytes'
128
+ elsif unit == 'Bytes'
129
+ average = (latest[:average] / 1_048_576).round(0)
130
+ unit = 'MegaBytes'
131
+ else
132
+ average = latest[:average]
133
+ end
134
+
135
+ # Depending on if the stat is less than or greater than use the -l option
136
+ if options[:lessthan] == true
137
+ # Begin the check of the average and against the warn and crit parameters
138
+ if average.to_f < options[:crit].to_f
139
+ puts "CRITICAL: #{options[:host]} statistic #{options[:stat]} is at #{average} #{unit} which is below threshold #{options[:crit]} #{unit}"
140
+ exit 1
141
+ elsif average.to_f < options[:warn].to_f
142
+ puts "WARNING: #{options[:host]} statistic #{options[:stat]} is at #{average} #{unit} which is below threshold #{options[:warn]} #{unit}"
143
+ exit 2
144
+ else
145
+ puts "OK: #{options[:host]} statistic #{options[:stat]} is #{average} #{unit}"
146
+ end
147
+ else
148
+ if average.to_f > options[:crit].to_f
149
+ puts "CRITICAL: #{options[:host]} statistic #{options[:stat]} is at #{average} #{unit} which is above threshold #{options[:crit]} #{unit}"
150
+ exit 1
151
+ elsif average.to_f > options[:warn].to_f
152
+ puts "WARNING: #{options[:host]} statistic #{options[:stat]} is at #{average} #{unit} which is above threshold #{options[:warn]} #{unit}"
153
+ exit 2
154
+ else
155
+ puts "OK: #{options[:host]} statistic #{options[:stat]} is #{average} #{unit}"
156
+ end
157
+ end
@@ -0,0 +1,92 @@
1
+ # !/usr/bin/env ruby
2
+ #
3
+ # MySQL Alive Plugin
4
+ # ===
5
+ #
6
+ # This plugin attempts to login to mysql with provided credentials.
7
+ #
8
+ # Copyright 2011 Joe Crim <josephcrim@gmail.com>
9
+ # Updated by Lewis Preson 2012 to accept a database parameter
10
+ # Updated by Oluwaseun Obajobi 2014 to accept ini argument
11
+ #
12
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
13
+ # for details.
14
+ #
15
+ # USING INI ARGUMENT
16
+ # This was implemented to load mysql credentials without parsing the username/password.
17
+ # The ini file should be readable by the sensu user/group.
18
+ # Ref: http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/
19
+ #
20
+ # EXAMPLE
21
+ # mysql-alive.rb -h db01 --ini '/etc/sensu/my.cnf'
22
+ #
23
+ # MY.CNF INI FORMAT
24
+ # [client]
25
+ # user=sensu
26
+ # password="abcd1234"
27
+ #
28
+
29
+ require 'sensu-plugin/check/cli'
30
+ require 'mysql'
31
+ require 'inifile'
32
+
33
+ class CheckMySQL < Sensu::Plugin::Check::CLI
34
+ option :user,
35
+ description: 'MySQL User',
36
+ short: '-u USER',
37
+ long: '--user USER'
38
+
39
+ option :password,
40
+ description: 'MySQL Password',
41
+ short: '-p PASS',
42
+ long: '--password PASS'
43
+
44
+ option :ini,
45
+ description: 'My.cnf ini file',
46
+ short: '-i',
47
+ long: '--ini VALUE'
48
+
49
+ option :hostname,
50
+ description: 'Hostname to login to',
51
+ short: '-h HOST',
52
+ long: '--hostname HOST'
53
+
54
+ option :database,
55
+ description: 'Database schema to connect to',
56
+ short: '-d DATABASE',
57
+ long: '--database DATABASE',
58
+ default: 'test'
59
+
60
+ option :port,
61
+ description: 'Port to connect to',
62
+ short: '-P PORT',
63
+ long: '--port PORT',
64
+ default: '3306'
65
+
66
+ option :socket,
67
+ description: 'Socket to use',
68
+ short: '-s SOCKET',
69
+ long: '--socket SOCKET'
70
+
71
+ def run
72
+ if config[:ini]
73
+ ini = IniFile.load(config[:ini])
74
+ section = ini['client']
75
+ db_user = section['user']
76
+ db_pass = section['password']
77
+ else
78
+ db_user = config[:user]
79
+ db_pass = config[:password]
80
+ end
81
+
82
+ begin
83
+ db = Mysql.real_connect(config[:hostname], db_user, db_pass, config[:database], config[:port].to_i, config[:socket])
84
+ info = db.get_server_info
85
+ ok "Server version: #{info}"
86
+ rescue Mysql::Error => e
87
+ critical "Error message: #{e.error}"
88
+ ensure
89
+ db.close if db
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,91 @@
1
+ # !/usr/bin/env ruby
2
+ #
3
+ # MySQL Health Plugin
4
+ # ===
5
+ #
6
+ # This plugin counts the maximum connections your MySQL has reached and warns you according to specified limits
7
+ #
8
+ # Copyright 2012 Panagiotis Papadomitsos <pj@ezgr.net>
9
+ #
10
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
11
+ # for details.
12
+
13
+ require 'sensu-plugin/check/cli'
14
+ require 'mysql'
15
+
16
+ class CheckMySQLHealth < Sensu::Plugin::Check::CLI
17
+ option :user,
18
+ description: 'MySQL User',
19
+ short: '-u USER',
20
+ long: '--user USER',
21
+ default: 'root'
22
+
23
+ option :password,
24
+ description: 'MySQL Password',
25
+ short: '-p PASS',
26
+ long: '--password PASS',
27
+ required: true
28
+
29
+ option :hostname,
30
+ description: 'Hostname to login to',
31
+ short: '-h HOST',
32
+ long: '--hostname HOST',
33
+ default: 'localhost'
34
+
35
+ option :port,
36
+ description: 'Port to connect to',
37
+ short: '-P PORT',
38
+ long: '--port PORT',
39
+ default: '3306'
40
+
41
+ option :socket,
42
+ description: 'Socket to use',
43
+ short: '-s SOCKET',
44
+ long: '--socket SOCKET'
45
+
46
+ option :maxwarn,
47
+ description: "Number of connections upon which we'll issue a warning",
48
+ short: '-w NUMBER',
49
+ long: '--warnnum NUMBER',
50
+ default: 100
51
+
52
+ option :maxcrit,
53
+ description: "Number of connections upon which we'll issue an alert",
54
+ short: '-c NUMBER',
55
+ long: '--critnum NUMBER',
56
+ default: 128
57
+
58
+ option :usepc,
59
+ description: 'Use percentage of defined max connections instead of absolute number',
60
+ short: '-a',
61
+ long: '--percentage',
62
+ default: false
63
+
64
+ def run
65
+ db = Mysql.real_connect(config[:hostname], config[:user], config[:password], config[:database], config[:port].to_i, config[:socket])
66
+ max_con = db
67
+ .query("SHOW VARIABLES LIKE 'max_connections'")
68
+ .fetch_hash
69
+ .fetch('Value')
70
+ .to_i
71
+ used_con = db
72
+ .query("SHOW GLOBAL STATUS LIKE 'Threads_connected'")
73
+ .fetch_hash
74
+ .fetch('Value')
75
+ .to_i
76
+ if config[:usepc]
77
+ pc = used_con.fdiv(max_con) * 100
78
+ critical "Max connections reached in MySQL: #{used_con} out of #{max_con}" if pc >= config[:maxcrit].to_i
79
+ warning "Max connections reached in MySQL: #{used_con} out of #{max_con}" if pc >= config[:maxwarn].to_i
80
+ ok "Max connections is under limit in MySQL: #{used_con} out of #{max_con}"
81
+ else
82
+ critical "Max connections reached in MySQL: #{used_con} out of #{max_con}" if used_con >= config[:maxcrit].to_i
83
+ warning "Max connections reached in MySQL: #{used_con} out of #{max_con}" if used_con >= config[:maxwarn].to_i
84
+ ok "Max connections is under limit in MySQL: #{used_con} out of #{max_con}"
85
+ end
86
+ rescue Mysql::Error => e
87
+ critical "MySQL check failed: #{e.error}"
88
+ ensure
89
+ db.close if db
90
+ end
91
+ end
@@ -0,0 +1,114 @@
1
+ # !/usr/bin/env ruby
2
+ #
3
+ # MySQL Disk Usage Check
4
+ # ===
5
+ #
6
+ # Copyright 2011 Sonian, Inc <chefs@sonian.net>
7
+ #
8
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
9
+ # for details.
10
+ #
11
+ # Check the size of the database and compare to crit and warn thresholds
12
+
13
+ require 'sensu-plugin/check/cli'
14
+ require 'mysql'
15
+
16
+ class CheckMysqlDisk < Sensu::Plugin::Check::CLI
17
+ option :host,
18
+ short: '-h',
19
+ long: '--host=VALUE',
20
+ description: 'Database host'
21
+
22
+ option :user,
23
+ short: '-u',
24
+ long: '--username=VALUE',
25
+ description: 'Database username'
26
+
27
+ option :pass,
28
+ short: '-p',
29
+ long: '--password=VALUE',
30
+ description: 'Database password'
31
+
32
+ option :size,
33
+ short: '-s',
34
+ long: '--size=VALUE',
35
+ description: 'Database size'
36
+
37
+ option :warn,
38
+ short: '-w',
39
+ long: '--warning=VALUE',
40
+ description: 'Warning threshold',
41
+ default: '85'
42
+
43
+ option :crit,
44
+ short: '-c',
45
+ long: '--critical=VALUE',
46
+ description: 'Critical threshold',
47
+ default: '95'
48
+
49
+ option :help,
50
+ short: '-h',
51
+ long: '--help',
52
+ description: 'Check RDS disk usage',
53
+ on: :tail,
54
+ boolean: true,
55
+ show_options: true,
56
+ exit: 0
57
+
58
+ def run
59
+ db_host = config[:host]
60
+ db_user = config[:user]
61
+ db_pass = config[:pass]
62
+ disk_size = config[:size].to_f
63
+ critical_usage = config[:crit].to_f
64
+ warning_usage = config[:warn].to_f
65
+
66
+ if [db_host, db_user, db_pass, disk_size].any?(&:nil?)
67
+ unknown 'Must specify host, user, password and size'
68
+ end
69
+
70
+ begin
71
+ total_size = 0.0
72
+ db = Mysql.new(db_host, db_user, db_pass)
73
+
74
+ results = db.query <<-EOSQL
75
+ SELECT table_schema,
76
+ count(*) TABLES,
77
+ concat(round(sum(table_rows)/1000000,2),'M') rows,
78
+ round(sum(data_length)/(1024*1024*1024),2) DATA,
79
+ round(sum(index_length)/(1024*1024*1024),2) idx,
80
+ round(sum(data_length+index_length)/(1024*1024*1024),2) total_size,
81
+ round(sum(index_length)/sum(data_length),2) idxfrac
82
+ FROM information_schema.TABLES group by table_schema
83
+ EOSQL
84
+
85
+ unless results.nil?
86
+ results.each_hash do |row|
87
+ # #YELLOW
88
+ total_size = total_size + row['total_size'].to_f # rubocop:disable Style/SelfAssignment
89
+ end
90
+ end
91
+
92
+ disk_use_percentage = total_size / disk_size * 100
93
+ diskstr = "DB size: #{total_size}, disk use: #{disk_use_percentage}%"
94
+
95
+ if disk_use_percentage > critical_usage
96
+ critical "Database size exceeds critical threshold: #{diskstr}"
97
+ elsif disk_use_percentage > warning_usage
98
+ warning "Database size exceeds warning threshold: #{diskstr}"
99
+ else
100
+ ok diskstr
101
+ end
102
+
103
+ rescue Mysql::Error => e
104
+ errstr = "Error code: #{e.errno} Error message: #{e.error}"
105
+ critical "#{errstr} SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate')
106
+
107
+ rescue => e
108
+ critical e
109
+
110
+ ensure
111
+ db.close if db
112
+ end
113
+ end
114
+ end