pghero 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pghero might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f45d1e2c61994223e2835c0d8fdbefea6a9c0b36
4
- data.tar.gz: 74227dbc52f80e9b1cb150f601a8ec9705ac56b3
2
+ SHA256:
3
+ metadata.gz: b627e79e52bdd3c9eb7f850e4350cd286459ac3771ec94c33b527e4061cad6d6
4
+ data.tar.gz: 33773361eb689372f74d012e5d603c76171abc153dd3eccff3ec6ef15012de1f
5
5
  SHA512:
6
- metadata.gz: f96125273c33eb6b632894c927118c2e308a62829df66128ca3a917dd578eafae7dd77308fd832142ddb54d61e748d753ee06da83f5393d3417d447223a208cd
7
- data.tar.gz: 777fc575408694f43f3a8de1273341c5be02e3288a63424e5150a13c5c4403fbc547c84b5172cdb23dc9720dfc3b50b8acf3d574dad399a569c43035df435984
6
+ metadata.gz: 857c4d36050a5532240173faae721bf93f6219641ed005a77ff3d45fd4eda6aa78e10d2d9c2bc8cc6e93547eb97c47006802b9bfad5f02f186535d1eb219e779
7
+ data.tar.gz: efba82dcf9d151aee9c94adac95ca27a032da04a358b435aaa86f7255949d7bf63f1a58f39f18976eeba294a0386223ea16c752c9f1e8285d0aa6fa5c8d29921
@@ -0,0 +1 @@
1
+ app/assets/* linguist-vendored
@@ -0,0 +1,7 @@
1
+ Hi,
2
+
3
+ Before creating an issue, please check out the Contributing Guide:
4
+
5
+ https://github.com/ankane/pghero/blob/master/CONTRIBUTING.md
6
+
7
+ Thanks!
@@ -1,10 +1,13 @@
1
1
  language: ruby
2
- rvm: 2.2.4
2
+ rvm: 2.4.4
3
3
  cache: bundler
4
4
  sudo: false
5
5
  script: TRAVIS_CI=1 bundle exec rake test
6
6
  addons:
7
7
  postgresql: "9.4"
8
+ before_install:
9
+ - gem update --system
10
+ - gem install bundler
8
11
  before_script:
9
12
  - psql -c 'create database pghero_test;' -U postgres
10
13
  notifications:
@@ -1,3 +1,9 @@
1
+ ## 2.1.1
2
+
3
+ - Added `explain_timeout_sec` option
4
+ - Fixed error with unparsable sequences
5
+ - Stopped throwing `Same sequence name in multiple schemas` error
6
+
1
7
  ## 2.1.0
2
8
 
3
9
  - Fixed issue with sequences in different schema than table
@@ -0,0 +1,40 @@
1
+ # Contributing
2
+
3
+ First, thanks for wanting to contribute. You’re awesome! :heart:
4
+
5
+ ## Questions
6
+
7
+ Use [Stack Overflow](https://stackoverflow.com/) with the tag `pghero`.
8
+
9
+ ## Feature Requests
10
+
11
+ Create an issue. Start the title with `[Idea]`.
12
+
13
+ ## Issues
14
+
15
+ Think you’ve discovered an issue?
16
+
17
+ 1. Search existing issues to see if it’s been reported.
18
+ 2. Try the `master` branch to make sure it hasn’t been fixed.
19
+
20
+ ```rb
21
+ gem "pghero", github: "ankane/pghero"
22
+ ```
23
+
24
+ If the above steps don’t help, create an issue. Include:
25
+
26
+ - Detailed steps to reproduce
27
+ - Complete backtraces for exceptions
28
+
29
+ ## Pull Requests
30
+
31
+ Fork the project and create a pull request. A few tips:
32
+
33
+ - Keep changes to a minimum. If you have multiple features or fixes, submit multiple pull requests.
34
+ - Follow the existing style. The code should read like it’s written by a single person.
35
+
36
+ Feel free to open an issue to get feedback on your idea before spending too much time on it.
37
+
38
+ ---
39
+
40
+ This contributing guide is released under [CCO](https://creativecommons.org/publicdomain/zero/1.0/) (public domain). Use it for your own project without attribution.
data/Gemfile CHANGED
@@ -3,4 +3,4 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in pghero.gemspec
4
4
  gemspec
5
5
 
6
- gem "activerecord", "~> 5.1.0"
6
+ gem "activerecord", "~> 5.2.0"
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Andrew Kane, 2008-2014 Heroku (initial queries)
1
+ Copyright (c) 2014-2018 Andrew Kane, 2008-2014 Heroku (initial queries)
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -20,6 +20,12 @@ Select your preferred method of installation to get started.
20
20
  - [Linux](guides/Linux.md)
21
21
  - [Docker](guides/Docker.md)
22
22
 
23
+ ## Related Projects
24
+
25
+ - [PgBouncerHero](https://github.com/kwent/pgbouncerhero) - A dashboard for PgBouncer
26
+ - [pgsync](https://github.com/ankane/pgsync) - Sync Postgres data between databases
27
+ - [pgslice](https://github.com/ankane/pgslice) - Postgres partitioning as easy as pie
28
+
23
29
  ## Credits
24
30
 
25
31
  A big thanks to [Craig Kerstiens](http://www.craigkerstiens.com/2013/01/10/more-on-postgres-performance/) and [Heroku](https://blog.heroku.com/archives/2013/5/10/more_insight_into_your_database_with_pgextras) for the initial queries and [Bootswatch](https://github.com/thomaspark/bootswatch) for the theme :clap:
@@ -196,6 +196,8 @@ module PgHero
196
196
 
197
197
  if @duration / @period > 1440
198
198
  render_text "Too many data points"
199
+ elsif @period % 60 != 0
200
+ render_text "Period must be a multiple of 60"
199
201
  end
200
202
  end
201
203
 
@@ -245,6 +247,10 @@ module PgHero
245
247
  @visualize = params[:commit] == "Visualize"
246
248
  rescue ActiveRecord::StatementInvalid => e
247
249
  @error = e.message
250
+
251
+ if @error.include?("bind message supplies 0 parameters")
252
+ @error = "Can't explain queries with bind parameters"
253
+ end
248
254
  end
249
255
  end
250
256
  end
@@ -3,7 +3,7 @@ module PgHero
3
3
  def pghero_pretty_ident(table, schema: nil)
4
4
  ident = table
5
5
  if schema && schema != "public"
6
- indent = "#{schema}.#{table}"
6
+ ident = "#{schema}.#{table}"
7
7
  end
8
8
  if ident =~ /\A[a-z0-9_]+\z/
9
9
  ident
@@ -129,9 +129,13 @@
129
129
  <% end %>
130
130
  </td>
131
131
  <td>
132
- <%= sequence[:sequence] %>
133
- <% if sequence[:schema] && sequence[:schema] != "public" %>
134
- <span class="text-muted"><%= sequence[:schema] %></span>
132
+ <% if sequence[:sequence] %>
133
+ <%= sequence[:sequence] %>
134
+ <% if sequence[:schema] && sequence[:schema] != "public" %>
135
+ <span class="text-muted"><%= sequence[:schema] %></span>
136
+ <% end %>
137
+ <% else %>
138
+ Unable to parse: <%= sequence[:default_value] %>
135
139
  <% end %>
136
140
  </td>
137
141
  </tr>
@@ -18,7 +18,7 @@
18
18
  </tbody>
19
19
  </table>
20
20
 
21
- <p>Check out <%= link_to "PgTune", "http://pgtune.leopard.in.ua", target: "_blank" %> for recommendations. DB version is <%= @database.server_version.split(".").first(2).join(".") %>.</p>
21
+ <p>Check out <%= link_to "PgTune", "https://pgtune.leopard.in.ua/", target: "_blank" %> for recommendations. DB version is <%= @database.server_version.split(" ").first.split(".").first(2).join(".") %>.</p>
22
22
  </div>
23
23
 
24
24
  <% if @autovacuum_settings %>
@@ -94,3 +94,9 @@ Minimum connections for high connections warning
94
94
  ```sh
95
95
  heroku config:set PGHERO_TOTAL_CONNECTIONS_THRESHOLD=100 # default
96
96
  ```
97
+
98
+ Statement timeout for explain
99
+
100
+ ```sh
101
+ heroku config:set PGHERO_EXPLAIN_TIMEOUT_SEC=10 # default
102
+ ````
@@ -4,6 +4,7 @@ Distributions
4
4
 
5
5
  - [Ubuntu 16.04 (Xenial)](#ubuntu-1604-xenial)
6
6
  - [Ubuntu 14.04 (Trusty)](#ubuntu-1404-trusty)
7
+ - [Debian 9 (Stretch)](#debian-9-stretch)
7
8
  - [Debian 8 (Jesse)](#debian-8-jesse)
8
9
  - [Debian 7 (Wheezy)](#debian-7-wheezy)
9
10
  - [CentOS / RHEL 7](#centos--rhel-7)
@@ -33,6 +34,17 @@ sudo apt-get update
33
34
  sudo apt-get -y install pghero
34
35
  ```
35
36
 
37
+ ### Debian 9 (Stretch)
38
+
39
+ ```sh
40
+ sudo apt-get -y install apt-transport-https
41
+ wget -qO- https://dl.packager.io/srv/pghero/pghero/key | sudo apt-key add -
42
+ sudo wget -O /etc/apt/sources.list.d/pghero.list \
43
+ https://dl.packager.io/srv/pghero/pghero/master/installer/debian/9.repo
44
+ sudo apt-get update
45
+ sudo apt-get -y install pghero
46
+ ```
47
+
36
48
  ### Debian 8 (Jesse)
37
49
 
38
50
  ```sh
@@ -248,6 +260,12 @@ Minimum connections for high connections warning
248
260
  sudo pghero config:set PGHERO_TOTAL_CONNECTIONS_THRESHOLD=100 # default
249
261
  ```
250
262
 
263
+ Statement timeout for explain
264
+
265
+ ```sh
266
+ sudo pghero config:set PGHERO_EXPLAIN_TIMEOUT_SEC=10 # default
267
+ ````
268
+
251
269
  ## Upgrading
252
270
 
253
271
  Ubuntu and Debian
@@ -1,6 +1,6 @@
1
1
  # Query Stats
2
2
 
3
- The [pg_stat_statements module](http://www.postgresql.org/docs/9.3/static/pgstatstatements.html) is used for query stats.
3
+ The [pg_stat_statements module](https://www.postgresql.org/docs/current/static/pgstatstatements.html) is used for query stats.
4
4
 
5
5
  ## Installation
6
6
 
@@ -172,6 +172,12 @@ Minimum connections for high connections warning
172
172
  PgHero.total_connections_threshold = 100 # default
173
173
  ```
174
174
 
175
+ Statement timeout for explain
176
+
177
+ ```ruby
178
+ PgHero.explain_timeout_sec = 10 # default
179
+ ```
180
+
175
181
  ## Methods
176
182
 
177
183
  Insights
@@ -329,5 +335,5 @@ CREATE EXTENSION pg_stat_statements;
329
335
  ## Bonus
330
336
 
331
337
  - See where queries come from with [Marginalia](https://github.com/basecamp/marginalia) - comments appear on the Live Queries tab.
332
- - Get weekly news and articles with [Postgres Weekly](http://postgresweekly.com)
333
- - Optimize your configuration with [PgTune](http://pgtune.leopard.in.ua) and [pgBench](http://www.postgresql.org/docs/devel/static/pgbench.html)
338
+ - Get weekly news and articles with [Postgres Weekly](https://postgresweekly.com/)
339
+ - Optimize your configuration with [PgTune](https://pgtune.leopard.in.ua/) and [pgBench](https://www.postgresql.org/docs/devel/static/pgbench.html)
@@ -1,12 +1,12 @@
1
1
  # How PgHero Suggests Indexes
2
2
 
3
- 1. Get the most time-consuming queries from [pg_stat_statements](http://www.postgresql.org/docs/current/static/pgstatstatements.html).
3
+ 1. Get the most time-consuming queries from [pg_stat_statements](https://www.postgresql.org/docs/current/static/pgstatstatements.html).
4
4
 
5
5
  2. Parse queries with [pg_query](https://github.com/lfittl/pg_query). Look for a single table with a `WHERE` clause that consists of only `=`, `IN`, `IS NULL` or `IS NOT NULL` and/or an `ORDER BY` clause.
6
6
 
7
- 3. Use the [pg_stats](http://www.postgresql.org/docs/current/static/view-pg-stats.html) view to get estimates about distinct rows and percent of `NULL` values for each column.
7
+ 3. Use the [pg_stats](https://www.postgresql.org/docs/current/static/view-pg-stats.html) view to get estimates about distinct rows and percent of `NULL` values for each column.
8
8
 
9
- 4. For each column in the `WHERE` clause, sort by the highest [cardinality](https://en.wikipedia.org/wiki/Cardinality_(SQL_statements)) (most unique values). This allows the database to narrow its search the fastest. Perform [row estimation](http://www.postgresql.org/docs/current/static/row-estimation-examples.html) to get the expected number of rows as we add columns to the index.
9
+ 4. For each column in the `WHERE` clause, sort by the highest [cardinality](https://en.wikipedia.org/wiki/Cardinality_(SQL_statements)) (most unique values). This allows the database to narrow its search the fastest. Perform [row estimation](https://www.postgresql.org/docs/current/static/row-estimation-examples.html) to get the expected number of rows as we add columns to the index.
10
10
 
11
11
  5. Continue this process with columns in the `ORDER BY` clause.
12
12
 
@@ -15,6 +15,9 @@ databases:
15
15
  # Minimum connections for high connections warning
16
16
  # total_connections_threshold: 100
17
17
 
18
+ # Statement timeout for explain
19
+ # explain_timeout_sec: 10
20
+
18
21
  # Add more databases
19
22
  # other:
20
23
  # url: <%= ENV["OTHER_DATABASE_URL"] %>
@@ -32,11 +32,12 @@ module PgHero
32
32
 
33
33
  # settings
34
34
  class << self
35
- attr_accessor :long_running_query_sec, :slow_query_ms, :slow_query_calls, :total_connections_threshold, :cache_hit_rate_threshold, :env, :show_migrations
35
+ attr_accessor :long_running_query_sec, :slow_query_ms, :slow_query_calls, :explain_timeout_sec, :total_connections_threshold, :cache_hit_rate_threshold, :env, :show_migrations
36
36
  end
37
37
  self.long_running_query_sec = (ENV["PGHERO_LONG_RUNNING_QUERY_SEC"] || 60).to_i
38
38
  self.slow_query_ms = (ENV["PGHERO_SLOW_QUERY_MS"] || 20).to_i
39
39
  self.slow_query_calls = (ENV["PGHERO_SLOW_QUERY_CALLS"] || 100).to_i
40
+ self.explain_timeout_sec = (ENV["PGHERO_EXPLAIN_TIMEOUT_SEC"] || 10).to_i
40
41
  self.total_connections_threshold = (ENV["PGHERO_TOTAL_CONNECTIONS_THRESHOLD"] || 100).to_i
41
42
  self.cache_hit_rate_threshold = 99
42
43
  self.env = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
@@ -52,6 +52,10 @@ module PgHero
52
52
  (config["slow_query_calls"] || PgHero.config["slow_query_calls"] || PgHero.slow_query_calls).to_i
53
53
  end
54
54
 
55
+ def explain_timeout_sec
56
+ (config["explain_timeout_sec"] || PgHero.config["explain_timeout_sec"] || PgHero.explain_timeout_sec).to_i
57
+ end
58
+
55
59
  def long_running_query_sec
56
60
  (config["long_running_query_sec"] || PgHero.config["long_running_query_sec"] || PgHero.long_running_query_sec).to_i
57
61
  end
@@ -6,7 +6,7 @@ module PgHero
6
6
  explanation = nil
7
7
 
8
8
  # use transaction for safety
9
- with_transaction(statement_timeout: 10000, rollback: true) do
9
+ with_transaction(statement_timeout: (explain_timeout_sec * 1000), rollback: true) do
10
10
  if (sql.sub(/;\z/, "").include?(";") || sql.upcase.include?("COMMIT")) && !explain_safe?
11
11
  raise ActiveRecord::StatementInvalid, "Unsafe statement"
12
12
  end
@@ -28,9 +28,10 @@ module PgHero
28
28
 
29
29
  # parse out sequence
30
30
  sequences.each do |column|
31
- m = /^nextval\('(.+)'\:\:regclass\)$/.match(column.delete(:default_value))
32
- column[:schema], column[:sequence] = unquote_ident(m[1])
33
31
  column[:max_value] = column[:column_type] == 'integer' ? 2147483647 : 9223372036854775807
32
+
33
+ column[:schema], column[:sequence] = parse_default_value(column[:default_value])
34
+ column.delete(:default_value) if column[:sequence]
34
35
  end
35
36
 
36
37
  add_sequence_attributes(sequences)
@@ -49,6 +50,19 @@ module PgHero
49
50
 
50
51
  private
51
52
 
53
+ # can parse
54
+ # nextval('id_seq'::regclass)
55
+ # nextval(('id_seq'::text)::regclass)
56
+ def parse_default_value(default_value)
57
+ m = /^nextval\('(.+)'\:\:regclass\)$/.match(default_value)
58
+ m = /^nextval\(\('(.+)'\:\:text\)\:\:regclass\)$/.match(default_value) unless m
59
+ if m
60
+ unquote_ident(m[1])
61
+ else
62
+ []
63
+ end
64
+ end
65
+
52
66
  def unquote_ident(value)
53
67
  schema, seq = value.split(".")
54
68
  unless seq
@@ -77,22 +91,18 @@ module PgHero
77
91
  SQL
78
92
 
79
93
  # first populate missing schemas
80
- missing_schema = sequences.select { |s| s[:schema].nil? }
94
+ missing_schema = sequences.select { |s| s[:schema].nil? && s[:sequence] }
81
95
  if missing_schema.any?
82
96
  sequence_schemas = sequence_attributes.group_by { |s| s[:sequence] }
83
97
 
84
98
  missing_schema.each do |sequence|
85
99
  schemas = sequence_schemas[sequence[:sequence]] || []
86
100
 
87
- case schemas.size
88
- when 0
89
- # do nothing, will be marked as unreadable
90
- when 1
91
- # bingo
101
+ if schemas.size == 1
92
102
  sequence[:schema] = schemas[0][:schema]
93
- else
94
- raise PgHero::Error, "Same sequence name in multiple schemas: #{sequence[:sequence]}"
95
103
  end
104
+ # otherwise, do nothing, will be marked as unreadable
105
+ # TODO better message for multiple schemas
96
106
  end
97
107
  end
98
108
 
@@ -1,3 +1,3 @@
1
1
  module PgHero
2
- VERSION = "2.1.0"
2
+ VERSION = "2.1.1"
3
3
  end
@@ -9,7 +9,6 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Andrew Kane"]
10
10
  spec.email = ["andrew@chartkick.com"]
11
11
  spec.summary = "A performance dashboard for Postgres"
12
- spec.description = "A performance dashboard for Postgres"
13
12
  spec.homepage = "https://github.com/ankane/pghero"
14
13
  spec.license = "MIT"
15
14
 
@@ -18,17 +17,19 @@ Gem::Specification.new do |spec|
18
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features|guides)/})
19
18
  spec.require_paths = ["lib"]
20
19
 
20
+ spec.required_ruby_version = ">= 2.2.0"
21
+
21
22
  spec.add_dependency "activerecord"
22
23
 
23
- spec.add_development_dependency "bundler", "~> 1.6"
24
- spec.add_development_dependency "rake"
25
- spec.add_development_dependency "minitest"
26
24
  spec.add_development_dependency "activerecord-import"
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "minitest"
27
+ spec.add_development_dependency "rake"
27
28
 
28
29
  if RUBY_PLATFORM == "java"
29
30
  spec.add_development_dependency "activerecord-jdbcpostgresql-adapter"
30
31
  else
31
- spec.add_development_dependency "pg"
32
+ spec.add_development_dependency "pg", "< 1.0.0"
32
33
  spec.add_development_dependency "pg_query"
33
34
  end
34
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pghero
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-01 00:00:00.000000000 Z
11
+ date: 2018-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -25,21 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: activerecord-import
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.6'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.6'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake
42
+ name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: activerecord-import
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: pg
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "<"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: 1.0.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "<"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: 1.0.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: pg_query
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -108,16 +108,19 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description: A performance dashboard for Postgres
111
+ description:
112
112
  email:
113
113
  - andrew@chartkick.com
114
114
  executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
+ - ".gitattributes"
119
+ - ".github/ISSUE_TEMPLATE.md"
118
120
  - ".gitignore"
119
121
  - ".travis.yml"
120
122
  - CHANGELOG.md
123
+ - CONTRIBUTING.md
121
124
  - Gemfile
122
125
  - LICENSE.txt
123
126
  - README.md
@@ -209,7 +212,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
209
212
  requirements:
210
213
  - - ">="
211
214
  - !ruby/object:Gem::Version
212
- version: '0'
215
+ version: 2.2.0
213
216
  required_rubygems_version: !ruby/object:Gem::Requirement
214
217
  requirements:
215
218
  - - ">="
@@ -217,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
220
  version: '0'
218
221
  requirements: []
219
222
  rubyforge_project:
220
- rubygems_version: 2.6.13
223
+ rubygems_version: 2.7.6
221
224
  signing_key:
222
225
  specification_version: 4
223
226
  summary: A performance dashboard for Postgres