Skip to content

Commit 2610275

Browse files
phumpalmajormoses
authored andcommitted
Assist in visualizing the PostgreSQL vacuum process
Uuse sensu to aggregate vacuum metrics from the `pg_stat_progress_vacuum` view. Per https://www.postgresql.org/docs/12/progress-reporting.html#VACUUM-PROGRESS-REPORTING
1 parent bcd2685 commit 2610275

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

bin/metric-postgres-vaccum.rb

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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: nil
76+
77+
include Pgpass
78+
79+
def phase_mapping(vacuum_phase)
80+
['initializing',
81+
'scanning heap',
82+
'vacuuming indexes',
83+
'vacuuming heap',
84+
'cleaning up indexes',
85+
'truncating heap',
86+
'performing final cleanup'].find_index(vacuum_phase)
87+
end
88+
89+
def run
90+
timestamp = Time.now.to_i
91+
pgpass
92+
con = PG.connect(host: config[:hostname],
93+
dbname: config[:database],
94+
user: config[:user],
95+
password: config[:password],
96+
port: config[:port],
97+
connect_timeout: config[:timeout])
98+
99+
query = 'SELECT * FROM pg_stat_progress_vacuum'
100+
params = []
101+
unless config[:all_databases]
102+
query += ' WHERE datname = $1'
103+
params.push config[:database]
104+
end
105+
106+
con.exec_params(query, params) do |result|
107+
result.each do |row|
108+
database = row['datname']
109+
110+
row.each do |key, value|
111+
next if %w[datid datname].include?(key)
112+
113+
if key == 'phase'
114+
output "#{config[:scheme]}.vacuum.#{database}.phase", phase_mapping(value).to_s, timestamp
115+
else
116+
output "#{config[:scheme]}.vacuum.#{database}.#{key}", value.to_s, timestamp
117+
end
118+
end
119+
end
120+
end
121+
122+
ok
123+
end
124+
end

0 commit comments

Comments
 (0)