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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +11 -0
- data/LICENSE +22 -0
- data/README.md +41 -0
- data/bin/check-cloudwatch-mysql-sensu.rb +157 -0
- data/bin/check-mysql-alive.rb +92 -0
- data/bin/check-mysql-connections.rb +91 -0
- data/bin/check-mysql-disk.rb +114 -0
- data/bin/check-mysql-innodb-lock.rb +130 -0
- data/bin/check-mysql-replication-status.rb +158 -0
- data/bin/metrics-mysql-graphite.rb +261 -0
- data/bin/metrics-mysql.rb +58 -0
- data/bin/mysql-metrics.sql +15 -0
- data/lib/sensu-plugins-mysql.rb +1 -0
- data/lib/sensu-plugins-mysql/version.rb +13 -0
- metadata +281 -0
- metadata.gz.sig +1 -0
@@ -0,0 +1,130 @@
|
|
1
|
+
# !/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# MySQL InnoDB Lock Check Plugin
|
4
|
+
# ===
|
5
|
+
#
|
6
|
+
# This plugin checks InnoDB locks.
|
7
|
+
#
|
8
|
+
# Copyright 2014 Hiroaki Sano <hiroaki.sano.9stories@gmail.com>
|
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 CheckMySQLInnoDBLock < 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 :warn,
|
47
|
+
description: 'Warning threshold',
|
48
|
+
short: '-w SECONDS',
|
49
|
+
long: '--warning SECONDS',
|
50
|
+
default: 5
|
51
|
+
|
52
|
+
option :crit,
|
53
|
+
description: 'Critical threshold',
|
54
|
+
short: '-c SECONDS',
|
55
|
+
long: '--critical SECONDS',
|
56
|
+
default: 10
|
57
|
+
|
58
|
+
def run
|
59
|
+
db = Mysql.new(config[:hostname], config[:user], config[:password], config[:database], config[:port].to_i, config[:socket])
|
60
|
+
|
61
|
+
warn = config[:warn].to_i
|
62
|
+
crit = config[:crit].to_i
|
63
|
+
|
64
|
+
res = db.query <<-EQSQL
|
65
|
+
select
|
66
|
+
t_b.trx_mysql_thread_id blocking_id,
|
67
|
+
t_w.trx_mysql_thread_id requesting_id,
|
68
|
+
p_b.HOST blocking_host,
|
69
|
+
p_w.HOST requesting_host,
|
70
|
+
l.lock_table lock_table,
|
71
|
+
l.lock_index lock_index,
|
72
|
+
l.lock_mode lock_mode,
|
73
|
+
p_w.TIME seconds,
|
74
|
+
p_b.INFO blocking_info,
|
75
|
+
p_w.INFO requesting_info
|
76
|
+
from
|
77
|
+
information_schema.INNODB_LOCK_WAITS w,
|
78
|
+
information_schema.INNODB_LOCKS l,
|
79
|
+
information_schema.INNODB_TRX t_b,
|
80
|
+
information_schema.INNODB_TRX t_w,
|
81
|
+
information_schema.PROCESSLIST p_b,
|
82
|
+
information_schema.PROCESSLIST p_w
|
83
|
+
where
|
84
|
+
w.blocking_lock_id = l.lock_id
|
85
|
+
and
|
86
|
+
w.blocking_trx_id = t_b.trx_id
|
87
|
+
and
|
88
|
+
w.requesting_trx_id = t_w.trx_id
|
89
|
+
and
|
90
|
+
t_b.trx_mysql_thread_id = p_b.ID
|
91
|
+
and
|
92
|
+
t_w.trx_mysql_thread_id = p_w.ID
|
93
|
+
and
|
94
|
+
p_w.TIME > #{warn}
|
95
|
+
order by
|
96
|
+
requesting_id,blocking_id
|
97
|
+
EQSQL
|
98
|
+
|
99
|
+
lock_info = []
|
100
|
+
is_crit = false
|
101
|
+
res.each_hash do |row|
|
102
|
+
h = {}
|
103
|
+
is_crit = true if row['seconds'].to_i > crit
|
104
|
+
h['blocking_id'] = row['blocking_id']
|
105
|
+
h['requesting_id'] = row['requesting_id']
|
106
|
+
h['blocking_host'] = row['blocking_host']
|
107
|
+
h['requesting_host'] = row['requesting_host']
|
108
|
+
h['lock_table'] = row['lock_table']
|
109
|
+
h['lock_index'] = row['lock_index']
|
110
|
+
h['lock_mode'] = row['lock_mode']
|
111
|
+
h['seconds'] = row['seconds']
|
112
|
+
h['blocking_info'] = row['blocking_info']
|
113
|
+
h['requesting_info'] = row['requesting_info']
|
114
|
+
lock_info.push(h)
|
115
|
+
end
|
116
|
+
|
117
|
+
if lock_info.length == 0
|
118
|
+
ok
|
119
|
+
elsif is_crit == false
|
120
|
+
warning "Detected Locks #{lock_info}"
|
121
|
+
else
|
122
|
+
critical "Detected Locks #{lock_info}"
|
123
|
+
end
|
124
|
+
|
125
|
+
rescue Mysql::Error => e
|
126
|
+
critical "MySQL check failed: #{e.error}"
|
127
|
+
ensure
|
128
|
+
db.close if db
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# !/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# MySQL Replication Status (modded from disk)
|
4
|
+
# ===
|
5
|
+
#
|
6
|
+
# Copyright 2011 Sonian, Inc <chefs@sonian.net>
|
7
|
+
# Updated by Oluwaseun Obajobi 2014 to accept ini argument
|
8
|
+
#
|
9
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
10
|
+
# for details.
|
11
|
+
#
|
12
|
+
# USING INI ARGUMENT
|
13
|
+
# This was implemented to load mysql credentials without parsing the username/password.
|
14
|
+
# The ini file should be readable by the sensu user/group.
|
15
|
+
# Ref: http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/
|
16
|
+
#
|
17
|
+
# EXAMPLE
|
18
|
+
# mysql-alive.rb -h db01 --ini '/etc/sensu/my.cnf'
|
19
|
+
#
|
20
|
+
# MY.CNF INI FORMAT
|
21
|
+
# [client]
|
22
|
+
# user=sensu
|
23
|
+
# password="abcd1234"
|
24
|
+
#
|
25
|
+
|
26
|
+
require 'sensu-plugin/check/cli'
|
27
|
+
require 'mysql'
|
28
|
+
require 'inifile'
|
29
|
+
|
30
|
+
class CheckMysqlReplicationStatus < Sensu::Plugin::Check::CLI
|
31
|
+
option :host,
|
32
|
+
short: '-h',
|
33
|
+
long: '--host=VALUE',
|
34
|
+
description: 'Database host'
|
35
|
+
|
36
|
+
option :port,
|
37
|
+
short: '-P',
|
38
|
+
long: '--port=VALUE',
|
39
|
+
description: 'Database port',
|
40
|
+
default: 3306,
|
41
|
+
# #YELLOW
|
42
|
+
proc: lambda { |s| s.to_i } # rubocop:disable Lambda
|
43
|
+
|
44
|
+
option :socket,
|
45
|
+
short: '-s SOCKET',
|
46
|
+
long: '--socket SOCKET',
|
47
|
+
description: 'Socket to use'
|
48
|
+
|
49
|
+
option :user,
|
50
|
+
short: '-u',
|
51
|
+
long: '--username=VALUE',
|
52
|
+
description: 'Database username'
|
53
|
+
|
54
|
+
option :pass,
|
55
|
+
short: '-p',
|
56
|
+
long: '--password=VALUE',
|
57
|
+
description: 'Database password'
|
58
|
+
|
59
|
+
option :ini,
|
60
|
+
short: '-i',
|
61
|
+
long: '--ini VALUE',
|
62
|
+
description: 'My.cnf ini file'
|
63
|
+
|
64
|
+
option :warn,
|
65
|
+
short: '-w',
|
66
|
+
long: '--warning=VALUE',
|
67
|
+
description: 'Warning threshold for replication lag',
|
68
|
+
default: 900,
|
69
|
+
# #YELLOW
|
70
|
+
proc: lambda { |s| s.to_i } # rubocop:disable Lambda
|
71
|
+
|
72
|
+
option :crit,
|
73
|
+
short: '-c',
|
74
|
+
long: '--critical=VALUE',
|
75
|
+
description: 'Critical threshold for replication lag',
|
76
|
+
default: 1800,
|
77
|
+
# #YELLOW
|
78
|
+
proc: lambda { |s| s.to_i } # rubocop:disable Lambda
|
79
|
+
|
80
|
+
option :help,
|
81
|
+
short: '-h',
|
82
|
+
long: '--help',
|
83
|
+
description: 'Check MySQL replication status',
|
84
|
+
on: :tail,
|
85
|
+
boolean: true,
|
86
|
+
show_options: true,
|
87
|
+
exit: 0
|
88
|
+
|
89
|
+
def run
|
90
|
+
if config[:ini]
|
91
|
+
ini = IniFile.load(config[:ini])
|
92
|
+
section = ini['client']
|
93
|
+
db_user = section['user']
|
94
|
+
db_pass = section['password']
|
95
|
+
else
|
96
|
+
db_user = config[:user]
|
97
|
+
db_pass = config[:pass]
|
98
|
+
end
|
99
|
+
db_host = config[:host]
|
100
|
+
|
101
|
+
if [db_host, db_user, db_pass].any?(&:nil?)
|
102
|
+
unknown 'Must specify host, user, password'
|
103
|
+
end
|
104
|
+
|
105
|
+
begin
|
106
|
+
db = Mysql.new(db_host, db_user, db_pass, nil, config[:port], config[:socket])
|
107
|
+
results = db.query 'show slave status'
|
108
|
+
|
109
|
+
unless results.nil?
|
110
|
+
results.each_hash do |row|
|
111
|
+
# #YELLOW
|
112
|
+
# rubocop:disable all
|
113
|
+
warn "couldn't detect replication status" unless
|
114
|
+
%w(Slave_IO_State Slave_IO_Running Slave_SQL_Running Last_IO_Error Last_SQL_Error Seconds_Behind_Master).all? do |key|
|
115
|
+
row.key? key
|
116
|
+
end
|
117
|
+
|
118
|
+
# rubocop: enable all
|
119
|
+
slave_running = %w(Slave_IO_Running Slave_SQL_Running).all? do |key|
|
120
|
+
row[key] =~ /Yes/
|
121
|
+
end
|
122
|
+
|
123
|
+
output = 'Slave not running!'
|
124
|
+
output += ' STATES:'
|
125
|
+
output += " Slave_IO_Running=#{row['Slave_IO_Running']}"
|
126
|
+
output += ", Slave_SQL_Running=#{row['Slave_SQL_Running']}"
|
127
|
+
output += ", LAST ERROR: #{row['Last_SQL_Error']}"
|
128
|
+
|
129
|
+
critical output unless slave_running
|
130
|
+
|
131
|
+
replication_delay = row['Seconds_Behind_Master'].to_i
|
132
|
+
|
133
|
+
message = "replication delayed by #{replication_delay}"
|
134
|
+
|
135
|
+
if replication_delay > config[:warn] &&
|
136
|
+
replication_delay <= config[:crit]
|
137
|
+
warning message
|
138
|
+
elsif replication_delay >= config[:crit]
|
139
|
+
critical message
|
140
|
+
else
|
141
|
+
ok "slave running: #{slave_running}, #{message}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
ok 'show slave status was nil. This server is not a slave.'
|
145
|
+
end
|
146
|
+
|
147
|
+
rescue Mysql::Error => e
|
148
|
+
errstr = "Error code: #{e.errno} Error message: #{e.error}"
|
149
|
+
critical "#{errstr} SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate')
|
150
|
+
|
151
|
+
rescue => e
|
152
|
+
critical e
|
153
|
+
|
154
|
+
ensure
|
155
|
+
db.close if db
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
# !/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Push mysql stats into graphite
|
4
|
+
# ===
|
5
|
+
#
|
6
|
+
# NOTE: This plugin will attempt to get replication stats but the user
|
7
|
+
# must have SUPER or REPLICATION CLIENT privileges to run 'SHOW SLAVE
|
8
|
+
# STATUS'. It will silently ignore and continue if 'SHOW SLAVE STATUS'
|
9
|
+
# fails for any reason. The key 'slaveLag' will not be present in the
|
10
|
+
# output.
|
11
|
+
#
|
12
|
+
# Copyright 2012 Pete Shima <me@peteshima.com>
|
13
|
+
# Additional hacks by Joe Miller - https://github.com/joemiller
|
14
|
+
# Updated by Oluwaseun Obajobi 2014 to accept ini argument
|
15
|
+
#
|
16
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
17
|
+
# for details.
|
18
|
+
#
|
19
|
+
# USING INI ARGUMENT
|
20
|
+
# This was implemented to load mysql credentials without parsing the username/password.
|
21
|
+
# The ini file should be readable by the sensu user/group.
|
22
|
+
# Ref: http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/
|
23
|
+
#
|
24
|
+
# EXAMPLE
|
25
|
+
# mysql-alive.rb -h db01 --ini '/etc/sensu/my.cnf'
|
26
|
+
#
|
27
|
+
# MY.CNF INI FORMAT
|
28
|
+
# [client]
|
29
|
+
# user=sensu
|
30
|
+
# password="abcd1234"
|
31
|
+
#
|
32
|
+
|
33
|
+
require 'sensu-plugin/metric/cli'
|
34
|
+
require 'mysql2'
|
35
|
+
require 'socket'
|
36
|
+
require 'inifile'
|
37
|
+
|
38
|
+
class Mysql2Graphite < Sensu::Plugin::Metric::CLI::Graphite
|
39
|
+
option :host,
|
40
|
+
short: '-h HOST',
|
41
|
+
long: '--host HOST',
|
42
|
+
description: 'Mysql Host to connect to',
|
43
|
+
required: true
|
44
|
+
|
45
|
+
option :port,
|
46
|
+
short: '-P PORT',
|
47
|
+
long: '--port PORT',
|
48
|
+
description: 'Mysql Port to connect to',
|
49
|
+
proc: proc(&:to_i),
|
50
|
+
default: 3306
|
51
|
+
|
52
|
+
option :username,
|
53
|
+
short: '-u USERNAME',
|
54
|
+
long: '--user USERNAME',
|
55
|
+
description: 'Mysql Username'
|
56
|
+
|
57
|
+
option :password,
|
58
|
+
short: '-p PASSWORD',
|
59
|
+
long: '--pass PASSWORD',
|
60
|
+
description: 'Mysql password',
|
61
|
+
default: ''
|
62
|
+
|
63
|
+
option :ini,
|
64
|
+
short: '-i',
|
65
|
+
long: '--ini VALUE',
|
66
|
+
description: 'My.cnf ini file'
|
67
|
+
|
68
|
+
option :scheme,
|
69
|
+
description: 'Metric naming scheme, text to prepend to metric',
|
70
|
+
short: '-s SCHEME',
|
71
|
+
long: '--scheme SCHEME',
|
72
|
+
default: "#{Socket.gethostname}.mysql"
|
73
|
+
|
74
|
+
option :socket,
|
75
|
+
short: '-S SOCKET',
|
76
|
+
long: '--socket SOCKET'
|
77
|
+
|
78
|
+
option :verbose,
|
79
|
+
short: '-v',
|
80
|
+
long: '--verbose',
|
81
|
+
boolean: true
|
82
|
+
|
83
|
+
def run
|
84
|
+
# props to https://github.com/coredump/hoardd/blob/master/scripts-available/mysql.coffee
|
85
|
+
|
86
|
+
metrics = {
|
87
|
+
'general' => {
|
88
|
+
'Bytes_received' => 'rxBytes',
|
89
|
+
'Bytes_sent' => 'txBytes',
|
90
|
+
'Key_read_requests' => 'keyRead_requests',
|
91
|
+
'Key_reads' => 'keyReads',
|
92
|
+
'Key_write_requests' => 'keyWrite_requests',
|
93
|
+
'Key_writes' => 'keyWrites',
|
94
|
+
'Binlog_cache_use' => 'binlogCacheUse',
|
95
|
+
'Binlog_cache_disk_use' => 'binlogCacheDiskUse',
|
96
|
+
'Max_used_connections' => 'maxUsedConnections',
|
97
|
+
'Aborted_clients' => 'abortedClients',
|
98
|
+
'Aborted_connects' => 'abortedConnects',
|
99
|
+
'Threads_connected' => 'threadsConnected',
|
100
|
+
'Open_files' => 'openFiles',
|
101
|
+
'Open_tables' => 'openTables',
|
102
|
+
'Opened_tables' => 'openedTables',
|
103
|
+
'Prepared_stmt_count' => 'preparedStmtCount',
|
104
|
+
'Seconds_Behind_Master' => 'slaveLag',
|
105
|
+
'Select_full_join' => 'fullJoins',
|
106
|
+
'Select_full_range_join' => 'fullRangeJoins',
|
107
|
+
'Select_range' => 'selectRange',
|
108
|
+
'Select_range_check' => 'selectRange_check',
|
109
|
+
'Select_scan' => 'selectScan',
|
110
|
+
'Slow_queries' => 'slowQueries'
|
111
|
+
},
|
112
|
+
'querycache' => {
|
113
|
+
'Qcache_queries_in_cache' => 'queriesInCache',
|
114
|
+
'Qcache_hits' => 'cacheHits',
|
115
|
+
'Qcache_inserts' => 'inserts',
|
116
|
+
'Qcache_not_cached' => 'notCached',
|
117
|
+
'Qcache_lowmem_prunes' => 'lowMemPrunes'
|
118
|
+
},
|
119
|
+
'commands' => {
|
120
|
+
'Com_admin_commands' => 'admin_commands',
|
121
|
+
'Com_begin' => 'begin',
|
122
|
+
'Com_change_db' => 'change_db',
|
123
|
+
'Com_commit' => 'commit',
|
124
|
+
'Com_create_table' => 'create_table',
|
125
|
+
'Com_drop_table' => 'drop_table',
|
126
|
+
'Com_show_keys' => 'show_keys',
|
127
|
+
'Com_delete' => 'delete',
|
128
|
+
'Com_create_db' => 'create_db',
|
129
|
+
'Com_grant' => 'grant',
|
130
|
+
'Com_show_processlist' => 'show_processlist',
|
131
|
+
'Com_flush' => 'flush',
|
132
|
+
'Com_insert' => 'insert',
|
133
|
+
'Com_purge' => 'purge',
|
134
|
+
'Com_replace' => 'replace',
|
135
|
+
'Com_rollback' => 'rollback',
|
136
|
+
'Com_select' => 'select',
|
137
|
+
'Com_set_option' => 'set_option',
|
138
|
+
'Com_show_binlogs' => 'show_binlogs',
|
139
|
+
'Com_show_databases' => 'show_databases',
|
140
|
+
'Com_show_fields' => 'show_fields',
|
141
|
+
'Com_show_status' => 'show_status',
|
142
|
+
'Com_show_tables' => 'show_tables',
|
143
|
+
'Com_show_variables' => 'show_variables',
|
144
|
+
'Com_update' => 'update',
|
145
|
+
'Com_drop_db' => 'drop_db',
|
146
|
+
'Com_revoke' => 'revoke',
|
147
|
+
'Com_drop_user' => 'drop_user',
|
148
|
+
'Com_show_grants' => 'show_grants',
|
149
|
+
'Com_lock_tables' => 'lock_tables',
|
150
|
+
'Com_show_create_table' => 'show_create_table',
|
151
|
+
'Com_unlock_tables' => 'unlock_tables',
|
152
|
+
'Com_alter_table' => 'alter_table'
|
153
|
+
},
|
154
|
+
'counters' => {
|
155
|
+
'Handler_write' => 'handlerWrite',
|
156
|
+
'Handler_update' => 'handlerUpdate',
|
157
|
+
'Handler_delete' => 'handlerDelete',
|
158
|
+
'Handler_read_first' => 'handlerRead_first',
|
159
|
+
'Handler_read_key' => 'handlerRead_key',
|
160
|
+
'Handler_read_next' => 'handlerRead_next',
|
161
|
+
'Handler_read_prev' => 'handlerRead_prev',
|
162
|
+
'Handler_read_rnd' => 'handlerRead_rnd',
|
163
|
+
'Handler_read_rnd_next' => 'handlerRead_rnd_next',
|
164
|
+
'Handler_commit' => 'handlerCommit',
|
165
|
+
'Handler_rollback' => 'handlerRollback',
|
166
|
+
'Handler_savepoint' => 'handlerSavepoint',
|
167
|
+
'Handler_savepoint_rollback' => 'handlerSavepointRollback'
|
168
|
+
},
|
169
|
+
'innodb' => {
|
170
|
+
'Innodb_buffer_pool_pages_total' => 'bufferTotal_pages',
|
171
|
+
'Innodb_buffer_pool_pages_free' => 'bufferFree_pages',
|
172
|
+
'Innodb_buffer_pool_pages_dirty' => 'bufferDirty_pages',
|
173
|
+
'Innodb_buffer_pool_pages_data' => 'bufferUsed_pages',
|
174
|
+
'Innodb_page_size' => 'pageSize',
|
175
|
+
'Innodb_pages_created' => 'pagesCreated',
|
176
|
+
'Innodb_pages_read' => 'pagesRead',
|
177
|
+
'Innodb_pages_written' => 'pagesWritten',
|
178
|
+
'Innodb_row_lock_current_waits' => 'currentLockWaits',
|
179
|
+
'Innodb_row_lock_waits' => 'lockWaitTimes',
|
180
|
+
'Innodb_row_lock_time' => 'rowLockTime',
|
181
|
+
'Innodb_data_reads' => 'fileReads',
|
182
|
+
'Innodb_data_writes' => 'fileWrites',
|
183
|
+
'Innodb_data_fsyncs' => 'fileFsyncs',
|
184
|
+
'Innodb_log_writes' => 'logWrites',
|
185
|
+
'Innodb_rows_updated' => 'rowsUpdated',
|
186
|
+
'Innodb_rows_read' => 'rowsRead',
|
187
|
+
'Innodb_rows_deleted' => 'rowsDeleted',
|
188
|
+
'Innodb_rows_inserted' => 'rowsInserted'
|
189
|
+
},
|
190
|
+
'configuration' => {
|
191
|
+
'Max_prepared_stmt_count' => 'MaxPreparedStmtCount'
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
config[:host].split(' ').each do |mysql_host|
|
196
|
+
mysql_shorthostname = mysql_host.split('.')[0]
|
197
|
+
if config[:ini]
|
198
|
+
ini = IniFile.load(config[:ini])
|
199
|
+
section = ini['client']
|
200
|
+
db_user = section['user']
|
201
|
+
db_pass = section['password']
|
202
|
+
else
|
203
|
+
db_user = config[:username]
|
204
|
+
db_pass = config[:password]
|
205
|
+
end
|
206
|
+
begin
|
207
|
+
mysql = Mysql2::Client.new(
|
208
|
+
host: mysql_host,
|
209
|
+
port: config[:port],
|
210
|
+
username: db_user,
|
211
|
+
password: db_pass,
|
212
|
+
socket: config[:socket]
|
213
|
+
)
|
214
|
+
|
215
|
+
results = mysql.query('SHOW GLOBAL STATUS')
|
216
|
+
rescue => e
|
217
|
+
puts e.message
|
218
|
+
end
|
219
|
+
|
220
|
+
results.each do |row|
|
221
|
+
metrics.each do |category, var_mapping|
|
222
|
+
if var_mapping.key?(row['Variable_name'])
|
223
|
+
output "#{config[:scheme]}.#{mysql_shorthostname}.#{category}.#{var_mapping[row['Variable_name']]}", row['Value']
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
begin
|
229
|
+
slave_results = mysql.query('SHOW SLAVE STATUS')
|
230
|
+
# should return a single element array containing one hash
|
231
|
+
# #YELLOW
|
232
|
+
slave_results.first.each do |key, value| # rubocop:disable Style/Next
|
233
|
+
if metrics['general'].include?(key)
|
234
|
+
# Replication lag being null is bad, very bad, so negativate it here
|
235
|
+
value = -1 if key == 'Seconds_Behind_Master' && value.nil?
|
236
|
+
output "#{config[:scheme]}.#{mysql_shorthostname}.general.#{metrics['general'][key]}", value
|
237
|
+
end
|
238
|
+
end
|
239
|
+
rescue => e
|
240
|
+
puts "Error querying slave status: #{e}" if config[:verbose]
|
241
|
+
end
|
242
|
+
|
243
|
+
begin
|
244
|
+
variables_results = mysql.query('SHOW GLOBAL VARIABLES')
|
245
|
+
|
246
|
+
category = 'configuration'
|
247
|
+
variables_results.each do |row|
|
248
|
+
metrics[category].each do |metric, desc|
|
249
|
+
if metric.casecmp(row['Variable_name']) == 0
|
250
|
+
output "#{config[:scheme]}.#{mysql_shorthostname}.#{category}.#{desc}", row['Value']
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
rescue => e
|
255
|
+
puts e.message
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
ok
|
260
|
+
end
|
261
|
+
end
|