pghero 0.1.10 → 1.0.0

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
2
  SHA1:
3
- metadata.gz: b36df22eb125725ef48c4c9c1cb4094a2cd346b8
4
- data.tar.gz: d683feef9adc1a6b0b09ed8ea844159e24b250cd
3
+ metadata.gz: 5007ffa26cad91ceca6b39cf0049c0f935933637
4
+ data.tar.gz: 505386ddd4f407457b0d88d06840007d3aa27059
5
5
  SHA512:
6
- metadata.gz: 42c4d3ccc26df2ac3a0011051acad9f9b06e8f61da89eed183a275d5d3a1752bbcb5a7a756ea26f3bfb20e6e05832c310c1bc87b63cfc6be194eb2b2ce46f247
7
- data.tar.gz: 1e584dd852a119509488d59f6fb5346d211e43da9cf221000f96899cb71ea9bf8002780b00d1e70586664c435bfea764a09816cfd992ac642ae350fe4a1ccea3
6
+ metadata.gz: abb53d06f528e1e0461864b5afbc2e8a27cc2c425ad3a04e3ad4e1cee6bf45f4a1bd44d549dbb56df94052c0aa1bf53164d3a84d780530047368ee06fa190178
7
+ data.tar.gz: d2ae582ac7093732798ad45b6914b6adc4caab8af229e229a899342811f3fe2a94aeb918babb40ad8ef316e3ba2740040e313829a5a2f6bbdbbc35ac7ca96f34
@@ -1,3 +1,13 @@
1
+ ## 1.0.0
2
+
3
+ - More platforms!
4
+ - Support for multiple databases!
5
+ - Added `replica?` method
6
+ - Added `replication_lag` method
7
+ - Added `ssl_used?` method
8
+ - Added `kill_long_running_queries` method
9
+ - Added env vars for settings
10
+
1
11
  ## 0.1.10
2
12
 
3
13
  - Added connections page
data/README.md CHANGED
@@ -4,245 +4,30 @@ Postgres insights made easy
4
4
 
