sensu-plugins-mysql-boutetnico 1.0.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.
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # MySQL Select Count Metrics
4
+ #
5
+ # Creates a graphite-formatted metrics for the first values of a result set from MySQL queries
6
+ # defined as a JSON parameter.
7
+ #
8
+ # Copyright 2017 Andrew Thal <athal7@me.com>
9
+ # Copyright 2018 Tibor Nagy <nagyt@hu.inter.net>
10
+ #
11
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
12
+ # for details.
13
+
14
+ require 'sensu-plugin/metric/cli'
15
+ require 'mysql'
16
+ require 'inifile'
17
+ require 'json'
18
+
19
+ class MysqlQueryCountMetric < Sensu::Plugin::Metric::CLI::Graphite
20
+ option :host,
21
+ short: '-h HOST',
22
+ long: '--host HOST',
23
+ description: 'MySQL Host to connect to',
24
+ required: true
25
+
26
+ option :port,
27
+ short: '-P PORT',
28
+ long: '--port PORT',
29
+ description: 'MySQL Port to connect to',
30
+ proc: proc(&:to_i),
31
+ default: 3306
32
+
33
+ option :username,
34
+ short: '-u USERNAME',
35
+ long: '--user USERNAME',
36
+ description: 'MySQL Username'
37
+
38
+ option :password,
39
+ short: '-p PASSWORD',
40
+ long: '--pass PASSWORD',
41
+ description: 'MySQL password'
42
+
43
+ option :database,
44
+ short: '-d DATABASE',
45
+ long: '--database DATABASE',
46
+ description: 'MySQL database',
47
+ default: ''
48
+
49
+ option :ini,
50
+ short: '-i',
51
+ long: '--ini VALUE',
52
+ description: 'My.cnf ini file'
53
+
54
+ option :ini_section,
55
+ description: 'Section in my.cnf ini file',
56
+ long: '--ini-section VALUE',
57
+ default: 'client'
58
+
59
+ option :socket,
60
+ short: '-S SOCKET',
61
+ long: '--socket SOCKET',
62
+ description: 'MySQL Unix socket to connect to'
63
+
64
+ option :name,
65
+ short: '-n NAME',
66
+ long: '--name NAME',
67
+ description: 'Metric name for a configured handler',
68
+ default: 'mysql.query_count'
69
+
70
+ option :query,
71
+ short: '-q SELECT_COUNT_QUERIES',
72
+ long: '--query SELECT_COUNT_QUERIES',
73
+ description: 'Queries to execute in JSON',
74
+ required: true
75
+
76
+ def run
77
+ if config[:ini]
78
+ ini = IniFile.load(config[:ini])
79
+ section = ini[config[:ini_section]]
80
+ db_user = section['user']
81
+ db_pass = section['password']
82
+ else
83
+ db_user = config[:username]
84
+ db_pass = config[:password]
85
+ end
86
+
87
+ begin
88
+ query_hash = ::JSON.parse config[:query]
89
+ rescue ::JSON::ParserError => e
90
+ critical "JSON.parse error: #{e}"
91
+ end
92
+
93
+ # traverse all SQL
94
+ query_hash.each do |key, sql|
95
+ raise "invalid query : #{sql}" unless sql =~ /^select\s+count\(\s*\*\s*\)/i
96
+
97
+ db = Mysql.real_connect(config[:host], db_user, db_pass, config[:database], config[:port], config[:socket])
98
+ count = db.query(sql).fetch_row[0].to_i
99
+
100
+ output "#{config[:name]}.#{key}", count
101
+ end
102
+
103
+ ok
104
+ rescue Mysql::Error => e
105
+ errstr = "Error code: #{e.errno} Error message: #{e.error}"
106
+ critical "#{errstr} SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate')
107
+ rescue StandardError => e
108
+ critical "unhandled exception: #{e}"
109
+ end
110
+ end
@@ -0,0 +1,149 @@
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 set_default_metrics
98
+ {
99
+ 'user' => {},
100
+ 'database' => {},
101
+ 'command' => {},
102
+ }.each_value { |value| value.default = 0 }
103
+ end
104
+
105
+ def db_connection_creds
106
+ if config[:ini]
107
+ ini = IniFile.load(config[:ini])
108
+ section = ini[config[:ini_section]]
109
+ db_user = section['user']
110
+ db_pass = section['password']
111
+ else
112
+ db_user = config[:username]
113
+ db_pass = config[:password]
114
+ end
115
+ [db_user, db_pass]
116
+ end
117
+
118
+ def run
119
+ config[:host].split(' ').each do |mysql_host|
120
+ mysql_shorthostname = mysql_host.split('.')[0]
121
+ db_user, db_pass = db_connection_creds
122
+ begin
123
+ mysql = Mysql.new(mysql_host, db_user, db_pass, nil, config[:port], config[:socket])
124
+
125
+ results = mysql.query('SHOW PROCESSLIST')
126
+ rescue StandardError => e
127
+ unknown "Unable to query MySQL: #{e.message}"
128
+ end
129
+
130
+ metrics = set_default_metrics
131
+
132
+ results.each_hash do |row|
133
+ metrics['user'][row['User']] += 1
134
+ if row['db'] # If no database has been selected by the process, it is set to nil.
135
+ metrics['database'][row['db']] += 1
136
+ end
137
+ metrics['command'][row['Command']] += 1
138
+ end
139
+
140
+ metrics.each do |key, value|
141
+ value.each do |instance, count|
142
+ output "#{config[:scheme]}.#{mysql_shorthostname}.#{key}.#{instance}", count
143
+ end
144
+ end
145
+ end
146
+
147
+ ok
148
+ end
149
+ end
@@ -0,0 +1,97 @@
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
+ rescue Mysql::Error => e
90
+ errstr = "Error code: #{e.errno} Error message: #{e.error}"
91
+ critical "#{errstr} SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate')
92
+ rescue StandardError => e
93
+ critical e
94
+ ensure
95
+ db.close if db
96
+ end
97
+ end
@@ -0,0 +1,397 @@
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 StandardError => 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 StandardError => 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
+ # FIXME: this needs refactoring
343
+ if config[:check] == 'metric' # rubocop:disable Style/GuardClause
344
+ mysql_shorthostname = config[:hostname].tr('.', '_')
345
+ begin
346
+ table = []
347
+ cmd = "#{config[:binary]} -u #{db_user} -h #{config[:hostname]} \
348
+ --port #{config[:port]} --socket #{db_socket} -p\"#{db_pass.chomp}\" --batch \
349
+ --disable-column-names -e 'SHOW GLOBAL STATUS;'"
350
+ stdout, _stderr, status = Open3.capture3(cmd)
351
+ puts status.to_s.split(' ')[3] if config[:verbose]
352
+ if status == 0
353
+ puts status.to_s if config[:verbose]
354
+ stdout.split("\n").each do |row|
355
+ line = row.tr("\t", ':')
356
+ key = line.split(':')[0]
357
+ value = line.split(':')[1]
358
+ table.push('Variable_name' => key, 'Value' => value)
359
+ end
360
+ else
361
+ critical "Error message: status: #{status}"
362
+ end
363
+ table.each do |row|
364
+ metrics.each do |category, var_mapping|
365
+ row_var_name = row['Variable_name'].to_s
366
+ var_mapping.each_key do |vmkey|
367
+ if row_var_name.to_s == vmkey.to_s
368
+ prefix = "#{config[:scheme]}.#{mysql_shorthostname}.#{category}.#{vmkey[row_var_name]}"
369
+ output prefix, row['Value'] unless mysql_shorthostname.to_s.chomp.empty?
370
+ end
371
+ end
372
+ end
373
+ end
374
+ # Slave and configuration metrics here
375
+ slave_metrics(metrics)
376
+ configuration_metrics(metrics, db_user, db_pass, db_socket)
377
+ rescue StandardError => e
378
+ critical "Error message: status: #{status} | Exception: #{e.backtrace}"
379
+ ensure
380
+ ok ''
381
+ end
382
+ end
383
+ end
384
+
385
+ # Main Function
386
+ def run
387
+ ok 'Metrics deactivated by user using option --off' if config[:off] == true
388
+ begin
389
+ Timeout.timeout(config[:timeout]) do
390
+ fetcher(credentials[0], credentials[1], credentials[2])
391
+ end
392
+ rescue Timeout::Error => e
393
+ unknown "Timed out #{e.message}"
394
+ end
395
+ unknown 'Did not succeed to retrieve MySQL metrics. Check your options'
396
+ end
397
+ end