sensu-plugins-mysql-nagyt 2.6.0
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
- data/CHANGELOG.md +155 -0
- data/LICENSE +22 -0
- data/README.md +156 -0
- data/bin/check-mysql-alive.rb +102 -0
- data/bin/check-mysql-connections.rb +110 -0
- data/bin/check-mysql-disk.rb +140 -0
- data/bin/check-mysql-innodb-lock.rb +149 -0
- data/bin/check-mysql-msr-replication-status.rb +153 -0
- data/bin/check-mysql-query-result-count.rb +113 -0
- data/bin/check-mysql-replication-status.rb +175 -0
- data/bin/check-mysql-select-count.rb +115 -0
- data/bin/check-mysql-status.rb +209 -0
- data/bin/check-mysql-threads.rb +122 -0
- data/bin/metrics-mysql-graphite.rb +268 -0
- data/bin/metrics-mysql-multiple-select-count.rb +112 -0
- data/bin/metrics-mysql-processes.rb +142 -0
- data/bin/metrics-mysql-query-result-count.rb +100 -0
- data/bin/metrics-mysql-raw.rb +396 -0
- data/bin/metrics-mysql-select-count.rb +102 -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 +9 -0
- metadata +262 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# metrics-mysql-processes
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# Gets metrics out of of MySQL's "SHOW PROCESSLIST" query.
|
7
|
+
#
|
8
|
+
# Output number of connections per-users, number of connections
|
9
|
+
# per-databases, number of the different commands running.
|
10
|
+
#
|
11
|
+
# OUTPUT:
|
12
|
+
# metric-data
|
13
|
+
#
|
14
|
+
# PLATFORMS:
|
15
|
+
# Linux, Windows, BSD, Solaris, etc
|
16
|
+
#
|
17
|
+
# DEPENDENCIES:
|
18
|
+
# gem: sensu-plugin
|
19
|
+
# gem: mysql
|
20
|
+
#
|
21
|
+
# USAGE:
|
22
|
+
# This was implemented to load mysql credentials without parsing the username/password.
|
23
|
+
# The ini file should be readable by the sensu user/group.
|
24
|
+
# Ref: http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/
|
25
|
+
#
|
26
|
+
# EXAMPLE
|
27
|
+
# mysql-alive.rb -h db01 --ini '/etc/sensu/my.cnf'
|
28
|
+
# mysql-alive.rb -h db01 --ini '/etc/sensu/my.cnf' --ini-section customsection
|
29
|
+
#
|
30
|
+
# MY.CNF INI FORMAT
|
31
|
+
# [client]
|
32
|
+
# user=sensu
|
33
|
+
# password="abcd1234"
|
34
|
+
#
|
35
|
+
# [customsection]
|
36
|
+
# user=user
|
37
|
+
# password="password"
|
38
|
+
#
|
39
|
+
# NOTES:
|
40
|
+
#
|
41
|
+
# LICENSE:
|
42
|
+
# Jonathan Ballet <jballet@edgelab.ch>
|
43
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
44
|
+
# for details.
|
45
|
+
|
46
|
+
require 'sensu-plugin/metric/cli'
|
47
|
+
require 'mysql'
|
48
|
+
require 'socket'
|
49
|
+
require 'inifile'
|
50
|
+
|
51
|
+
class MetricsMySQLProcesses < Sensu::Plugin::Metric::CLI::Graphite
|
52
|
+
option :host,
|
53
|
+
short: '-h HOST',
|
54
|
+
long: '--host HOST',
|
55
|
+
description: 'MySQL Host to connect to',
|
56
|
+
required: true
|
57
|
+
|
58
|
+
option :port,
|
59
|
+
short: '-P PORT',
|
60
|
+
long: '--port PORT',
|
61
|
+
description: 'MySQL Port to connect to',
|
62
|
+
proc: proc(&:to_i),
|
63
|
+
default: 3306
|
64
|
+
|
65
|
+
option :username,
|
66
|
+
short: '-u USERNAME',
|
67
|
+
long: '--user USERNAME',
|
68
|
+
description: 'MySQL Username'
|
69
|
+
|
70
|
+
option :password,
|
71
|
+
short: '-p PASSWORD',
|
72
|
+
long: '--pass PASSWORD',
|
73
|
+
description: 'MySQL password',
|
74
|
+
default: ''
|
75
|
+
|
76
|
+
option :ini,
|
77
|
+
short: '-i',
|
78
|
+
long: '--ini VALUE',
|
79
|
+
description: 'My.cnf ini file'
|
80
|
+
|
81
|
+
option :ini_section,
|
82
|
+
description: 'Section in my.cnf ini file',
|
83
|
+
long: '--ini-section VALUE',
|
84
|
+
default: 'client'
|
85
|
+
|
86
|
+
option :scheme,
|
87
|
+
description: 'Metric naming scheme, text to prepend to metric',
|
88
|
+
short: '-s SCHEME',
|
89
|
+
long: '--scheme SCHEME',
|
90
|
+
default: "#{Socket.gethostname}.mysql"
|
91
|
+
|
92
|
+
option :socket,
|
93
|
+
short: '-S SOCKET',
|
94
|
+
long: '--socket SOCKET',
|
95
|
+
description: 'MySQL Unix socket to connect to'
|
96
|
+
|
97
|
+
def run
|
98
|
+
config[:host].split(' ').each do |mysql_host|
|
99
|
+
mysql_shorthostname = mysql_host.split('.')[0]
|
100
|
+
if config[:ini]
|
101
|
+
ini = IniFile.load(config[:ini])
|
102
|
+
section = ini[config[:ini_section]]
|
103
|
+
db_user = section['user']
|
104
|
+
db_pass = section['password']
|
105
|
+
else
|
106
|
+
db_user = config[:username]
|
107
|
+
db_pass = config[:password]
|
108
|
+
end
|
109
|
+
begin
|
110
|
+
mysql = Mysql.new(mysql_host, db_user, db_pass, nil, config[:port], config[:socket])
|
111
|
+
|
112
|
+
results = mysql.query('SHOW PROCESSLIST')
|
113
|
+
rescue => e
|
114
|
+
unknown "Unable to query MySQL: #{e.message}"
|
115
|
+
end
|
116
|
+
|
117
|
+
metrics = {
|
118
|
+
'user' => {},
|
119
|
+
'database' => {},
|
120
|
+
'command' => {}
|
121
|
+
}
|
122
|
+
|
123
|
+
metrics.each_value { |value| value.default = 0 }
|
124
|
+
|
125
|
+
results.each_hash do |row|
|
126
|
+
metrics['user'][row['User']] += 1
|
127
|
+
if row['db'] # If no database has been selected by the process, it is set to nil.
|
128
|
+
metrics['database'][row['db']] += 1
|
129
|
+
end
|
130
|
+
metrics['command'][row['Command']] += 1
|
131
|
+
end
|
132
|
+
|
133
|
+
metrics.each do |key, value|
|
134
|
+
value.each do |instance, count|
|
135
|
+
output "#{config[:scheme]}.#{mysql_shorthostname}.#{key}.#{instance}", count
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
ok
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# MySQL Query Result Count Metric
|
4
|
+
#
|
5
|
+
# Creates a graphite-formatted metric for the length of a result set from a MySQL query.
|
6
|
+
#
|
7
|
+
# Copyright 2017 Andrew Thal <athal7@me.com>
|
8
|
+
#
|
9
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
10
|
+
# for details.
|
11
|
+
|
12
|
+
require 'sensu-plugin/metric/cli'
|
13
|
+
require 'mysql'
|
14
|
+
require 'inifile'
|
15
|
+
|
16
|
+
class MysqlQueryCountMetric < Sensu::Plugin::Metric::CLI::Graphite
|
17
|
+
option :host,
|
18
|
+
short: '-h HOST',
|
19
|
+
long: '--host HOST',
|
20
|
+
description: 'MySQL Host to connect to',
|
21
|
+
required: true
|
22
|
+
|
23
|
+
option :port,
|
24
|
+
short: '-P PORT',
|
25
|
+
long: '--port PORT',
|
26
|
+
description: 'MySQL Port to connect to',
|
27
|
+
proc: proc(&:to_i),
|
28
|
+
default: 3306
|
29
|
+
|
30
|
+
option :username,
|
31
|
+
short: '-u USERNAME',
|
32
|
+
long: '--user USERNAME',
|
33
|
+
description: 'MySQL Username'
|
34
|
+
|
35
|
+
option :password,
|
36
|
+
short: '-p PASSWORD',
|
37
|
+
long: '--pass PASSWORD',
|
38
|
+
description: 'MySQL password',
|
39
|
+
default: ''
|
40
|
+
|
41
|
+
option :database,
|
42
|
+
short: '-d DATABASE',
|
43
|
+
long: '--database DATABASE',
|
44
|
+
description: 'MySQL database',
|
45
|
+
default: ''
|
46
|
+
|
47
|
+
option :ini,
|
48
|
+
short: '-i',
|
49
|
+
long: '--ini VALUE',
|
50
|
+
description: 'My.cnf ini file'
|
51
|
+
|
52
|
+
option :ini_section,
|
53
|
+
description: 'Section in my.cnf ini file',
|
54
|
+
long: '--ini-section VALUE',
|
55
|
+
default: 'client'
|
56
|
+
|
57
|
+
option :socket,
|
58
|
+
short: '-S SOCKET',
|
59
|
+
long: '--socket SOCKET',
|
60
|
+
description: 'MySQL Unix socket to connect to'
|
61
|
+
|
62
|
+
option :name,
|
63
|
+
short: '-n NAME',
|
64
|
+
long: '--name NAME',
|
65
|
+
description: 'Metric name for a configured handler',
|
66
|
+
default: 'mysql.query_count'
|
67
|
+
|
68
|
+
option :query,
|
69
|
+
short: '-q QUERY',
|
70
|
+
long: '--query QUERY',
|
71
|
+
description: 'Query to execute',
|
72
|
+
required: true
|
73
|
+
|
74
|
+
def run
|
75
|
+
if config[:ini]
|
76
|
+
ini = IniFile.load(config[:ini])
|
77
|
+
section = ini[config[:ini_section]]
|
78
|
+
db_user = section['user']
|
79
|
+
db_pass = section['password']
|
80
|
+
else
|
81
|
+
db_user = config[:username]
|
82
|
+
db_pass = config[:password]
|
83
|
+
end
|
84
|
+
db = Mysql.real_connect(config[:host], db_user, db_pass, config[:database], config[:port].to_i, config[:socket])
|
85
|
+
length = db.query(config[:query]).count
|
86
|
+
|
87
|
+
output config[:name], length
|
88
|
+
ok
|
89
|
+
|
90
|
+
rescue Mysql::Error => e
|
91
|
+
errstr = "Error code: #{e.errno} Error message: #{e.error}"
|
92
|
+
critical "#{errstr} SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate')
|
93
|
+
|
94
|
+
rescue => e
|
95
|
+
critical e
|
96
|
+
|
97
|
+
ensure
|
98
|
+
db.close if db
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,396 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# MySQL metrics Plugin without mysql gem requirement
|
4
|
+
# ===
|
5
|
+
#
|
6
|
+
# This plugin attempts to login to mysql with provided credentials.
|
7
|
+
# and outputs metrics in graphite format
|
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
|
14
|
+
# the username/password.
|
15
|
+
# The ini file should be readable by the sensu user/group.
|
16
|
+
#
|
17
|
+
# EXAMPLE
|
18
|
+
# metrics-mysql-raw.rb -h localhost --ini '/etc/sensu/my.cnf'
|
19
|
+
# metrics-mysql-raw.rb -h localhost --ini '/etc/sensu/my.cnf' --ini-section customsection
|
20
|
+
#
|
21
|
+
# MY.CNF INI FORMAT
|
22
|
+
# [client]
|
23
|
+
# user=sensu
|
24
|
+
# password="abcd1234"
|
25
|
+
# socket="/var/lib/mysql/mysql.sock"
|
26
|
+
#
|
27
|
+
# [customsection]
|
28
|
+
# user=user
|
29
|
+
# password="password"
|
30
|
+
#
|
31
|
+
# LICENSE:
|
32
|
+
# Copyright 2012 Pete Shima <me@peteshima.com>
|
33
|
+
# Additional hacks by Joe Miller - https://github.com/joemiller
|
34
|
+
# Updated by Oluwaseun Obajobi 2014 to accept ini argument
|
35
|
+
# Forked by Magic Online 11.2016 to not depend on mysql gem
|
36
|
+
# - www.magic.fr <hanynowsky@gmail.com>
|
37
|
+
# MIT - Same as Sensu License
|
38
|
+
#
|
39
|
+
|
40
|
+
require 'sensu-plugin/metric/cli'
|
41
|
+
require 'open3'
|
42
|
+
require 'socket'
|
43
|
+
require 'inifile'
|
44
|
+
require 'timeout'
|
45
|
+
|
46
|
+
#
|
47
|
+
# Metrics Mysql Raw
|
48
|
+
#
|
49
|
+
class MetricsMySQLRaw < Sensu::Plugin::Metric::CLI::Graphite
|
50
|
+
option(
|
51
|
+
:user,
|
52
|
+
description: 'MySQL User',
|
53
|
+
short: '-u USER',
|
54
|
+
long: '--user USER',
|
55
|
+
default: 'mosim'
|
56
|
+
)
|
57
|
+
|
58
|
+
option(
|
59
|
+
:password,
|
60
|
+
description: 'MySQL Password',
|
61
|
+
short: '-p PASS',
|
62
|
+
long: '--password PASS',
|
63
|
+
default: 'mysqlPassWord'
|
64
|
+
)
|
65
|
+
|
66
|
+
option(
|
67
|
+
:ini,
|
68
|
+
description: 'My.cnf ini file',
|
69
|
+
short: '-i',
|
70
|
+
long: '--ini VALUE'
|
71
|
+
)
|
72
|
+
|
73
|
+
option(
|
74
|
+
:ini_section,
|
75
|
+
description: 'Section in my.cnf ini file',
|
76
|
+
long: '--ini-section VALUE',
|
77
|
+
default: 'client'
|
78
|
+
)
|
79
|
+
|
80
|
+
option(
|
81
|
+
:hostname,
|
82
|
+
description: 'Hostname to login to',
|
83
|
+
short: '-h HOST',
|
84
|
+
long: '--hostname HOST',
|
85
|
+
default: 'localhost'
|
86
|
+
)
|
87
|
+
|
88
|
+
option(
|
89
|
+
:database,
|
90
|
+
description: 'Database schema to connect to. NOT YET IMPlemented',
|
91
|
+
short: '-d DATABASE',
|
92
|
+
long: '--database DATABASE',
|
93
|
+
default: 'test'
|
94
|
+
)
|
95
|
+
|
96
|
+
option(
|
97
|
+
:timeout,
|
98
|
+
description: 'Timeout',
|
99
|
+
short: '-T TIMEOUT',
|
100
|
+
long: '--timeout TIMEOUT',
|
101
|
+
default: 10
|
102
|
+
)
|
103
|
+
|
104
|
+
option(
|
105
|
+
:port,
|
106
|
+
description: 'Port to connect to',
|
107
|
+
short: '-P PORT',
|
108
|
+
long: '--port PORT',
|
109
|
+
default: '3306'
|
110
|
+
)
|
111
|
+
|
112
|
+
option(
|
113
|
+
:socket,
|
114
|
+
description: 'Socket to use',
|
115
|
+
short: '-s SOCKET',
|
116
|
+
long: '--socket SOCKET',
|
117
|
+
default: '/var/run/mysqld/mysqld.sock'
|
118
|
+
)
|
119
|
+
|
120
|
+
option(
|
121
|
+
:binary,
|
122
|
+
description: 'Absolute path to mysql binary',
|
123
|
+
short: '-b BINARY',
|
124
|
+
long: '--binary BINARY',
|
125
|
+
default: 'mysql'
|
126
|
+
)
|
127
|
+
|
128
|
+
option(
|
129
|
+
:check,
|
130
|
+
description: 'type of check: metric',
|
131
|
+
short: '-c CHECK',
|
132
|
+
long: '--check CHECK',
|
133
|
+
default: 'metric'
|
134
|
+
)
|
135
|
+
|
136
|
+
option(
|
137
|
+
:scheme,
|
138
|
+
description: 'Metric naming scheme, text to prepend to metric',
|
139
|
+
short: '-s SCHEME',
|
140
|
+
long: '--scheme SCHEME',
|
141
|
+
default: "#{Socket.gethostname}.mysql"
|
142
|
+
)
|
143
|
+
|
144
|
+
option(
|
145
|
+
:verbose,
|
146
|
+
short: '-v',
|
147
|
+
long: '--verbose',
|
148
|
+
boolean: true
|
149
|
+
)
|
150
|
+
|
151
|
+
option(
|
152
|
+
:off,
|
153
|
+
description: 'Turn Metrics OFF',
|
154
|
+
long: '--off',
|
155
|
+
boolean: true,
|
156
|
+
default: false
|
157
|
+
)
|
158
|
+
|
159
|
+
# Metrics hash
|
160
|
+
def metrics_hash
|
161
|
+
metrics = {
|
162
|
+
'general' => {
|
163
|
+
'Bytes_received' => 'rxBytes',
|
164
|
+
'Bytes_sent' => 'txBytes',
|
165
|
+
'Key_read_requests' => 'keyRead_requests',
|
166
|
+
'Key_reads' => 'keyReads',
|
167
|
+
'Key_write_requests' => 'keyWrite_requests',
|
168
|
+
'Key_writes' => 'keyWrites',
|
169
|
+
'Binlog_cache_use' => 'binlogCacheUse',
|
170
|
+
'Binlog_cache_disk_use' => 'binlogCacheDiskUse',
|
171
|
+
'Max_used_connections' => 'maxUsedConnections',
|
172
|
+
'Aborted_clients' => 'abortedClients',
|
173
|
+
'Aborted_connects' => 'abortedConnects',
|
174
|
+
'Threads_connected' => 'threadsConnected',
|
175
|
+
'Open_files' => 'openFiles',
|
176
|
+
'Open_tables' => 'openTables',
|
177
|
+
'Opened_tables' => 'openedTables',
|
178
|
+
'Prepared_stmt_count' => 'preparedStmtCount',
|
179
|
+
'Seconds_Behind_Master' => 'slaveLag',
|
180
|
+
'Select_full_join' => 'fullJoins',
|
181
|
+
'Select_full_range_join' => 'fullRangeJoins',
|
182
|
+
'Select_range' => 'selectRange',
|
183
|
+
'Select_range_check' => 'selectRange_check',
|
184
|
+
'Select_scan' => 'selectScan',
|
185
|
+
'Slow_queries' => 'slowQueries'
|
186
|
+
},
|
187
|
+
'querycache' => {
|
188
|
+
'Qcache_queries_in_cache' => 'queriesInCache',
|
189
|
+
'Qcache_hits' => 'cacheHits',
|
190
|
+
'Qcache_inserts' => 'inserts',
|
191
|
+
'Qcache_not_cached' => 'notCached',
|
192
|
+
'Qcache_lowmem_prunes' => 'lowMemPrunes',
|
193
|
+
'Qcache_free_memory' => 'freeMemory'
|
194
|
+
},
|
195
|
+
'commands' => {
|
196
|
+
'Com_admin_commands' => 'admin_commands',
|
197
|
+
'Com_begin' => 'begin',
|
198
|
+
'Com_change_db' => 'change_db',
|
199
|
+
'Com_commit' => 'commit',
|
200
|
+
'Com_create_table' => 'create_table',
|
201
|
+
'Com_drop_table' => 'drop_table',
|
202
|
+
'Com_show_keys' => 'show_keys',
|
203
|
+
'Com_delete' => 'delete',
|
204
|
+
'Com_create_db' => 'create_db',
|
205
|
+
'Com_grant' => 'grant',
|
206
|
+
'Com_show_processlist' => 'show_processlist',
|
207
|
+
'Com_flush' => 'flush',
|
208
|
+
'Com_insert' => 'insert',
|
209
|
+
'Com_purge' => 'purge',
|
210
|
+
'Com_replace' => 'replace',
|
211
|
+
'Com_rollback' => 'rollback',
|
212
|
+
'Com_select' => 'select',
|
213
|
+
'Com_set_option' => 'set_option',
|
214
|
+
'Com_show_binlogs' => 'show_binlogs',
|
215
|
+
'Com_show_databases' => 'show_databases',
|
216
|
+
'Com_show_fields' => 'show_fields',
|
217
|
+
'Com_show_status' => 'show_status',
|
218
|
+
'Com_show_tables' => 'show_tables',
|
219
|
+
'Com_show_variables' => 'show_variables',
|
220
|
+
'Com_update' => 'update',
|
221
|
+
'Com_drop_db' => 'drop_db',
|
222
|
+
'Com_revoke' => 'revoke',
|
223
|
+
'Com_drop_user' => 'drop_user',
|
224
|
+
'Com_show_grants' => 'show_grants',
|
225
|
+
'Com_lock_tables' => 'lock_tables',
|
226
|
+
'Com_show_create_table' => 'show_create_table',
|
227
|
+
'Com_unlock_tables' => 'unlock_tables',
|
228
|
+
'Com_alter_table' => 'alter_table'
|
229
|
+
},
|
230
|
+
'counters' => {
|
231
|
+
'Handler_write' => 'handlerWrite',
|
232
|
+
'Handler_update' => 'handlerUpdate',
|
233
|
+
'Handler_delete' => 'handlerDelete',
|
234
|
+
'Handler_read_first' => 'handlerRead_first',
|
235
|
+
'Handler_read_key' => 'handlerRead_key',
|
236
|
+
'Handler_read_next' => 'handlerRead_next',
|
237
|
+
'Handler_read_prev' => 'handlerRead_prev',
|
238
|
+
'Handler_read_rnd' => 'handlerRead_rnd',
|
239
|
+
'Handler_read_rnd_next' => 'handlerRead_rnd_next',
|
240
|
+
'Handler_commit' => 'handlerCommit',
|
241
|
+
'Handler_rollback' => 'handlerRollback',
|
242
|
+
'Handler_savepoint' => 'handlerSavepoint',
|
243
|
+
'Handler_savepoint_rollback' => 'handlerSavepointRollback'
|
244
|
+
},
|
245
|
+
'innodb' => {
|
246
|
+
'Innodb_buffer_pool_pages_total' => 'bufferTotal_pages',
|
247
|
+
'Innodb_buffer_pool_pages_free' => 'bufferFree_pages',
|
248
|
+
'Innodb_buffer_pool_pages_dirty' => 'bufferDirty_pages',
|
249
|
+
'Innodb_buffer_pool_pages_data' => 'bufferUsed_pages',
|
250
|
+
'Innodb_page_size' => 'pageSize',
|
251
|
+
'Innodb_pages_created' => 'pagesCreated',
|
252
|
+
'Innodb_pages_read' => 'pagesRead',
|
253
|
+
'Innodb_pages_written' => 'pagesWritten',
|
254
|
+
'Innodb_row_lock_current_waits' => 'currentLockWaits',
|
255
|
+
'Innodb_row_lock_waits' => 'lockWaitTimes',
|
256
|
+
'Innodb_row_lock_time' => 'rowLockTime',
|
257
|
+
'Innodb_data_reads' => 'fileReads',
|
258
|
+
'Innodb_data_writes' => 'fileWrites',
|
259
|
+
'Innodb_data_fsyncs' => 'fileFsyncs',
|
260
|
+
'Innodb_log_writes' => 'logWrites',
|
261
|
+
'Innodb_rows_updated' => 'rowsUpdated',
|
262
|
+
'Innodb_rows_read' => 'rowsRead',
|
263
|
+
'Innodb_rows_deleted' => 'rowsDeleted',
|
264
|
+
'Innodb_rows_inserted' => 'rowsInserted'
|
265
|
+
},
|
266
|
+
'configuration' => {
|
267
|
+
'Max_prepared_stmt_count' => 'MaxPreparedStmtCount'
|
268
|
+
}
|
269
|
+
}
|
270
|
+
metrics
|
271
|
+
end
|
272
|
+
|
273
|
+
# Credentials
|
274
|
+
def credentials
|
275
|
+
if config[:ini]
|
276
|
+
ini = IniFile.load(config[:ini])
|
277
|
+
section = ini[config[:ini_section]]
|
278
|
+
db_user = section['user']
|
279
|
+
db_pass = section['password']
|
280
|
+
db_socket = section['socket']
|
281
|
+
else
|
282
|
+
db_user = config[:user]
|
283
|
+
db_pass = config[:password]
|
284
|
+
db_socket = config[:socket]
|
285
|
+
end
|
286
|
+
[db_user, db_pass, db_socket]
|
287
|
+
end
|
288
|
+
|
289
|
+
# Slave metrics
|
290
|
+
def slave_metrics(metrics)
|
291
|
+
# should return a single element array containing one hash
|
292
|
+
# #YELLOW
|
293
|
+
mysql_shorthostname = config[:hostname].tr('.', '_')
|
294
|
+
slave_results = Hash['a' => 100, 'b' => 200]
|
295
|
+
slave_results.first.each do |key, value|
|
296
|
+
if metrics['general'].include?(key)
|
297
|
+
# Replication lag being null is bad, very bad, so negativate it here
|
298
|
+
value = -1 if key == 'Seconds_Behind_Master' && value.nil?
|
299
|
+
output "#{config[:scheme]}.#{mysql_shorthostname}.general.#{metrics['general'][key]}", value
|
300
|
+
end
|
301
|
+
end
|
302
|
+
rescue => e
|
303
|
+
puts "Error querying slave status: #{e}" if config[:verbose]
|
304
|
+
end
|
305
|
+
|
306
|
+
# Configuration metrics
|
307
|
+
def configuration_metrics(metrics, db_user, db_pass, db_socket)
|
308
|
+
mysql_shorthostname = config[:hostname].tr('.', '_')
|
309
|
+
table = []
|
310
|
+
cmd = "#{config[:binary]} -u #{db_user} -h #{config[:hostname]} \
|
311
|
+
--port #{config[:port]} --socket #{db_socket} -p\"#{db_pass.chomp}\" --batch \
|
312
|
+
--disable-column-names -e 'SHOW GLOBAL VARIABLES;'"
|
313
|
+
stdout, _stderr, status = Open3.capture3(cmd)
|
314
|
+
puts status.to_s.split(' ')[3] if config[:verbose]
|
315
|
+
if status == 0
|
316
|
+
puts status.to_s if config[:verbose]
|
317
|
+
stdout.split("\n").each do |row|
|
318
|
+
line = row.tr("\t", ':')
|
319
|
+
key = line.split(':')[0]
|
320
|
+
value = line.split(':')[1]
|
321
|
+
table.push('Variable_name' => key, 'Value' => value)
|
322
|
+
end
|
323
|
+
else
|
324
|
+
critical "Error message: Global variables - status: #{status}"
|
325
|
+
end
|
326
|
+
variables_results = table
|
327
|
+
category = 'configuration'
|
328
|
+
variables_results.each do |row|
|
329
|
+
metrics[category].each do |metric, desc|
|
330
|
+
if metric.casecmp(row['Variable_name']) == 0
|
331
|
+
output "#{config[:scheme]}.#{mysql_shorthostname}.#{category}.#{desc}", row['Value']
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
rescue => e
|
336
|
+
puts e.message
|
337
|
+
end
|
338
|
+
|
339
|
+
# Fetch MySQL metrics
|
340
|
+
def fetcher(db_user, db_pass, db_socket)
|
341
|
+
metrics = metrics_hash
|
342
|
+
if config[:check] == 'metric'
|
343
|
+
mysql_shorthostname = config[:hostname].tr('.', '_')
|
344
|
+
begin
|
345
|
+
table = []
|
346
|
+
cmd = "#{config[:binary]} -u #{db_user} -h #{config[:hostname]} \
|
347
|
+
--port #{config[:port]} --socket #{db_socket} -p\"#{db_pass.chomp}\" --batch \
|
348
|
+
--disable-column-names -e 'SHOW GLOBAL STATUS;'"
|
349
|
+
stdout, _stderr, status = Open3.capture3(cmd)
|
350
|
+
puts status.to_s.split(' ')[3] if config[:verbose]
|
351
|
+
if status == 0
|
352
|
+
puts status.to_s if config[:verbose]
|
353
|
+
stdout.split("\n").each do |row|
|
354
|
+
line = row.tr("\t", ':')
|
355
|
+
key = line.split(':')[0]
|
356
|
+
value = line.split(':')[1]
|
357
|
+
table.push('Variable_name' => key, 'Value' => value)
|
358
|
+
end
|
359
|
+
else
|
360
|
+
critical "Error message: status: #{status}"
|
361
|
+
end
|
362
|
+
table.each do |row|
|
363
|
+
metrics.each do |category, var_mapping|
|
364
|
+
row_var_name = row['Variable_name'].to_s
|
365
|
+
var_mapping.keys.each do |vmkey|
|
366
|
+
if row_var_name.to_s == vmkey.to_s
|
367
|
+
prefix = "#{config[:scheme]}.#{mysql_shorthostname}.#{category}.#{vmkey[row_var_name]}"
|
368
|
+
output prefix, row['Value'] unless mysql_shorthostname.to_s.chomp.empty?
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
# Slave and configuration metrics here
|
374
|
+
slave_metrics(metrics)
|
375
|
+
configuration_metrics(metrics, db_user, db_pass, db_socket)
|
376
|
+
rescue => e
|
377
|
+
critical "Error message: status: #{status} | Exception: #{e.backtrace}"
|
378
|
+
ensure
|
379
|
+
ok ''
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
# Main Function
|
385
|
+
def run
|
386
|
+
ok 'Metrics deactivated by user using option --off' if config[:off] == true
|
387
|
+
begin
|
388
|
+
Timeout.timeout(config[:timeout]) do
|
389
|
+
fetcher(credentials[0], credentials[1], credentials[2])
|
390
|
+
end
|
391
|
+
rescue Timeout::Error => e
|
392
|
+
unknown "Timed out #{e.message}"
|
393
|
+
end
|
394
|
+
unknown 'Did not succeed to retrieve MySQL metrics. Check your options'
|
395
|
+
end
|
396
|
+
end
|