5
5
  [View the demo](https://pghero.herokuapp.com/)
6
6
 
7
- ![Screenshot](https://pghero.herokuapp.com/assets/screenshot-d09df77e5e1de184ae1fcfb2e5f49387.png)
8
-
9
- Supports PostgreSQL 9.2+
7
+ [![Screenshot](https://pghero.herokuapp.com/assets/screenshot-34a33ee68c77d64c1f89f143f6297a47.png)](https://pghero.herokuapp.com/)
10
8
 
11
9
  :speech_balloon: Get [handcrafted updates](http://chartkick.us7.list-manage.com/subscribe?u=952c861f99eb43084e0a49f98&id=6ea6541e8e&group[0][32]=true) for new features
12
10
 
13
- For pure SQL, check out [PgHero.sql](https://github.com/ankane/pghero.sql) and for a standalone app, check out [PgHero Solo](https://github.com/bmorton/pghero_solo)
14
-
15
- 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 :clap:
16
-
17
11
  ## Installation
18
12
 
19
- Add this line to your application’s Gemfile:
20
-
21
- ```ruby
22
- gem 'pghero'
23
- ```
24
-
25
- And mount the dashboard in your `config/routes.rb`:
26
-
27
- ```ruby
28
- mount PgHero::Engine, at: "pghero"
29
- ```
30
-
31
- Be sure to [secure the dashboard](#security) in production.
32
-
33
- ## Insights
34
-
35
- ```ruby
36
- PgHero.running_queries
37
- PgHero.long_running_queries
38
- PgHero.index_usage
39
- PgHero.missing_indexes
40
- PgHero.unused_indexes
41
- PgHero.unused_tables
42
- PgHero.database_size
43
- PgHero.relation_sizes
44
- PgHero.index_hit_rate
45
- PgHero.table_hit_rate
46
- PgHero.total_connections
47
- ```
48
-
49
- Kill queries
50
-
51
- ```ruby
52
- PgHero.kill(pid)
53
- PgHero.kill_all
54
- ```
55
-
56
- Query stats
57
-
58
- ```ruby
59
- PgHero.query_stats_enabled?
60
- PgHero.enable_query_stats
61
- PgHero.disable_query_stats
62
- PgHero.reset_query_stats
63
- PgHero.query_stats
64
- PgHero.slow_queries
65
- ```
66
-
67
- ## Users
68
-
69
- Create a user
70
-
71
- ```ruby
72
- PgHero.create_user("link")
73
- # {password: "zbTrNHk2tvMgNabFgCo0ws7T"}
74
- ```
75
-
76
- This generates and returns a secure password. The user has full access to the `public` schema.
77
-
78
- Read-only access
79
-
80
- ```ruby
81
- PgHero.create_user("epona", readonly: true)
82
- ```
83
-
84
- Set the password
85
-
86
- ```ruby
87
- PgHero.create_user("zelda", password: "hyrule")
88
- ```
89
-
90
- Drop a user
91
-
92
- ```ruby
93
- PgHero.drop_user("ganondorf")
94
- ```
95
-
96
- ## Security
97
-
98
- #### Basic Authentication
99
-
100
- Set the following variables in your environment or an initializer.
101
-
102
- ```ruby
103
- ENV["PGHERO_USERNAME"] = "andrew"
104
- ENV["PGHERO_PASSWORD"] = "secret"
105
- ```
106
-
107
- #### Devise
108
-
109
- ```ruby
110
- authenticate :user, lambda {|user| user.admin? } do
111
- mount PgHero::Engine, at: "pghero"
112
- end
113
- ```
114
-
115
- ## Query Stats
116
-
117
- The [pg_stat_statements module](http://www.postgresql.org/docs/9.3/static/pgstatstatements.html) is used for query stats.
118
-
119
- ### Installation
120
-
121
- If you have trouble enabling query stats from the dashboard, try doing it manually.
122
-
123
- Add the following to your `postgresql.conf`:
124
-
125
- ```conf
126
- shared_preload_libraries = 'pg_stat_statements'
127
- pg_stat_statements.track = all
128
- pg_stat_statements.max = 10000
129
- track_activity_query_size = 2048
130
- ```
13
+ PgHero can be installed as a standalone app or a Rails engine.
131
14
 
132
- Then restart PostgreSQL. As a superuser from the `psql` console, run:
15
+ ### Standalone
133
16
 
134
- ```psql
135
- CREATE extension pg_stat_statements;
136
- ```
17
+ [Linux](guides/Linux.md) - Ubuntu, Debian, and more
137
18
 
138
- #### Amazon RDS
19
+ [Docker](guides/Docker.md)
139
20
 
140
- Change `shared_preload_libraries` to `pg_stat_statements` in your [Parameter Group](https://console.aws.amazon.com/rds/home?region=us-east-1#parameter-groups:) and restart the database instance.
21
+ [Heroku](guides/Heroku.md)
141
22
 
142
- As a superuser from the `psql` console, run:
23
+ ### Rails
143
24
 
144
- ```psql
145
- CREATE extension pg_stat_statements;
146
- ```
25
+ [Rails](guides/Rails.md)
147
26
 
148
- ### Common Issues
27
+ ## Credits
149
28
 
150
- #### pg_stat_statements must be loaded via shared_preload_libraries
151
-
152
- Follow the instructions above.
153
-
154
- #### FATAL: could not access file "pg_stat_statements": No such file or directory
155
-
156
- Run `apt-get install postgresql-contrib-9.3` and follow the instructions above.
157
-
158
- #### The database user does not have permission to ...
159
-
160
- The database user is not a superuser. You can manually enable stats from the `psql` console with:
161
-
162
- ```psql
163
- CREATE extension pg_stat_statements;
164
- ```
165
-
166
- and reset stats with:
167
-
168
- ```psql
169
- SELECT pg_stat_statements_reset();
170
- ```
171
-
172
- #### Queries show up as `<insufficient privilege>`
173
-
174
- For security reasons, only superusers can see queries executed by other users.
175
-
176
- ## System Stats
177
-
178
- CPU usage is available for Amazon RDS. Add these lines to your application’s Gemfile:
179
-
180
- ```ruby
181
- gem 'aws-sdk'
182
- gem 'chartkick'
183
- ```
184
-
185
- And add these variables to your environment:
186
-
187
- ```sh
188
- PGHERO_ACCESS_KEY_ID=accesskey123
189
- PGHERO_SECRET_ACCESS_KEY=secret123
190
- PGHERO_DB_INSTANCE_IDENTIFIER=datakick-production
191
- ```
192
-
193
- ## Customize
194
-
195
- Minimum time for long running queries
196
-
197
- ```ruby
198
- PgHero.long_running_query_sec = 60 # default
199
- ```
200
-
201
- Minimum average time for slow queries
202
-
203
- ```ruby
204
- PgHero.slow_query_ms = 20 # default
205
- ```
206
-
207
- Minimum calls for slow queries
208
-
209
- ```ruby
210
- PgHero.slow_query_calls = 100 # default
211
- ```
212
-
213
- Minimum connections for high connections warning
214
-
215
- ```ruby
216
- PgHero.total_connections_threshold = 100 # default
217
- ```
218
-
219
- ## Bonus Projects
220
-
221
- - See where queries come from with [Marginalia](https://github.com/basecamp/marginalia) - comments appear on the Live Queries tab.
222
- - Get weekly news and articles with [Postgres Weekly](http://postgresweekly.com)
223
- - Optimize your configuration with [PgTune](http://pgtune.leopard.in.ua) and [pgBench](http://www.postgresql.org/docs/devel/static/pgbench.html)
224
-
225
- ## TODO
226
-
227
- - suggest indexes
228
- - suggest paramater values
229
- - better explanations on dashboard
29
+ 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:
230
30
 
231
31
  Know a bit about PostgreSQL? [Suggestions](https://github.com/ankane/pghero/issues) are greatly appreciated.
232
32
 
233
- ## Thanks
234
-
235
- 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.
236
-
237
- ## History
238
-
239
- View the [changelog](https://github.com/ankane/pghero/blob/master/CHANGELOG.md)
240
-
241
- ## Contributing
242
-
243
- Everyone is encouraged to help improve this project. Here are a few ways you can help:
244
-
245
- - [Report bugs](https://github.com/ankane/pghero/issues)
246
- - Fix bugs and [submit pull requests](https://github.com/ankane/pghero/pulls)
247
- - Write, clarify, or fix documentation
248
- - Suggest or add new features
33
+ :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
@@ -6,10 +6,11 @@ module PgHero
6
6
 
7
7
  http_basic_authenticate_with name: ENV["PGHERO_USERNAME"], password: ENV["PGHERO_PASSWORD"] if ENV["PGHERO_PASSWORD"]
8
8
 
9
+ around_filter :set_database
9
10
  before_filter :set_query_stats_enabled
10
11
 
11
12
  def index
12
- @title = "Status"
13
+ @title = "Overview"
13
14
  @slow_queries = PgHero.slow_queries
14
15
  @long_running_queries = PgHero.long_running_queries
15
16
  @index_hit_rate = PgHero.index_hit_rate
@@ -20,10 +21,15 @@ module PgHero
20
21
  @query_stats_available = PgHero.query_stats_available?
21
22
  @total_connections = PgHero.total_connections
22
23
  @good_total_connections = @total_connections < PgHero.total_connections_threshold
24
+ @replica = PgHero.replica?
25
+ if @replica
26
+ @replication_lag = PgHero.replication_lag
27
+ @good_replication_lag = @replication_lag < 5
28
+ end
23
29
  end
24
30
 
25
- def indexes
26
- @title = "Indexes"
31
+ def index_usage
32
+ @title = "Index Usage"
27
33
  @index_usage = PgHero.index_usage
28
34
  end
29
35
 
@@ -33,20 +39,30 @@ module PgHero
33
39
  @relation_sizes = PgHero.relation_sizes
34
40
  end
35
41
 
36
- def queries
42
+ def live_queries
37
43
  @title = "Live Queries"
38
44
  @running_queries = PgHero.running_queries
39
45
  end
40
46
 
41
- def query_stats
47
+ def queries
42
48
  @title = "Queries"
43
49
  @query_stats = PgHero.query_stats
44
50
  end
45
51
 
46
- def system_stats
47
- @title = "System Stats"
48
- @cpu_usage = PgHero.cpu_usage.map { |k, v| [k, v.round] }
49
- @connection_stats = PgHero.connection_stats
52
+ def system
53
+ @title = "System"
54
+ end
55
+
56
+ def cpu_usage
57
+ render json: PgHero.cpu_usage.map { |k, v| [k, v.round] }
58
+ end
59
+
60
+ def connection_stats
61
+ render json: PgHero.connection_stats
62
+ end
63
+
64
+ def replication_lag_stats
65
+ render json: PgHero.replication_lag_stats
50
66
  end
51
67
 
52
68
  def explain
@@ -81,6 +97,11 @@ module PgHero
81
97
  end
82
98
  end
83
99
 
100
+ def kill_long_running_queries
101
+ PgHero.kill_long_running_queries
102
+ redirect_to :back, notice: "Queries killed"
103
+ end
104
+
84
105
  def kill_all
85
106
  PgHero.kill_all
86
107
  redirect_to :back, notice: "Connections killed"
@@ -102,6 +123,23 @@ module PgHero
102
123
 
103
124
  protected
104
125
 
126
+ def set_database
127
+ @databases = PgHero.config["databases"].keys
128
+ if params[:database]
129
+ PgHero.with(params[:database]) do
130
+ yield
131
+ end
132
+ elsif @databases.size > 1
133
+ redirect_to url_for(params.slice(:controller, :action).merge(database: PgHero.primary_database))
134
+ else
135
+ yield
136
+ end
137
+ end
138
+
139
+ def default_url_options
140
+ {database: params[:database]}
141
+ end
142
+
105
143
  def set_query_stats_enabled
106
144
  @query_stats_enabled = PgHero.query_stats_enabled?
107
145
  @system_stats_enabled = PgHero.system_stats_enabled?
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= @title %> - PgHero</title>
4
+ <title><%= [@databases.size > 1 ? PgHero.current_database.titleize : "PgHero", @title].compact.join(" / ") %></title>
5
5
 
6
6
  <meta charset="utf-8" />
7
7
 
@@ -9,7 +9,7 @@
9
9
  body {
10
10
  margin: 0;
11
11
  padding: 20px;
12
- background-color: #2b3e50;
12
+ background-color: #eee;
13
13
  }
14
14
 
15
15
  body, textarea {
@@ -65,7 +65,7 @@
65
65
  }
66
66
 
67
67
  pre {
68
- background-color: #ddd;
68
+ background-color: #eee;
69
69
  padding: 10px;
70
70
  white-space: pre-wrap;
71
71
  word-break: break-word;
@@ -74,7 +74,7 @@
74
74
  textarea {
75
75
  width: 100%;
76
76
  height: 100px;
77
- border: solid 1px #ccc;
77
+ border: solid 1px #ddd;
78
78
  padding: 10px;
79
79
  }
80
80
 
@@ -94,13 +94,18 @@
94
94
  margin-left: 6px;
95
95
  }
96
96
 
97
+ .tiny {
98
+ font-size: 12px;
99
+ margin-left: 6px;
100
+ }
101
+
97
102
  #status, .content, .alert {
98
103
  margin-bottom: 20px;
99
104
  }
100
105
 
101
106
  .content {
102
107
  padding: 20px 20px 1px 20px;
103
- background-color: #eee;
108
+ background-color: #fff;
104
109
  }
105
110
 
106
111
  .queries td {
@@ -114,18 +119,25 @@
114
119
  /* nav */
115
120
 
116
121
  .nav a {
117
- color: #fff;
122
+ color: #333;
118
123
  text-decoration: none;
119
124
  display: block;
120
125
  padding: 12px 20px;
121
126
  }
122
127
 
123
128
  .nav li.active a {
124
- background-color: #df691a;
129
+ background-color: #ddd;
125
130
  }
126
131
 
127
132
  .nav a:hover {
128
- background-color: #4e5d6c;
133
+ background-color: #ddd;
134
+ }
135
+
136
+ .nav-header {
137
+ font-weight: bold;
138
+ color: #333;
139
+ padding: 12px 20px 12px 0;
140
+ margin: 0;
129
141
  }
130
142
 
131
143
  /* buttons */
@@ -146,7 +158,7 @@
146
158
  }
147
159
 
148
160
  .btn-danger {
149
- background-color: #df691a;
161
+ background-color: #d9534f;
150
162
  }
151
163
 
152
164
  .btn-info {
@@ -173,7 +185,7 @@
173
185
  }
174
186
 
175
187
  .alert-danger {
176
- background-color: #df691a;
188
+ background-color: #d9534f;
177
189
  }
178
190
 
179
191
  .alert a {
@@ -349,22 +361,37 @@
349
361
 
350
362
  <div class="grid">
351
363
  <div class="col-3-12">
364
+ <% if @databases.size > 1 %>
365
+ <p class="nav-header"><%= PgHero.current_database.titleize %></p>
366
+ <% end %>
367
+
352
368
  <ul class="nav">
353
369
  <!-- poor man's active_link_to -->
354
- <li class="<%= controller.action_name == "index" ? "active" : "" %>"><%= link_to "Status", root_path %></li>
370
+ <li class="<%= controller.action_name == "index" ? "active" : "" %>"><%= link_to "Overview", root_path %></li>
355
371
  <% if @system_stats_enabled %>
356
- <li class="<%= controller.action_name == "system_stats" ? "active" : "" %>"><%= link_to "System", system_stats_path %></li>
372
+ <li class="<%= controller.action_name == "system" ? "active" : "" %>"><%= link_to "System", system_path %></li>
357
373
  <% end %>
358
374
  <% if @query_stats_enabled %>
359
- <li class="<%= controller.action_name == "query_stats" ? "active" : "" %>"><%= link_to "Queries", query_stats_path %></li>
375
+ <li class="<%= controller.action_name == "queries" ? "active" : "" %>"><%= link_to "Queries", queries_path %></li>
360
376
  <% end %>
361
- <li class="<%= controller.action_name == "indexes" ? "active" : "" %>"><%= link_to "Indexes", indexes_path %></li>
377
+ <li class="<%= controller.action_name == "index_usage" ? "active" : "" %>"><%= link_to "Index Usage", index_usage_path %></li>
362
378
  <li class="<%= controller.action_name == "space" ? "active" : "" %>"><%= link_to "Space", space_path %></li>
363
- <li class="<%= controller.action_name == "explain" ? "active" : "" %>"><%= link_to "Explain", explain_path %></li>
364
- <li class="<%= controller.action_name == "queries" ? "active" : "" %>"><%= link_to "Live Queries", queries_path %></li>
365
379
  <li class="<%= controller.action_name == "connections" ? "active" : "" %>"><%= link_to "Connections", connections_path %></li>
380
+ <li class="<%= controller.action_name == "live_queries" ? "active" : "" %>"><%= link_to "Live Queries", live_queries_path %></li>
381
+ <li class="<%= controller.action_name == "explain" ? "active" : "" %>"><%= link_to "Explain", explain_path %></li>
366
382
  <li class="<%= controller.action_name == "tune" ? "active" : "" %>"><%= link_to "Tune", tune_path %></li>
367
383
  </ul>
384
+
385
+ <% if @databases.size > 1 %>
386
+ <p class="nav-header">Other Databases</p>
387
+ <ul class="nav">
388
+ <% (@databases - [PgHero.current_database]).each do |database| %>
389
+ <li>
390
+ <%= link_to database.titleize, root_path(database: database) %>
391
+ </li>
392
+ <% end %>
393
+ </ul>
394
+ <% end %>
368
395
  </div>
369
396
 
370
397
  <div class="col-9-12">