sensu-plugins-mysql 2.6.0 → 3.2.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 +4 -4
- data/CHANGELOG.md +37 -1
- data/README.md +13 -0
- data/bin/check-mysql-alive.rb +3 -1
- data/bin/check-mysql-connections.rb +3 -1
- data/bin/check-mysql-disk.rb +12 -15
- data/bin/check-mysql-innodb-lock.rb +3 -2
- data/bin/check-mysql-msr-replication-status.rb +15 -9
- data/bin/check-mysql-query-result-count.rb +4 -5
- data/bin/check-mysql-replication-status.rb +27 -15
- data/bin/check-mysql-select-count.rb +3 -4
- data/bin/check-mysql-status.rb +8 -4
- data/bin/check-mysql-threads.rb +3 -1
- data/bin/metrics-mysql-graphite.rb +105 -98
- data/bin/metrics-mysql-multiple-select-count.rb +112 -0
- data/bin/metrics-mysql-processes.rb +26 -17
- data/bin/metrics-mysql-query-result-count.rb +4 -5
- data/bin/metrics-mysql-raw.rb +96 -93
- data/bin/metrics-mysql-select-count.rb +101 -0
- data/bin/metrics-mysql.rb +3 -1
- data/lib/sensu-plugins-mysql.rb +2 -0
- data/lib/sensu-plugins-mysql/version.rb +4 -2
- metadata +30 -27
data/bin/check-mysql-threads.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: false
|
3
|
+
|
2
4
|
#
|
3
5
|
# check-mysql-threads.rb
|
4
6
|
#
|
@@ -117,6 +119,6 @@ class CheckMySQLHealth < Sensu::Plugin::Check::CLI
|
|
117
119
|
rescue Mysql::Error => e
|
118
120
|
critical "MySQL check failed: #{e.error}"
|
119
121
|
ensure
|
120
|
-
db
|
122
|
+
db&.close
|
121
123
|
end
|
122
124
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: false
|
3
|
+
|
2
4
|
#
|
3
5
|
# Push mysql stats into graphite
|
4
6
|
# ===
|
@@ -90,120 +92,125 @@ class MysqlGraphite < Sensu::Plugin::Metric::CLI::Graphite
|
|
90
92
|
long: '--verbose',
|
91
93
|
boolean: true
|
92
94
|
|
93
|
-
def
|
94
|
-
|
95
|
-
|
96
|
-
metrics = {
|
95
|
+
def metrics_hash
|
96
|
+
{
|
97
97
|
'general' => {
|
98
|
-
'Bytes_received' =>
|
99
|
-
'Bytes_sent' =>
|
100
|
-
'Key_read_requests' =>
|
101
|
-
'Key_reads' =>
|
102
|
-
'Key_write_requests' =>
|
103
|
-
'Key_writes' =>
|
104
|
-
'Binlog_cache_use' =>
|
105
|
-
'Binlog_cache_disk_use' =>
|
106
|
-
'Max_used_connections' =>
|
107
|
-
'Aborted_clients' =>
|
108
|
-
'Aborted_connects' =>
|
109
|
-
'Threads_connected' =>
|
110
|
-
'Open_files' =>
|
111
|
-
'Open_tables' =>
|
112
|
-
'Opened_tables' =>
|
113
|
-
'Prepared_stmt_count' =>
|
114
|
-
'Seconds_Behind_Master' =>
|
115
|
-
'Select_full_join' =>
|
98
|
+
'Bytes_received' => 'rxBytes',
|
99
|
+
'Bytes_sent' => 'txBytes',
|
100
|
+
'Key_read_requests' => 'keyRead_requests',
|
101
|
+
'Key_reads' => 'keyReads',
|
102
|
+
'Key_write_requests' => 'keyWrite_requests',
|
103
|
+
'Key_writes' => 'keyWrites',
|
104
|
+
'Binlog_cache_use' => 'binlogCacheUse',
|
105
|
+
'Binlog_cache_disk_use' => 'binlogCacheDiskUse',
|
106
|
+
'Max_used_connections' => 'maxUsedConnections',
|
107
|
+
'Aborted_clients' => 'abortedClients',
|
108
|
+
'Aborted_connects' => 'abortedConnects',
|
109
|
+
'Threads_connected' => 'threadsConnected',
|
110
|
+
'Open_files' => 'openFiles',
|
111
|
+
'Open_tables' => 'openTables',
|
112
|
+
'Opened_tables' => 'openedTables',
|
113
|
+
'Prepared_stmt_count' => 'preparedStmtCount',
|
114
|
+
'Seconds_Behind_Master' => 'slaveLag',
|
115
|
+
'Select_full_join' => 'fullJoins',
|
116
116
|
'Select_full_range_join' => 'fullRangeJoins',
|
117
|
-
'Select_range' =>
|
118
|
-
'Select_range_check' =>
|
119
|
-
'Select_scan' =>
|
120
|
-
'Slow_queries' =>
|
117
|
+
'Select_range' => 'selectRange',
|
118
|
+
'Select_range_check' => 'selectRange_check',
|
119
|
+
'Select_scan' => 'selectScan',
|
120
|
+
'Slow_queries' => 'slowQueries'
|
121
121
|
},
|
122
122
|
'querycache' => {
|
123
|
-
'Qcache_queries_in_cache' =>
|
124
|
-
'Qcache_hits' =>
|
125
|
-
'Qcache_inserts' =>
|
126
|
-
'Qcache_not_cached' =>
|
127
|
-
'Qcache_lowmem_prunes' =>
|
123
|
+
'Qcache_queries_in_cache' => 'queriesInCache',
|
124
|
+
'Qcache_hits' => 'cacheHits',
|
125
|
+
'Qcache_inserts' => 'inserts',
|
126
|
+
'Qcache_not_cached' => 'notCached',
|
127
|
+
'Qcache_lowmem_prunes' => 'lowMemPrunes'
|
128
128
|
},
|
129
129
|
'commands' => {
|
130
130
|
'Com_admin_commands' => 'admin_commands',
|
131
|
-
'Com_begin' =>
|
132
|
-
'Com_change_db' =>
|
133
|
-
'Com_commit' =>
|
134
|
-
'Com_create_table' =>
|
135
|
-
'Com_drop_table' =>
|
136
|
-
'Com_show_keys' =>
|
137
|
-
'Com_delete' =>
|
138
|
-
'Com_create_db' =>
|
139
|
-
'Com_grant' =>
|
131
|
+
'Com_begin' => 'begin',
|
132
|
+
'Com_change_db' => 'change_db',
|
133
|
+
'Com_commit' => 'commit',
|
134
|
+
'Com_create_table' => 'create_table',
|
135
|
+
'Com_drop_table' => 'drop_table',
|
136
|
+
'Com_show_keys' => 'show_keys',
|
137
|
+
'Com_delete' => 'delete',
|
138
|
+
'Com_create_db' => 'create_db',
|
139
|
+
'Com_grant' => 'grant',
|
140
140
|
'Com_show_processlist' => 'show_processlist',
|
141
|
-
'Com_flush' =>
|
142
|
-
'Com_insert' =>
|
143
|
-
'Com_purge' =>
|
144
|
-
'Com_replace' =>
|
145
|
-
'Com_rollback' =>
|
146
|
-
'Com_select' =>
|
147
|
-
'Com_set_option' =>
|
148
|
-
'Com_show_binlogs' =>
|
141
|
+
'Com_flush' => 'flush',
|
142
|
+
'Com_insert' => 'insert',
|
143
|
+
'Com_purge' => 'purge',
|
144
|
+
'Com_replace' => 'replace',
|
145
|
+
'Com_rollback' => 'rollback',
|
146
|
+
'Com_select' => 'select',
|
147
|
+
'Com_set_option' => 'set_option',
|
148
|
+
'Com_show_binlogs' => 'show_binlogs',
|
149
149
|
'Com_show_databases' => 'show_databases',
|
150
|
-
'Com_show_fields' =>
|
151
|
-
'Com_show_status' =>
|
152
|
-
'Com_show_tables' =>
|
150
|
+
'Com_show_fields' => 'show_fields',
|
151
|
+
'Com_show_status' => 'show_status',
|
152
|
+
'Com_show_tables' => 'show_tables',
|
153
153
|
'Com_show_variables' => 'show_variables',
|
154
|
-
'Com_update' =>
|
155
|
-
'Com_drop_db' =>
|
156
|
-
'Com_revoke' =>
|
157
|
-
'Com_drop_user' =>
|
158
|
-
'Com_show_grants' =>
|
159
|
-
'Com_lock_tables' =>
|
154
|
+
'Com_update' => 'update',
|
155
|
+
'Com_drop_db' => 'drop_db',
|
156
|
+
'Com_revoke' => 'revoke',
|
157
|
+
'Com_drop_user' => 'drop_user',
|
158
|
+
'Com_show_grants' => 'show_grants',
|
159
|
+
'Com_lock_tables' => 'lock_tables',
|
160
160
|
'Com_show_create_table' => 'show_create_table',
|
161
|
-
'Com_unlock_tables' =>
|
162
|
-
'Com_alter_table' =>
|
161
|
+
'Com_unlock_tables' => 'unlock_tables',
|
162
|
+
'Com_alter_table' => 'alter_table'
|
163
163
|
},
|
164
164
|
'counters' => {
|
165
|
-
'Handler_write' =>
|
166
|
-
'Handler_update' =>
|
167
|
-
'Handler_delete' =>
|
168
|
-
'Handler_read_first' =>
|
169
|
-
'Handler_read_key' =>
|
170
|
-
'Handler_read_next' =>
|
171
|
-
'Handler_read_prev' =>
|
172
|
-
'Handler_read_rnd' =>
|
173
|
-
'Handler_read_rnd_next' =>
|
174
|
-
'Handler_commit' =>
|
175
|
-
'Handler_rollback' =>
|
176
|
-
'Handler_savepoint' =>
|
165
|
+
'Handler_write' => 'handlerWrite',
|
166
|
+
'Handler_update' => 'handlerUpdate',
|
167
|
+
'Handler_delete' => 'handlerDelete',
|
168
|
+
'Handler_read_first' => 'handlerRead_first',
|
169
|
+
'Handler_read_key' => 'handlerRead_key',
|
170
|
+
'Handler_read_next' => 'handlerRead_next',
|
171
|
+
'Handler_read_prev' => 'handlerRead_prev',
|
172
|
+
'Handler_read_rnd' => 'handlerRead_rnd',
|
173
|
+
'Handler_read_rnd_next' => 'handlerRead_rnd_next',
|
174
|
+
'Handler_commit' => 'handlerCommit',
|
175
|
+
'Handler_rollback' => 'handlerRollback',
|
176
|
+
'Handler_savepoint' => 'handlerSavepoint',
|
177
177
|
'Handler_savepoint_rollback' => 'handlerSavepointRollback'
|
178
178
|
},
|
179
179
|
'innodb' => {
|
180
|
-
'Innodb_buffer_pool_pages_total' =>
|
181
|
-
'Innodb_buffer_pool_pages_free' =>
|
182
|
-
'Innodb_buffer_pool_pages_dirty' =>
|
183
|
-
'Innodb_buffer_pool_pages_data' =>
|
184
|
-
'Innodb_page_size' =>
|
185
|
-
'Innodb_pages_created' =>
|
186
|
-
'Innodb_pages_read' =>
|
187
|
-
'Innodb_pages_written' =>
|
188
|
-
'Innodb_row_lock_current_waits' =>
|
189
|
-
'Innodb_row_lock_waits' =>
|
190
|
-
'Innodb_row_lock_time' =>
|
191
|
-
'Innodb_data_reads' =>
|
192
|
-
'Innodb_data_writes' =>
|
193
|
-
'Innodb_data_fsyncs' =>
|
194
|
-
'Innodb_log_writes' =>
|
195
|
-
'Innodb_rows_updated' =>
|
196
|
-
'Innodb_rows_read' =>
|
197
|
-
'Innodb_rows_deleted' =>
|
198
|
-
'Innodb_rows_inserted' =>
|
180
|
+
'Innodb_buffer_pool_pages_total' => 'bufferTotal_pages',
|
181
|
+
'Innodb_buffer_pool_pages_free' => 'bufferFree_pages',
|
182
|
+
'Innodb_buffer_pool_pages_dirty' => 'bufferDirty_pages',
|
183
|
+
'Innodb_buffer_pool_pages_data' => 'bufferUsed_pages',
|
184
|
+
'Innodb_page_size' => 'pageSize',
|
185
|
+
'Innodb_pages_created' => 'pagesCreated',
|
186
|
+
'Innodb_pages_read' => 'pagesRead',
|
187
|
+
'Innodb_pages_written' => 'pagesWritten',
|
188
|
+
'Innodb_row_lock_current_waits' => 'currentLockWaits',
|
189
|
+
'Innodb_row_lock_waits' => 'lockWaitTimes',
|
190
|
+
'Innodb_row_lock_time' => 'rowLockTime',
|
191
|
+
'Innodb_data_reads' => 'fileReads',
|
192
|
+
'Innodb_data_writes' => 'fileWrites',
|
193
|
+
'Innodb_data_fsyncs' => 'fileFsyncs',
|
194
|
+
'Innodb_log_writes' => 'logWrites',
|
195
|
+
'Innodb_rows_updated' => 'rowsUpdated',
|
196
|
+
'Innodb_rows_read' => 'rowsRead',
|
197
|
+
'Innodb_rows_deleted' => 'rowsDeleted',
|
198
|
+
'Innodb_rows_inserted' => 'rowsInserted'
|
199
199
|
},
|
200
200
|
'configuration' => {
|
201
|
-
'max_connections'
|
202
|
-
'Max_prepared_stmt_count' =>
|
201
|
+
'max_connections' => 'MaxConnections',
|
202
|
+
'Max_prepared_stmt_count' => 'MaxPreparedStmtCount'
|
203
203
|
}
|
204
204
|
}
|
205
|
+
end
|
206
|
+
|
207
|
+
def run
|
208
|
+
# props to https://github.com/coredump/hoardd/blob/master/scripts-available/mysql.coffee
|
209
|
+
|
210
|
+
metrics = metrics_hash
|
205
211
|
|
206
|
-
|
212
|
+
# FIXME: break this up
|
213
|
+
config[:host].split(' ').each do |mysql_host| # rubocop:disable Metrics/BlockLength
|
207
214
|
mysql_shorthostname = mysql_host.split('.')[0]
|
208
215
|
if config[:ini]
|
209
216
|
ini = IniFile.load(config[:ini])
|
@@ -218,7 +225,7 @@ class MysqlGraphite < Sensu::Plugin::Metric::CLI::Graphite
|
|
218
225
|
mysql = Mysql.new(mysql_host, db_user, db_pass, nil, config[:port], config[:socket])
|
219
226
|
|
220
227
|
results = mysql.query('SHOW GLOBAL STATUS')
|
221
|
-
rescue => e
|
228
|
+
rescue StandardError => e
|
222
229
|
puts e.message
|
223
230
|
end
|
224
231
|
|
@@ -241,7 +248,7 @@ class MysqlGraphite < Sensu::Plugin::Metric::CLI::Graphite
|
|
241
248
|
output "#{config[:scheme]}.#{mysql_shorthostname}.general.#{metrics['general'][key]}", value
|
242
249
|
end
|
243
250
|
end
|
244
|
-
rescue => e
|
251
|
+
rescue StandardError => e
|
245
252
|
puts "Error querying slave status: #{e}" if config[:verbose]
|
246
253
|
end
|
247
254
|
|
@@ -251,16 +258,16 @@ class MysqlGraphite < Sensu::Plugin::Metric::CLI::Graphite
|
|
251
258
|
category = 'configuration'
|
252
259
|
variables_results.each_hash do |row|
|
253
260
|
metrics[category].each do |metric, desc|
|
254
|
-
if metric.casecmp(row['Variable_name'])
|
261
|
+
if metric.casecmp(row['Variable_name']).zero?
|
255
262
|
output "#{config[:scheme]}.#{mysql_shorthostname}.#{category}.#{desc}", row['Value']
|
256
263
|
end
|
257
264
|
end
|
258
265
|
end
|
259
|
-
rescue => e
|
266
|
+
rescue StandardError => e
|
260
267
|
puts e.message
|
261
268
|
end
|
262
269
|
|
263
|
-
mysql
|
270
|
+
mysql&.close
|
264
271
|
end
|
265
272
|
|
266
273
|
ok
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: false
|
3
|
+
|
4
|
+
#
|
5
|
+
# MySQL Select Count Metrics
|
6
|
+
#
|
7
|
+
# Creates a graphite-formatted metrics for the first values of a result set from MySQL queries
|
8
|
+
# defined as a JSON parameter.
|
9
|
+
#
|
10
|
+
# Copyright 2017 Andrew Thal <athal7@me.com>
|
11
|
+
# Copyright 2018 Tibor Nagy <nagyt@hu.inter.net>
|
12
|
+
#
|
13
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
14
|
+
# for details.
|
15
|
+
|
16
|
+
require 'sensu-plugin/metric/cli'
|
17
|
+
require 'mysql'
|
18
|
+
require 'inifile'
|
19
|
+
require 'json'
|
20
|
+
|
21
|
+
class MysqlQueryCountMetric < Sensu::Plugin::Metric::CLI::Graphite
|
22
|
+
option :host,
|
23
|
+
short: '-h HOST',
|
24
|
+
long: '--host HOST',
|
25
|
+
description: 'MySQL Host to connect to',
|
26
|
+
required: true
|
27
|
+
|
28
|
+
option :port,
|
29
|
+
short: '-P PORT',
|
30
|
+
long: '--port PORT',
|
31
|
+
description: 'MySQL Port to connect to',
|
32
|
+
proc: proc(&:to_i),
|
33
|
+
default: 3306
|
34
|
+
|
35
|
+
option :username,
|
36
|
+
short: '-u USERNAME',
|
37
|
+
long: '--user USERNAME',
|
38
|
+
description: 'MySQL Username'
|
39
|
+
|
40
|
+
option :password,
|
41
|
+
short: '-p PASSWORD',
|
42
|
+
long: '--pass PASSWORD',
|
43
|
+
description: 'MySQL password'
|
44
|
+
|
45
|
+
option :database,
|
46
|
+
short: '-d DATABASE',
|
47
|
+
long: '--database DATABASE',
|
48
|
+
description: 'MySQL database',
|
49
|
+
default: ''
|
50
|
+
|
51
|
+
option :ini,
|
52
|
+
short: '-i',
|
53
|
+
long: '--ini VALUE',
|
54
|
+
description: 'My.cnf ini file'
|
55
|
+
|
56
|
+
option :ini_section,
|
57
|
+
description: 'Section in my.cnf ini file',
|
58
|
+
long: '--ini-section VALUE',
|
59
|
+
default: 'client'
|
60
|
+
|
61
|
+
option :socket,
|
62
|
+
short: '-S SOCKET',
|
63
|
+
long: '--socket SOCKET',
|
64
|
+
description: 'MySQL Unix socket to connect to'
|
65
|
+
|
66
|
+
option :name,
|
67
|
+
short: '-n NAME',
|
68
|
+
long: '--name NAME',
|
69
|
+
description: 'Metric name for a configured handler',
|
70
|
+
default: 'mysql.query_count'
|
71
|
+
|
72
|
+
option :query,
|
73
|
+
short: '-q SELECT_COUNT_QUERIES',
|
74
|
+
long: '--query SELECT_COUNT_QUERIES',
|
75
|
+
description: 'Queries to execute in JSON',
|
76
|
+
required: true
|
77
|
+
|
78
|
+
def run
|
79
|
+
if config[:ini]
|
80
|
+
ini = IniFile.load(config[:ini])
|
81
|
+
section = ini[config[:ini_section]]
|
82
|
+
db_user = section['user']
|
83
|
+
db_pass = section['password']
|
84
|
+
else
|
85
|
+
db_user = config[:username]
|
86
|
+
db_pass = config[:password]
|
87
|
+
end
|
88
|
+
|
89
|
+
begin
|
90
|
+
query_hash = ::JSON.parse config[:query]
|
91
|
+
rescue ::JSON::ParserError => e
|
92
|
+
critical "JSON.parse error: #{e}"
|
93
|
+
end
|
94
|
+
|
95
|
+
# traverse all SQL
|
96
|
+
query_hash.each do |key, sql|
|
97
|
+
raise "invalid query : #{sql}" unless sql =~ /^select\s+count\(\s*\*\s*\)/i
|
98
|
+
|
99
|
+
db = Mysql.real_connect(config[:host], db_user, db_pass, config[:database], config[:port], config[:socket])
|
100
|
+
count = db.query(sql).fetch_row[0].to_i
|
101
|
+
|
102
|
+
output "#{config[:name]}.#{key}", count
|
103
|
+
end
|
104
|
+
|
105
|
+
ok
|
106
|
+
rescue Mysql::Error => e
|
107
|
+
errstr = "Error code: #{e.errno} Error message: #{e.error}"
|
108
|
+
critical "#{errstr} SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate')
|
109
|
+
rescue StandardError => e
|
110
|
+
critical "unhandled exception: #{e}"
|
111
|
+
end
|
112
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: false
|
3
|
+
|
2
4
|
#
|
3
5
|
# metrics-mysql-processes
|
4
6
|
#
|
@@ -94,33 +96,40 @@ class MetricsMySQLProcesses < Sensu::Plugin::Metric::CLI::Graphite
|
|
94
96
|
long: '--socket SOCKET',
|
95
97
|
description: 'MySQL Unix socket to connect to'
|
96
98
|
|
99
|
+
def set_default_metrics
|
100
|
+
{
|
101
|
+
'user' => {},
|
102
|
+
'database' => {},
|
103
|
+
'command' => {}
|
104
|
+
}.each_value { |value| value.default = 0 }
|
105
|
+
end
|
106
|
+
|
107
|
+
def db_connection_creds
|
108
|
+
if config[:ini]
|
109
|
+
ini = IniFile.load(config[:ini])
|
110
|
+
section = ini[config[:ini_section]]
|
111
|
+
db_user = section['user']
|
112
|
+
db_pass = section['password']
|
113
|
+
else
|
114
|
+
db_user = config[:username]
|
115
|
+
db_pass = config[:password]
|
116
|
+
end
|
117
|
+
[db_user, db_pass]
|
118
|
+
end
|
119
|
+
|
97
120
|
def run
|
98
121
|
config[:host].split(' ').each do |mysql_host|
|
99
122
|
mysql_shorthostname = mysql_host.split('.')[0]
|
100
|
-
|
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
|
123
|
+
db_user, db_pass = db_connection_creds
|
109
124
|
begin
|
110
125
|
mysql = Mysql.new(mysql_host, db_user, db_pass, nil, config[:port], config[:socket])
|
111
126
|
|
112
127
|
results = mysql.query('SHOW PROCESSLIST')
|
113
|
-
rescue => e
|
128
|
+
rescue StandardError => e
|
114
129
|
unknown "Unable to query MySQL: #{e.message}"
|
115
130
|
end
|
116
131
|
|
117
|
-
metrics =
|
118
|
-
'user' => {},
|
119
|
-
'database' => {},
|
120
|
-
'command' => {}
|
121
|
-
}
|
122
|
-
|
123
|
-
metrics.each_value { |value| value.default = 0 }
|
132
|
+
metrics = set_default_metrics
|
124
133
|
|
125
134
|
results.each_hash do |row|
|
126
135
|
metrics['user'][row['User']] += 1
|