sensu-plugins-postgres-mrtrotl 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # metric-postgres-statstable
6
+ #
7
+ # DESCRIPTION:
8
+ #
9
+ # This plugin collects postgres database metrics from the pg_stat tables
10
+ #
11
+ # OUTPUT:
12
+ # metric data
13
+ #
14
+ # PLATFORMS:
15
+ # Linux
16
+ #
17
+ # DEPENDENCIES:
18
+ # gem: sensu-plugin
19
+ # gem: pg
20
+ #
21
+ # USAGE:
22
+ # ./metric-postgres-statstable.rb -u db_user -p db_pass -h db_host -d db -s scope
23
+ #
24
+ # NOTES:
25
+ # Requires PSQL `track_counts` enabled
26
+ #
27
+ # LICENSE:
28
+ # Copyright (c) 2012 Kwarter, Inc <platforms@kwarter.com>
29
+ # Author Gilles Devaux <gilles.devaux@gmail.com>
30
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
31
+ # for details.
32
+ #
33
+
34
+ require 'sensu-plugins-postgres/pgpass'
35
+ require 'sensu-plugin/metric/cli'
36
+ require 'pg'
37
+ require 'socket'
38
+
39
+ class PostgresStatsTableMetrics < Sensu::Plugin::Metric::CLI::Graphite
40
+ option :pgpass,
41
+ description: 'Pgpass file',
42
+ short: '-f FILE',
43
+ long: '--pgpass',
44
+ default: ENV['PGPASSFILE'] || "#{ENV['HOME']}/.pgpass"
45
+
46
+ option :user,
47
+ description: 'Postgres User',
48
+ short: '-u USER',
49
+ long: '--user USER'
50
+
51
+ option :password,
52
+ description: 'Postgres Password',
53
+ short: '-p PASS',
54
+ long: '--password PASS'
55
+
56
+ option :hostname,
57
+ description: 'Hostname to login to',
58
+ short: '-h HOST',
59
+ long: '--hostname HOST'
60
+
61
+ option :port,
62
+ description: 'Database port',
63
+ short: '-P PORT',
64
+ long: '--port PORT'
65
+
66
+ option :database,
67
+ description: 'Database name',
68
+ short: '-d DB',
69
+ long: '--db DB'
70
+
71
+ option :scope,
72
+ description: 'Scope, see http://www.postgresql.org/docs/9.2/static/monitoring-stats.html',
73
+ short: '-s SCOPE',
74
+ long: '--scope SCOPE',
75
+ default: 'user'
76
+
77
+ option :scheme,
78
+ description: 'Metric naming scheme, text to prepend to $queue_name.$metric',
79
+ long: '--scheme SCHEME',
80
+ default: "#{Socket.gethostname}.postgresql"
81
+
82
+ option :timeout,
83
+ description: 'Connection timeout (seconds)',
84
+ short: '-T TIMEOUT',
85
+ long: '--timeout TIMEOUT',
86
+ default: 10,
87
+ proc: proc(&:to_i)
88
+
89
+ include Pgpass
90
+
91
+ def run
92
+ timestamp = Time.now.to_i
93
+ pgpass
94
+ con = PG.connect(host: config[:hostname],
95
+ dbname: config[:database],
96
+ user: config[:user],
97
+ password: config[:password],
98
+ port: config[:port],
99
+ connect_timeout: config[:timeout])
100
+ request = [
101
+ 'select sum(seq_scan) as seq_scan, sum(seq_tup_read) as seq_tup_read,',
102
+ 'sum(idx_scan) as idx_scan, sum(idx_tup_fetch) as idx_tup_fetch,',
103
+ 'sum(n_tup_ins) as n_tup_ins, sum(n_tup_upd) as n_tup_upd, sum(n_tup_del) as n_tup_del,',
104
+ 'sum(n_tup_hot_upd) as n_tup_hot_upd, sum(n_live_tup) as n_live_tup, sum(n_dead_tup) as n_dead_tup',
105
+ "from pg_stat_#{config[:scope]}_tables"
106
+ ]
107
+ con.exec(request.join(' ')) do |result|
108
+ result.each do |row|
109
+ output "#{config[:scheme]}.statstable.#{config[:database]}.seq_scan", row['seq_scan'], timestamp
110
+ output "#{config[:scheme]}.statstable.#{config[:database]}.seq_tup_read", row['seq_tup_read'], timestamp
111
+ output "#{config[:scheme]}.statstable.#{config[:database]}.idx_scan", row['idx_scan'], timestamp
112
+ output "#{config[:scheme]}.statstable.#{config[:database]}.idx_tup_fetch", row['idx_tup_fetch'], timestamp
113
+ output "#{config[:scheme]}.statstable.#{config[:database]}.n_tup_ins", row['n_tup_ins'], timestamp
114
+ output "#{config[:scheme]}.statstable.#{config[:database]}.n_tup_upd", row['n_tup_upd'], timestamp
115
+ output "#{config[:scheme]}.statstable.#{config[:database]}.n_tup_del", row['n_tup_del'], timestamp
116
+ output "#{config[:scheme]}.statstable.#{config[:database]}.n_tup_hot_upd", row['n_tup_hot_upd'], timestamp
117
+ output "#{config[:scheme]}.statstable.#{config[:database]}.n_live_tup", row['n_live_tup'], timestamp
118
+ output "#{config[:scheme]}.statstable.#{config[:database]}.n_dead_tup", row['n_dead_tup'], timestamp
119
+ end
120
+ end
121
+
122
+ ok
123
+ end
124
+ end
@@ -0,0 +1,125 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # DEPENDENCIES:
5
+ # gem: sensu-plugin
6
+ # gem: pg
7
+ #
8
+ # USAGE:
9
+ # ./metric-postgres-vaccum.rb -u db_user -p db_pass -h db_host -d db
10
+ #
11
+ # NOTES:
12
+ # Requires PSQL `track_counts` `track_io_timing` for some metrics enabled
13
+ #
14
+ # LICENSE:
15
+ # Copyright (c) 2020 Airbrake Technologies, Inc <support@airbrake.io>
16
+ # Author Patrick Humpal <patrick@netvilla.net>
17
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
18
+ # for details.
19
+ #
20
+
21
+ require 'sensu-plugins-postgres/pgpass'
22
+ require 'sensu-plugin/metric/cli'
23
+ require 'pg'
24
+ require 'socket'
25
+
26
+ class PostgresVacuumDBMetrics < Sensu::Plugin::Metric::CLI::Graphite
27
+ option :pgpass,
28
+ description: 'Pgpass file',
29
+ short: '-f FILE',
30
+ long: '--pgpass',
31
+ default: ENV['PGPASSFILE'] || "#{ENV['HOME']}/.pgpass"
32
+
33
+ option :user,
34
+ description: 'Postgres User',
35
+ short: '-u USER',
36
+ long: '--user USER'
37
+
38
+ option :password,
39
+ description: 'Postgres Password',
40
+ short: '-p PASS',
41
+ long: '--password PASS'
42
+
43
+ option :hostname,
44
+ description: 'Hostname to login to',
45
+ short: '-h HOST',
46
+ long: '--hostname HOST'
47
+
48
+ option :port,
49
+ description: 'Database port',
50
+ short: '-P PORT',
51
+ long: '--port PORT'
52
+
53
+ option :database,
54
+ description: 'Database to connect on',
55
+ short: '-d DB',
56
+ long: '--db DB',
57
+ default: 'postgres'
58
+
59
+ option :all_databases,
60
+ description: 'Get stats for all available databases',
61
+ short: '-a',
62
+ long: '--all-databases',
63
+ boolean: true,
64
+ default: false
65
+
66
+ option :scheme,
67
+ description: 'Metric naming scheme, text to prepend to $queue_name.$metric',
68
+ long: '--scheme SCHEME',
69
+ default: "#{Socket.gethostname}.postgresql"
70
+
71
+ option :timeout,
72
+ description: 'Connection timeout (seconds)',
73
+ short: '-T TIMEOUT',
74
+ long: '--timeout TIMEOUT',
75
+ default: 10,
76
+ proc: proc(&:to_i)
77
+
78
+ include Pgpass
79
+
80
+ def phase_mapping(vacuum_phase)
81
+ ['initializing',
82
+ 'scanning heap',
83
+ 'vacuuming indexes',
84
+ 'vacuuming heap',
85
+ 'cleaning up indexes',
86
+ 'truncating heap',
87
+ 'performing final cleanup'].find_index(vacuum_phase)
88
+ end
89
+
90
+ def run
91
+ timestamp = Time.now.to_i
92
+ pgpass
93
+ con = PG.connect(host: config[:hostname],
94
+ dbname: config[:database],
95
+ user: config[:user],
96
+ password: config[:password],
97
+ port: config[:port],
98
+ connect_timeout: config[:timeout])
99
+
100
+ query = 'SELECT * FROM pg_stat_progress_vacuum'
101
+ params = []
102
+ unless config[:all_databases]
103
+ query += ' WHERE datname = $1'
104
+ params.push config[:database]
105
+ end
106
+
107
+ con.exec_params(query, params) do |result|
108
+ result.each do |row|
109
+ database = row['datname']
110
+
111
+ row.each do |key, value|
112
+ next if %w[datid datname].include?(key)
113
+
114
+ if key == 'phase'
115
+ output "#{config[:scheme]}.vacuum.#{database}.phase", phase_mapping(value).to_s, timestamp
116
+ else
117
+ output "#{config[:scheme]}.vacuum.#{database}.#{key}", value.to_s, timestamp
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ ok
124
+ end
125
+ end
@@ -0,0 +1,132 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # metrics-postgres-query
6
+ #
7
+ # DESCRIPTION:
8
+ # This plugin collects metrics from the results of a postgres query. Can optionally
9
+ # count the number of tuples (rows) returned by the query.
10
+ #
11
+ # OUTPUT:
12
+ # metric data
13
+ #
14
+ # PLATFORMS:
15
+ # Linux
16
+ #
17
+ # DEPENDENCIES:
18
+ # gem: pg
19
+ # gem: sensu-plugin
20
+ #
21
+ # USAGE:
22
+ # metrics-postgres-query.rb -u db_user -p db_pass -h db_server -d db -q 'select foo from bar'
23
+ #
24
+ # NOTES:
25
+ #
26
+ # LICENSE:
27
+ # Copyright 2015, Eric Heydrick <eheydrick@gmail.com>
28
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
29
+ # for details.
30
+ #
31
+
32
+ require 'sensu-plugins-postgres/pgpass'
33
+ require 'sensu-plugin/metric/cli'
34
+ require 'pg'
35
+
36
+ class MetricsPostgresQuery < Sensu::Plugin::Metric::CLI::Graphite
37
+ option :pgpass,
38
+ description: 'Pgpass file',
39
+ short: '-f FILE',
40
+ long: '--pgpass',
41
+ default: ENV['PGPASSFILE'] || "#{ENV['HOME']}/.pgpass"
42
+
43
+ option :user,
44
+ description: 'Postgres User',
45
+ short: '-u USER',
46
+ long: '--user USER'
47
+
48
+ option :password,
49
+ description: 'Postgres Password',
50
+ short: '-p PASS',
51
+ long: '--password PASS'
52
+
53
+ option :hostname,
54
+ description: 'Hostname to login to',
55
+ short: '-h HOST',
56
+ long: '--hostname HOST'
57
+
58
+ option :port,
59
+ description: 'Database port',
60
+ short: '-P PORT',
61
+ long: '--port PORT'
62
+
63
+ option :database,
64
+ description: 'Database name',
65
+ short: '-d DB',
66
+ long: '--db DB'
67
+
68
+ option :query,
69
+ description: 'Database query to execute',
70
+ short: '-q QUERY',
71
+ long: '--query QUERY',
72
+ required: true
73
+
74
+ option :count_tuples,
75
+ description: 'Count the number of tuples (rows) returned by the query',
76
+ short: '-t',
77
+ long: '--tuples',
78
+ boolean: true,
79
+ default: false
80
+
81
+ option :scheme,
82
+ description: 'Metric naming scheme, text to prepend to metric',
83
+ short: '-s SCHEME',
84
+ long: '--scheme SCHEME',
85
+ default: 'postgres'
86
+
87
+ option :multirow,
88
+ description: 'Determines if we return first row or all rows',
89
+ short: '-m',
90
+ long: '--multirow',
91
+ boolean: true,
92
+ default: false
93
+
94
+ option :timeout,
95
+ description: 'Connection timeout (seconds)',
96
+ short: '-T TIMEOUT',
97
+ long: '--timeout TIMEOUT',
98
+ default: 10,
99
+ proc: proc(&:to_i)
100
+
101
+ include Pgpass
102
+
103
+ def run
104
+ begin
105
+ pgpass
106
+ con = PG.connect(host: config[:hostname],
107
+ dbname: config[:database],
108
+ user: config[:user],
109
+ password: config[:password],
110
+ port: config[:port],
111
+ connect_timeout: config[:timeout])
112
+ res = con.exec(config[:query].to_s)
113
+ rescue PG::Error => e
114
+ unknown "Unable to query PostgreSQL: #{e.message}"
115
+ end
116
+
117
+ value = if config[:count_tuples]
118
+ res.ntuples
119
+ else
120
+ res.first&.values&.first
121
+ end
122
+
123
+ if config[:multirow] && !config[:count_tuples]
124
+ res.values.each do |row|
125
+ output "#{config[:scheme]}.#{row[0]}", row[1]
126
+ end
127
+ else
128
+ output config[:scheme], value
129
+ end
130
+ ok
131
+ end
132
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pgpass
4
+ def read_pgpass(pg_pass_file)
5
+ File.readlines(pg_pass_file).each do |line|
6
+ return line.strip.split(':') unless line.start_with?('#')
7
+
8
+ next
9
+ end
10
+ end
11
+
12
+ def pgpass
13
+ if File.file?(config[:pgpass])
14
+ pgpass = Hash[%i[hostname port database user password].zip(read_pgpass(config[:pgpass]))]
15
+ pgpass[:database] = nil if pgpass[:database] == '*'
16
+ pgpass.each do |k, v|
17
+ config[k] ||= v
18
+ end
19
+ else
20
+ config[:hostname] ||= ENV['PGHOST'] || 'localhost'
21
+ config[:port] ||= ENV['PGPORT'] || 5432
22
+ config[:database] ||= ENV['PGDATABASE'] || 'postgres'
23
+ config[:user] ||= ENV['PGUSER'] || 'postgres'
24
+ config[:password] ||= ENV['PGPASSWORD']
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgUtil
4
+ def check_vsn_newer_than_postgres9(conn)
5
+ pg_vsn = conn.exec("SELECT current_setting('server_version')").getvalue(0, 0)
6
+ pg_vsn = pg_vsn.split(' ')[0]
7
+ Gem::Version.new(pg_vsn) < Gem::Version.new('10.0') && Gem::Version.new(pg_vsn) >= Gem::Version.new('9.0')
8
+ end
9
+
10
+ def compute_lag(master, slave, m_segbytes)
11
+ m_segment, m_offset = master.split('/')
12
+ s_segment, s_offset = slave.split('/')
13
+ ((m_segment.hex - s_segment.hex) * m_segbytes) + (m_offset.hex - s_offset.hex)
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SensuPluginsPostgres
4
+ module Version
5
+ MAJOR = 4
6
+ MINOR = 3
7
+ PATCH = 1
8
+
9
+ VER_STRING = [MAJOR, MINOR, PATCH].compact.join('.')
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sensu-plugins-postgres/version'
4
+ require 'sensu-plugins-postgres/pgpass'