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.
@@ -0,0 +1,140 @@
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
+ require 'inifile'
16
+
17
+ class CheckMysqlDisk < Sensu::Plugin::Check::CLI
18
+ option :host,
19
+ short: '-h',
20
+ long: '--host=VALUE',
21
+ description: 'Database host'
22
+
23
+ option :user,
24
+ short: '-u',
25
+ long: '--username=VALUE',
26
+ description: 'Database username'
27
+
28
+ option :pass,
29
+ short: '-p',
30
+ long: '--password=VALUE',
31
+ description: 'Database password'
32
+
33
+ option :ini,
34
+ description: 'My.cnf ini file',
35
+ short: '-i',
36
+ long: '--ini VALUE'
37
+
38
+ option :ini_section,
39
+ description: 'Section in my.cnf ini file',
40
+ long: '--ini-section VALUE',
41
+ default: 'client'
42
+
43
+ option :size,
44
+ short: '-s',
45
+ long: '--size=VALUE',
46
+ description: 'Database size',
47
+ proc: proc(&:to_f),
48
+ required: true
49
+
50
+ option :warn,
51
+ short: '-w',
52
+ long: '--warning=VALUE',
53
+ description: 'Warning threshold',
54
+ proc: proc(&:to_f),
55
+ default: '85'
56
+
57
+ option :crit,
58
+ short: '-c',
59
+ long: '--critical=VALUE',
60
+ description: 'Critical threshold',
61
+ proc: proc(&:to_f),
62
+ default: '95'
63
+
64
+ option :port,
65
+ description: 'Port to connect to',
66
+ short: '-P PORT',
67
+ long: '--port PORT',
68
+ proc: proc(&:to_i),
69
+ default: '3306'
70
+
71
+ option :socket,
72
+ description: 'Socket to use',
73
+ short: '-S SOCKET',
74
+ long: '--socket SOCKET',
75
+ default: nil
76
+
77
+ def run
78
+ if config[:ini]
79
+ ini = IniFile.load(config[:ini])
80
+ section = ini[config[:ini_section]]
81
+ db_user = section['user']
82
+ db_pass = section['password']
83
+ else
84
+ db_user = config[:user]
85
+ db_pass = config[:pass]
86
+ end
87
+ db_host = config[:host]
88
+ disk_size = config[:size]
89
+ critical_usage = config[:crit]
90
+ warning_usage = config[:warn]
91
+
92
+ if [db_host, db_user, db_pass, disk_size].any?(&:nil?)
93
+ unknown 'Must specify host, user, password and size'
94
+ end
95
+
96
+ begin
97
+ total_size = 0.0
98
+ db = Mysql.real_connect(config[:host], db_user, db_pass, nil, config[:port], config[:socket])
99
+
100
+ results = db.query <<-EOSQL
101
+ SELECT table_schema,
102
+ count(*) TABLES,
103
+ concat(round(sum(table_rows)/1000000,2),'M') rows,
104
+ round(sum(data_length)/(1024*1024*1024),2) DATA,
105
+ round(sum(index_length)/(1024*1024*1024),2) idx,
106
+ round(sum(data_length+index_length)/(1024*1024*1024),2) total_size,
107
+ round(sum(index_length)/sum(data_length),2) idxfrac
108
+ FROM information_schema.TABLES group by table_schema
109
+ EOSQL
110
+
111
+ unless results.nil?
112
+ results.each_hash do |row|
113
+ # #YELLOW
114
+ total_size = total_size + row['total_size'].to_f # rubocop:disable Style/SelfAssignment
115
+ end
116
+ end
117
+
118
+ disk_use_percentage = total_size / disk_size * 100
119
+ diskstr = "DB size: #{total_size}, disk use: #{disk_use_percentage}%"
120
+
121
+ if disk_use_percentage > critical_usage
122
+ critical "Database size exceeds critical threshold: #{diskstr}"
123
+ elsif disk_use_percentage > warning_usage
124
+ warning "Database size exceeds warning threshold: #{diskstr}"
125
+ else
126
+ ok diskstr
127
+ end
128
+
129
+ rescue Mysql::Error => e
130
+ errstr = "Error code: #{e.errno} Error message: #{e.error}"
131
+ critical "#{errstr} SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate')
132
+
133
+ rescue => e
134
+ critical e
135
+
136
+ ensure
137
+ db.close if db
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,149 @@
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
+ require 'inifile'
16
+
17
+ class CheckMySQLInnoDBLock < Sensu::Plugin::Check::CLI
18
+ option :user,
19
+ description: 'MySQL User',
20
+ short: '-u USER',
21
+ long: '--user USER',
22
+ default: 'root'
23
+
24
+ option :password,
25
+ description: 'MySQL Password',
26
+ short: '-p PASS',
27
+ long: '--password PASS'
28
+
29
+ option :ini,
30
+ description: 'My.cnf ini file',
31
+ short: '-i',
32
+ long: '--ini VALUE'
33
+
34
+ option :ini_section,
35
+ description: 'Section in my.cnf ini file',
36
+ long: '--ini-section VALUE',
37
+ default: 'client'
38
+
39
+ option :hostname,
40
+ description: 'Hostname to login to',
41
+ short: '-h HOST',
42
+ long: '--hostname HOST',
43
+ default: 'localhost'
44
+
45
+ option :port,
46
+ description: 'Port to connect to',
47
+ short: '-P PORT',
48
+ long: '--port PORT',
49
+ default: '3306'
50
+
51
+ option :socket,
52
+ description: 'Socket to use',
53
+ short: '-s SOCKET',
54
+ long: '--socket SOCKET'
55
+
56
+ option :warn,
57
+ description: 'Warning threshold',
58
+ short: '-w SECONDS',
59
+ long: '--warning SECONDS',
60
+ default: 5
61
+
62
+ option :crit,
63
+ description: 'Critical threshold',
64
+ short: '-c SECONDS',
65
+ long: '--critical SECONDS',
66
+ default: 10
67
+
68
+ def run
69
+ if config[:ini]
70
+ ini = IniFile.load(config[:ini])
71
+ section = ini[config[:ini_section]]
72
+ db_user = section['user']
73
+ db_pass = section['password']
74
+ else
75
+ db_user = config[:user]
76
+ db_pass = config[:password]
77
+ end
78
+ db = Mysql.new(config[:hostname], db_user, db_pass, config[:database], config[:port].to_i, config[:socket])
79
+
80
+ warn = config[:warn].to_i
81
+ crit = config[:crit].to_i
82
+
83
+ res = db.query <<-EQSQL
84
+ select
85
+ t_b.trx_mysql_thread_id blocking_id,
86
+ t_w.trx_mysql_thread_id requesting_id,
87
+ p_b.HOST blocking_host,
88
+ p_w.HOST requesting_host,
89
+ l.lock_table lock_table,
90
+ l.lock_index lock_index,
91
+ l.lock_mode lock_mode,
92
+ p_w.TIME seconds,
93
+ p_b.INFO blocking_info,
94
+ p_w.INFO requesting_info
95
+ from
96
+ information_schema.INNODB_LOCK_WAITS w,
97
+ information_schema.INNODB_LOCKS l,
98
+ information_schema.INNODB_TRX t_b,
99
+ information_schema.INNODB_TRX t_w,
100
+ information_schema.PROCESSLIST p_b,
101
+ information_schema.PROCESSLIST p_w
102
+ where
103
+ w.blocking_lock_id = l.lock_id
104
+ and
105
+ w.blocking_trx_id = t_b.trx_id
106
+ and
107
+ w.requesting_trx_id = t_w.trx_id
108
+ and
109
+ t_b.trx_mysql_thread_id = p_b.ID
110
+ and
111
+ t_w.trx_mysql_thread_id = p_w.ID
112
+ and
113
+ p_w.TIME > #{warn}
114
+ order by
115
+ requesting_id,blocking_id
116
+ EQSQL
117
+
118
+ lock_info = []
119
+ is_crit = false
120
+ res.each_hash do |row|
121
+ h = {}
122
+ is_crit = true if row['seconds'].to_i > crit
123
+ h['blocking_id'] = row['blocking_id']
124
+ h['requesting_id'] = row['requesting_id']
125
+ h['blocking_host'] = row['blocking_host']
126
+ h['requesting_host'] = row['requesting_host']
127
+ h['lock_table'] = row['lock_table']
128
+ h['lock_index'] = row['lock_index']
129
+ h['lock_mode'] = row['lock_mode']
130
+ h['seconds'] = row['seconds']
131
+ h['blocking_info'] = row['blocking_info']
132
+ h['requesting_info'] = row['requesting_info']
133
+ lock_info.push(h)
134
+ end
135
+
136
+ if lock_info.length == 0 # rubocop:disable Style/ZeroLengthPredicate
137
+ ok
138
+ elsif is_crit == false
139
+ warning "Detected Locks #{lock_info}"
140
+ else
141
+ critical "Detected Locks #{lock_info}"
142
+ end
143
+
144
+ rescue Mysql::Error => e
145
+ critical "MySQL check failed: #{e.error}"
146
+ ensure
147
+ db.close if db
148
+ end
149
+ end
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # MySQL Multi-source Replication Status
4
+ # ===
5
+ #
6
+ #
7
+ # EXAMPLE
8
+ # check-mysql-msr-replication-status.rb -h db01 --ini '/etc/sensu/my.cnf'
9
+ # check-mysql-msr-replication-status.rb -h db01 --ini '/etc/sensu/my.cnf' --ini-section customsection
10
+ #
11
+ # MY.CNF INI FORMAT
12
+ # [client]
13
+ # user=sensu
14
+ # password="abcd1234"
15
+ #
16
+ # [customsection]
17
+ # user=user
18
+ # password="password"
19
+ #
20
+
21
+ require 'sensu-plugin/check/cli'
22
+ require 'mysql'
23
+ require 'inifile'
24
+
25
+ class CheckMysqlMSRReplicationStatus < Sensu::Plugin::Check::CLI
26
+ option :host,
27
+ short: '-h',
28
+ long: '--host VALUE',
29
+ description: 'Database host'
30
+
31
+ option :port,
32
+ short: '-P',
33
+ long: '--port VALUE',
34
+ description: 'Database port',
35
+ default: 3306,
36
+ proc: proc(&:to_i)
37
+
38
+ option :socket,
39
+ short: '-s SOCKET',
40
+ long: '--socket SOCKET',
41
+ description: 'Socket to use'
42
+
43
+ option :user,
44
+ short: '-u',
45
+ long: '--username VALUE',
46
+ description: 'Database username'
47
+
48
+ option :pass,
49
+ short: '-p',
50
+ long: '--password VALUE',
51
+ description: 'Database password'
52
+
53
+ option :ini,
54
+ short: '-i',
55
+ long: '--ini VALUE',
56
+ description: 'My.cnf ini file'
57
+
58
+ option :ini_section,
59
+ description: 'Section in my.cnf ini file',
60
+ long: '--ini-section VALUE',
61
+ default: 'client'
62
+
63
+ option :warn,
64
+ short: '-w',
65
+ long: '--warning VALUE',
66
+ description: 'Warning threshold for replication lag',
67
+ default: 900,
68
+ proc: proc(&:to_i)
69
+
70
+ option :crit,
71
+ short: '-c',
72
+ long: '--critical=VALUE',
73
+ description: 'Critical threshold for replication lag',
74
+ default: 1800,
75
+ proc: proc(&:to_i)
76
+
77
+ def run
78
+ if config[:ini]
79
+ ini = IniFile.load(config[:ini])
80
+ section = ini[config[:ini_section]]
81
+ db_user = section['user']
82
+ db_pass = section['password']
83
+ else
84
+ db_user = config[:user]
85
+ db_pass = config[:pass]
86
+ end
87
+ db_host = config[:host]
88
+
89
+ if [db_host, db_user, db_pass].any?(&:nil?)
90
+ unknown 'Must specify host, user, password'
91
+ end
92
+
93
+ begin
94
+ ok_statuses = []
95
+ warn_statuses = []
96
+ crit_statuses = []
97
+ output = []
98
+
99
+ db = Mysql.new(db_host, db_user, db_pass, nil, config[:port], config[:socket])
100
+ channels = db.query('SELECT channel_name FROM performance_schema.replication_connection_status')
101
+
102
+ channels.num_rows.times do
103
+ channel = channels.fetch_hash
104
+ results = db.query("SHOW SLAVE STATUS FOR CHANNEL \'#{channel['channel_name']}\'")
105
+ results.each_hash do |row|
106
+ io_thread_status = row['Slave_IO_Running']
107
+ sql_thread_status = row['Slave_SQL_Running']
108
+ seconds_behind_master = row['Seconds_Behind_Master'].to_i
109
+ status = 0
110
+ if io_thread_status == 'No' || sql_thread_status == 'No' || seconds_behind_master > config[:crit]
111
+ status = 2
112
+ end
113
+ if seconds_behind_master > config[:warn] && seconds_behind_master <= config[:crit]
114
+ status = 1
115
+ end
116
+ message = "#{channel['channel_name']} STATES:"
117
+ message += " Slave_IO_Running=#{io_thread_status}"
118
+ message += ", Slave_SQL_Running=#{sql_thread_status}"
119
+ message += ", Seconds_Behind_Master=#{seconds_behind_master}"
120
+
121
+ if status.zero?
122
+ ok_statuses << message
123
+ elsif status == 1
124
+ warn_statuses << message
125
+ elsif status == 2
126
+ crit_statuses << message
127
+ else
128
+ puts 'Undefined status.'
129
+ end
130
+ end
131
+ end
132
+ output << crit_statuses unless crit_statuses.empty?
133
+ output << warn_statuses unless warn_statuses.empty?
134
+ output << ok_statuses unless ok_statuses.empty?
135
+
136
+ if !crit_statuses.empty?
137
+ critical output
138
+ elsif !warn_statuses.empty?
139
+ warning output
140
+ else
141
+ ok output
142
+ end
143
+ rescue Mysql::Error => e
144
+ errstr = "Error code: #{e.errno} Error message: #{e.error}"
145
+ errstr += "SQLSTATE: #{e.sqlstate}" if e.respond_to?('sqlstate')
146
+ critical errstr
147
+ rescue StandardError => e
148
+ critical "unhandled exception: #{e}"
149
+ ensure
150
+ db.close if db
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # MySQL Query Result Count Check
4
+ #
5
+ # Checks 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/check/cli'
13
+ require 'mysql'
14
+ require 'inifile'
15
+
16
+ class MysqlQueryCountCheck < Sensu::Plugin::Check::CLI
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
+ required: true
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 :warn,
63
+ short: '-w COUNT',
64
+ long: '--warning COUNT',
65
+ description: 'COUNT warning threshold for number of items returned by the query',
66
+ proc: proc(&:to_i),
67
+ required: true
68
+
69
+ option :crit,
70
+ short: '-c COUNT',
71
+ long: '--critical COUNT',
72
+ description: 'COUNT critical threshold for number of items returned by the query',
73
+ proc: proc(&:to_i),
74
+ required: true
75
+
76
+ option :query,
77
+ short: '-q QUERY',
78
+ long: '--query QUERY',
79
+ description: 'Query to execute',
80
+ required: true
81
+
82
+ def run
83
+ if config[:ini]
84
+ ini = IniFile.load(config[:ini])
85
+ section = ini[config[:ini_section]]
86
+ db_user = section['user']
87
+ db_pass = section['password']
88
+ else
89
+ db_user = config[:username]
90
+ db_pass = config[:password]
91
+ end
92
+ db = Mysql.real_connect(config[:host], db_user, db_pass, config[:database], config[:port].to_i, config[:socket])
93
+ length = db.query(config[:query]).count
94
+
95
+ if length >= config[:crit]
96
+ critical "Result count is above the CRITICAL limit: #{length} length / #{config[:crit]} limit"
97
+ elsif length >= config[:warn]
98
+ warning "Result count is above the WARNING limit: #{length} length / #{config[:warn]} limit"
99
+ else
100
+ ok 'Result count length is below thresholds'
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