pghero 3.1.0 → 3.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +78 -1
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/app/assets/javascripts/pghero/Chart.bundle.js +23379 -19766
- data/app/assets/javascripts/pghero/application.js +27 -12
- data/app/assets/javascripts/pghero/chartkick.js +834 -764
- data/app/assets/javascripts/pghero/highlight.min.js +440 -0
- data/app/assets/javascripts/pghero/jquery.js +318 -197
- data/app/assets/javascripts/pghero/nouislider.js +676 -1066
- data/app/assets/stylesheets/pghero/application.css +108 -2
- data/app/assets/stylesheets/pghero/nouislider.css +4 -10
- data/app/controllers/pg_hero/home_controller.rb +53 -16
- data/app/helpers/pg_hero/home_helper.rb +3 -3
- data/app/views/layouts/pg_hero/application.html.erb +3 -3
- data/app/views/pg_hero/home/_connections_table.html.erb +1 -1
- data/app/views/pg_hero/home/_live_queries_table.html.erb +8 -8
- data/app/views/pg_hero/home/_queries_table.html.erb +5 -5
- data/app/views/pg_hero/home/_query_stats_slider.html.erb +8 -8
- data/app/views/pg_hero/home/_suggested_index.html.erb +6 -5
- data/app/views/pg_hero/home/connections.html.erb +12 -12
- data/app/views/pg_hero/home/explain.html.erb +2 -2
- data/app/views/pg_hero/home/index.html.erb +22 -20
- data/app/views/pg_hero/home/index_bloat.html.erb +6 -6
- data/app/views/pg_hero/home/maintenance.html.erb +3 -3
- data/app/views/pg_hero/home/queries.html.erb +7 -5
- data/app/views/pg_hero/home/relation_space.html.erb +4 -4
- data/app/views/pg_hero/home/show_query.html.erb +35 -31
- data/app/views/pg_hero/home/space.html.erb +50 -46
- data/app/views/pg_hero/home/system.html.erb +18 -18
- data/app/views/pg_hero/home/tune.html.erb +2 -2
- data/lib/generators/pghero/query_stats_generator.rb +1 -0
- data/lib/generators/pghero/space_stats_generator.rb +1 -0
- data/lib/pghero/database.rb +2 -2
- data/lib/pghero/engine.rb +4 -3
- data/lib/pghero/methods/basic.rb +26 -31
- data/lib/pghero/methods/connections.rb +4 -4
- data/lib/pghero/methods/constraints.rb +1 -1
- data/lib/pghero/methods/explain.rb +4 -3
- data/lib/pghero/methods/indexes.rb +8 -8
- data/lib/pghero/methods/kill.rb +1 -1
- data/lib/pghero/methods/maintenance.rb +3 -3
- data/lib/pghero/methods/queries.rb +2 -2
- data/lib/pghero/methods/query_stats.rb +34 -24
- data/lib/pghero/methods/replication.rb +2 -2
- data/lib/pghero/methods/sequences.rb +10 -5
- data/lib/pghero/methods/settings.rb +8 -1
- data/lib/pghero/methods/space.rb +20 -14
- data/lib/pghero/methods/suggested_indexes.rb +14 -7
- data/lib/pghero/methods/system.rb +12 -6
- data/lib/pghero/methods/tables.rb +4 -5
- data/lib/pghero/version.rb +1 -1
- data/lib/pghero.rb +35 -36
- data/lib/tasks/pghero.rake +11 -1
- data/licenses/LICENSE-chart.js.txt +1 -1
- data/licenses/LICENSE-date-fns.txt +21 -20
- data/licenses/LICENSE-kurkle-color.txt +9 -0
- metadata +8 -11
- data/app/assets/javascripts/pghero/highlight.pack.js +0 -2
@@ -55,9 +55,11 @@
|
|
55
55
|
Vacuuming healthy
|
56
56
|
<% end %>
|
57
57
|
</div>
|
58
|
-
<div class="alert alert-<%= @sequence_danger && @sequence_danger.empty? ? "success" : "warning" %>">
|
58
|
+
<div class="alert alert-<%= @sequence_danger && @sequence_danger.empty? && !@sequences_timeout ? "success" : "warning" %>">
|
59
59
|
<% if @sequence_danger.any? %>
|
60
60
|
<%= pluralize(@sequence_danger.size, "column") %> approaching overflow
|
61
|
+
<% elsif @sequences_timeout %>
|
62
|
+
Sequences not available (system catalog locked)
|
61
63
|
<% else %>
|
62
64
|
No columns near integer overflow
|
63
65
|
<% end %>
|
@@ -125,7 +127,7 @@
|
|
125
127
|
<table class="table">
|
126
128
|
<thead>
|
127
129
|
<tr>
|
128
|
-
<th
|
130
|
+
<th class="width-33">Column</th>
|
129
131
|
<th>Sequence</th>
|
130
132
|
</tr>
|
131
133
|
</thead>
|
@@ -249,7 +251,7 @@
|
|
249
251
|
<thead>
|
250
252
|
<tr>
|
251
253
|
<th>Table</th>
|
252
|
-
<th
|
254
|
+
<th class="width-20">Transactions Left</th>
|
253
255
|
</tr>
|
254
256
|
</thead>
|
255
257
|
<tbody>
|
@@ -277,9 +279,9 @@
|
|
277
279
|
<thead>
|
278
280
|
<tr>
|
279
281
|
<th>Column</th>
|
280
|
-
<th
|
281
|
-
<th
|
282
|
-
<th
|
282
|
+
<th class="width-20">Type</th>
|
283
|
+
<th class="width-20">Values Left</th>
|
284
|
+
<th class="width-10">% Left</th>
|
283
285
|
</tr>
|
284
286
|
</thead>
|
285
287
|
<tbody>
|
@@ -330,7 +332,7 @@
|
|
330
332
|
</td>
|
331
333
|
</tr>
|
332
334
|
<tr>
|
333
|
-
<td
|
335
|
+
<td class="query-row">
|
334
336
|
<pre><code>DROP INDEX CONCURRENTLY <%= pghero_pretty_ident(index[:name], schema: index[:schema]) %>;
|
335
337
|
<%= index[:definition].sub("CREATE INDEX ", "CREATE INDEX CONCURRENTLY ") %>;</code></pre>
|
336
338
|
</td>
|
@@ -364,7 +366,7 @@
|
|
364
366
|
</td>
|
365
367
|
</tr>
|
366
368
|
<tr>
|
367
|
-
<td
|
369
|
+
<td class="query-row">
|
368
370
|
<pre><code>ALTER TABLE <%= pghero_pretty_ident(constraint[:table], schema: constraint[:schema]) %> VALIDATE CONSTRAINT <%= pghero_pretty_ident(constraint[:name]) %>;</code></pre>
|
369
371
|
</td>
|
370
372
|
</tr>
|
@@ -381,15 +383,15 @@
|
|
381
383
|
<p>
|
382
384
|
These indexes exist, but aren’t needed. Remove them
|
383
385
|
<% if @show_migrations %>
|
384
|
-
<a href="
|
386
|
+
<a href="#" class="migration-link">with a migration</a>
|
385
387
|
<% end %>
|
386
388
|
for faster writes.
|
387
389
|
</p>
|
388
390
|
|
389
|
-
<div
|
391
|
+
<div class="migration">
|
390
392
|
<pre>rails generate migration remove_unneeded_indexes</pre>
|
391
393
|
<p>And paste</p>
|
392
|
-
<pre
|
394
|
+
<pre><% @duplicate_indexes.each do |query| %>
|
393
395
|
<%= pghero_remove_index(query[:unneeded_index]) %><% end %></pre>
|
394
396
|
</div>
|
395
397
|
|
@@ -424,14 +426,14 @@
|
|
424
426
|
Add indexes to speed up queries.
|
425
427
|
<% if @show_migrations %>
|
426
428
|
Here’s a
|
427
|
-
<a href="
|
429
|
+
<a href="#" class="migration-link">migration</a> to help.
|
428
430
|
<% end %>
|
429
431
|
</p>
|
430
432
|
|
431
|
-
<div
|
433
|
+
<div class="migration">
|
432
434
|
<pre>rails generate migration add_suggested_indexes</pre>
|
433
435
|
<p>And paste</p>
|
434
|
-
<pre
|
436
|
+
<pre>commit_db_transaction
|
435
437
|
<% @suggested_indexes.each do |index| %>
|
436
438
|
<% if index[:using] && index[:using] != "btree" %>
|
437
439
|
add_index <%= index[:table].to_sym.inspect %>, <%= index[:columns].first.inspect %>, using: <%= index[:using].inspect %>, algorithm: :concurrently
|
@@ -485,15 +487,15 @@ pg_stat_statements.track = all</pre>
|
|
485
487
|
<p>
|
486
488
|
Unused indexes cause unnecessary overhead. Remove them
|
487
489
|
<% if @show_migrations %>
|
488
|
-
<a href="
|
490
|
+
<a href="#" class="migration-link">with a migration</a>
|
489
491
|
<% end %>
|
490
492
|
for faster writes.
|
491
493
|
</p>
|
492
494
|
|
493
|
-
<div
|
495
|
+
<div class="migration">
|
494
496
|
<pre>rails generate migration remove_unused_indexes</pre>
|
495
497
|
<p>And paste</p>
|
496
|
-
<pre
|
498
|
+
<pre><% @unused_indexes.each do |query| %>
|
497
499
|
<%= pghero_remove_index(query)%><% end %></pre>
|
498
500
|
</div>
|
499
501
|
|
@@ -501,7 +503,7 @@ pg_stat_statements.track = all</pre>
|
|
501
503
|
<thead>
|
502
504
|
<tr>
|
503
505
|
<th>Name</th>
|
504
|
-
<th
|
506
|
+
<th class="width-20">Index Size</th>
|
505
507
|
</tr>
|
506
508
|
</thead>
|
507
509
|
<tbody>
|
@@ -516,6 +518,6 @@ pg_stat_statements.track = all</pre>
|
|
516
518
|
</div>
|
517
519
|
<% end %>
|
518
520
|
|
519
|
-
|
521
|
+
<%= javascript_tag nonce: true do %>
|
520
522
|
highlightQueries();
|
521
|
-
|
523
|
+
<% end %>
|
@@ -25,15 +25,15 @@ ALTER INDEX new_index RENAME TO index;</code></pre>
|
|
25
25
|
<thead>
|
26
26
|
<tr>
|
27
27
|
<th>Index</th>
|
28
|
-
<th
|
29
|
-
<th
|
28
|
+
<th class="width-15">Bloat</th>
|
29
|
+
<th class="width-15">Size</th>
|
30
30
|
</tr>
|
31
31
|
</thead>
|
32
32
|
<tbody>
|
33
33
|
<% @index_bloat.each do |index| %>
|
34
34
|
<tr>
|
35
35
|
<td>
|
36
|
-
<span
|
36
|
+
<span class="break-all"><%= index[:index] %></span>
|
37
37
|
<% if index[:primary] %>
|
38
38
|
<span class="primary-key">PRIMARY</span>
|
39
39
|
<% end %>
|
@@ -43,7 +43,7 @@ ALTER INDEX new_index RENAME TO index;</code></pre>
|
|
43
43
|
</tr>
|
44
44
|
<% if @show_sql && !index[:primary] %>
|
45
45
|
<tr>
|
46
|
-
<td colspan="3"
|
46
|
+
<td colspan="3" class="query-row">
|
47
47
|
<% new_index = "new_#{index[:index]}".first(63) %>
|
48
48
|
<pre><code><%= index[:definition].sub(" INDEX ", " INDEX CONCURRENTLY \n ").sub(index[:index], new_index) %>;
|
49
49
|
|
@@ -67,6 +67,6 @@ ALTER INDEX <%= pghero_pretty_ident(new_index) %>
|
|
67
67
|
<% end %>
|
68
68
|
</div>
|
69
69
|
|
70
|
-
|
70
|
+
<%= javascript_tag nonce: true do %>
|
71
71
|
highlightQueries();
|
72
|
-
|
72
|
+
<% end %>
|
@@ -5,10 +5,10 @@
|
|
5
5
|
<thead>
|
6
6
|
<tr>
|
7
7
|
<th>Table</th>
|
8
|
-
<th
|
9
|
-
<th
|
8
|
+
<th class="width-20">Last Vacuum</th>
|
9
|
+
<th class="width-20">Last Analyze</th>
|
10
10
|
<% if @show_dead_rows %>
|
11
|
-
<th
|
11
|
+
<th class="width-20">Dead Rows</th>
|
12
12
|
<% end %>
|
13
13
|
</tr>
|
14
14
|
</thead>
|
@@ -1,14 +1,16 @@
|
|
1
1
|
<div class="content">
|
2
|
-
<% if @query_stats_enabled %>
|
2
|
+
<% if @query_stats_enabled && !@historical_query_stats_enabled %>
|
3
3
|
<%= button_to "Reset", reset_query_stats_path, class: "btn btn-danger", style: "float: right;" %>
|
4
4
|
<% end %>
|
5
5
|
|
6
|
-
|
6
|
+
<% if !@historical_query_stats_enabled %>
|
7
|
+
<h1 class="push-left">Queries</h1>
|
8
|
+
<% end %>
|
7
9
|
|
8
10
|
<% if @historical_query_stats_enabled %>
|
9
11
|
<%= render partial: "query_stats_slider" %>
|
10
12
|
<% elsif @database.query_stats_table_exists? && (columns = @database.missing_query_stats_columns).any? %>
|
11
|
-
<div
|
13
|
+
<div class="clear-both">
|
12
14
|
<p>Add missing columns to re-enable historical query stats.</p>
|
13
15
|
<pre><code><% @database.missing_query_stats_columns.each do |column| %>ALTER TABLE pghero_query_stats ADD COLUMN "<%= column %>" <%= column == "query_hash" ? "bigint" : "text" %>;
|
14
16
|
<% end %></code></pre>
|
@@ -21,9 +23,9 @@
|
|
21
23
|
<div class="alert alert-danger">Cannot understand start or end time.</div>
|
22
24
|
<% elsif @query_stats.any? || @historical_query_stats_enabled %>
|
23
25
|
<%= render partial: "queries_table", locals: {queries: @query_stats, sort_headers: true} %>
|
24
|
-
|
26
|
+
<%= javascript_tag nonce: true do %>
|
25
27
|
highlightQueries();
|
26
|
-
|
28
|
+
<% end %>
|
27
29
|
<% else %>
|
28
30
|
<p>Stats are not available yet. Come back soon!</p>
|
29
31
|
<% end %>
|
@@ -7,8 +7,8 @@
|
|
7
7
|
</h1>
|
8
8
|
|
9
9
|
<h1>Size</h1>
|
10
|
-
<div id="chart-1" class="chart"
|
11
|
-
|
12
|
-
new Chartkick.LineChart("chart-1", <%=
|
13
|
-
|
10
|
+
<div id="chart-1" class="chart">Loading...</div>
|
11
|
+
<%= javascript_tag nonce: true do %>
|
12
|
+
new Chartkick.LineChart("chart-1", <%= pghero_js_value(@chart_data) %>, {colors: ["#5bc0de"], legend: false, min: null, bytes: true, library: {plugins: {tooltip: {intersect: false, mode: "index"}}}})
|
13
|
+
<% end %>
|
14
14
|
</div>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<div class="content">
|
2
|
-
<pre><code
|
3
|
-
|
2
|
+
<pre><code class="query-code"><%= @query %></code></pre>
|
3
|
+
<%= javascript_tag nonce: true do %>
|
4
4
|
highlightQueries()
|
5
|
-
|
5
|
+
<% end %>
|
6
6
|
|
7
7
|
<% if @explain_enabled && @explainable_query %>
|
8
8
|
<p>
|
@@ -11,11 +11,11 @@
|
|
11
11
|
<% end %>
|
12
12
|
|
13
13
|
<% if @origins && @origins.keys.select { |k| k.length > 0 }.any? %>
|
14
|
-
<table
|
14
|
+
<table class="origins-table">
|
15
15
|
<thead>
|
16
16
|
<tr>
|
17
17
|
<th colspan="2">
|
18
|
-
<div
|
18
|
+
<div class="push-right">Approx. Time</div>
|
19
19
|
Origin
|
20
20
|
</th>
|
21
21
|
</tr>
|
@@ -23,14 +23,14 @@
|
|
23
23
|
<tbody>
|
24
24
|
<% @origins.sort_by { |o, c| [-c, o.to_s] }.each do |origin, count| %>
|
25
25
|
<tr>
|
26
|
-
<td class="origin"
|
26
|
+
<td class="origin">
|
27
27
|
<% if origin.length > 0 %>
|
28
28
|
<%= origin %>
|
29
29
|
<% else %>
|
30
30
|
<span class="text-muted">Unknown</span>
|
31
31
|
<% end %>
|
32
32
|
</td>
|
33
|
-
<td
|
33
|
+
<td class="origin-pct">
|
34
34
|
<% pct = (100.0 * count / @total_count).round %>
|
35
35
|
<% if pct == 0 %>
|
36
36
|
< 1%
|
@@ -47,22 +47,22 @@
|
|
47
47
|
<!-- chart -->
|
48
48
|
<% if @chart_data %>
|
49
49
|
<h1>Total Time <small>ms</small></h1>
|
50
|
-
<div id="chart-1" class="chart"
|
51
|
-
|
52
|
-
new Chartkick.LineChart("chart-1", <%=
|
53
|
-
|
50
|
+
<div id="chart-1" class="chart">Loading...</div>
|
51
|
+
<%= javascript_tag nonce: true do %>
|
52
|
+
new Chartkick.LineChart("chart-1", <%= pghero_js_value(@chart_data) %>, {colors: ["#5bc0de"], legend: false, library: {plugins: {tooltip: {intersect: false, mode: "index"}}}})
|
53
|
+
<% end %>
|
54
54
|
|
55
55
|
<h1>Average Time <small>ms</small></h1>
|
56
|
-
<div id="chart-2" class="chart"
|
57
|
-
|
58
|
-
new Chartkick.LineChart("chart-2", <%=
|
59
|
-
|
56
|
+
<div id="chart-2" class="chart">Loading...</div>
|
57
|
+
<%= javascript_tag nonce: true do %>
|
58
|
+
new Chartkick.LineChart("chart-2", <%= pghero_js_value(@chart2_data) %>, {colors: ["#5bc0de"], legend: false, library: {plugins: {tooltip: {intersect: false, mode: "index"}}}})
|
59
|
+
<% end %>
|
60
60
|
|
61
61
|
<h1>Calls</h1>
|
62
|
-
<div id="chart-3" class="chart"
|
63
|
-
|
64
|
-
new Chartkick.LineChart("chart-3", <%=
|
65
|
-
|
62
|
+
<div id="chart-3" class="chart">Loading...</div>
|
63
|
+
<%= javascript_tag nonce: true do %>
|
64
|
+
new Chartkick.LineChart("chart-3", <%= pghero_js_value(@chart3_data) %>, {colors: ["#5bc0de"], legend: false, library: {plugins: {tooltip: {intersect: false, mode: "index"}}}})
|
65
|
+
<% end %>
|
66
66
|
<% else %>
|
67
67
|
<p>
|
68
68
|
Enable
|
@@ -77,8 +77,8 @@
|
|
77
77
|
<table>
|
78
78
|
<thead>
|
79
79
|
<tr>
|
80
|
-
<th
|
81
|
-
<th
|
80
|
+
<th class="width-25">Name</th>
|
81
|
+
<th class="width-25">Rows</th>
|
82
82
|
<th>Indexes</th>
|
83
83
|
</tr>
|
84
84
|
</thead>
|
@@ -86,17 +86,21 @@
|
|
86
86
|
<% @tables.each do |table| %>
|
87
87
|
<tr>
|
88
88
|
<td><%= table %></td>
|
89
|
-
<td><%= @row_counts[table] %></td>
|
89
|
+
<td><%= number_with_delimiter(@row_counts[table]) if @row_counts[table] %></td>
|
90
90
|
<td>
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
91
|
+
<% if @indexes_timeout %>
|
92
|
+
Not available
|
93
|
+
<% else %>
|
94
|
+
<ul>
|
95
|
+
<% @indexes_by_table[table].to_a.sort_by { |i| [i[:primary] ? 0 : 1, i[:columns]] }.each do |i3| %>
|
96
|
+
<li>
|
97
|
+
<%= i3[:columns].join(", ") %><% if i3[:using] != "btree" %>
|
98
|
+
<%= i3[:using].to_s.upcase %><% end %>
|
99
|
+
<% if i3[:primary] %> PRIMARY<% elsif i3[:unique] %> UNIQUE<% end %>
|
100
|
+
</li>
|
101
|
+
<% end %>
|
102
|
+
</ul>
|
103
|
+
<% end %>
|
100
104
|
</td>
|
101
105
|
</tr>
|
102
106
|
<% end %>
|
@@ -4,10 +4,10 @@
|
|
4
4
|
<p>Database Size: <%= @database_size %></p>
|
5
5
|
|
6
6
|
<% if @system_stats_enabled %>
|
7
|
-
<div id="chart-1" class="chart"
|
8
|
-
|
9
|
-
new Chartkick.LineChart("chart-1", <%=
|
10
|
-
|
7
|
+
<div id="chart-1" class="chart">Loading...</div>
|
8
|
+
<%= javascript_tag nonce: true do %>
|
9
|
+
new Chartkick.LineChart("chart-1", <%= pghero_js_value(free_space_stats_path) %>, {colors: ["#5bc0de"], bytes: true, library: {plugins: {tooltip: {intersect: false, mode: "index"}}}})
|
10
|
+
<% end %>
|
11
11
|
<% end %>
|
12
12
|
|
13
13
|
<!--
|
@@ -20,7 +20,7 @@
|
|
20
20
|
<p>
|
21
21
|
<%= pluralize(@unused_indexes.size, "unused index") %>. Remove them
|
22
22
|
<% if @show_migrations %>
|
23
|
-
<a href="
|
23
|
+
<a href="#" class="migration-link">with a migration</a>
|
24
24
|
<% end %>
|
25
25
|
for faster writes.
|
26
26
|
|
@@ -29,55 +29,59 @@
|
|
29
29
|
<% end %>
|
30
30
|
</p>
|
31
31
|
|
32
|
-
<div
|
32
|
+
<div class="migration">
|
33
33
|
<pre>rails generate migration remove_unused_indexes</pre>
|
34
34
|
<p>And paste</p>
|
35
|
-
<pre
|
35
|
+
<pre><% @unused_indexes.sort_by { |q| [-q[:size_bytes], q[:index]] }.each do |query| %>
|
36
36
|
<%= pghero_remove_index(query) %><% end %></pre>
|
37
37
|
</div>
|
38
38
|
<% end %>
|
39
39
|
|
40
|
-
|
41
|
-
<
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
<% if @space_stats_enabled %>
|
46
|
-
<th style="width: 15%;"><%= link_to "#{@days}d Growth", @header_options.merge(sort: "growth") %></th>
|
47
|
-
<% end %>
|
48
|
-
</tr>
|
49
|
-
</thead>
|
50
|
-
<tbody>
|
51
|
-
<% @relation_sizes.each do |query| %>
|
40
|
+
<% if @sizes_timeout %>
|
41
|
+
<p>Breakdown not available (system catalog locked)</p>
|
42
|
+
<% else %>
|
43
|
+
<table class="table space-table">
|
44
|
+
<thead>
|
52
45
|
<tr>
|
53
|
-
<
|
54
|
-
|
55
|
-
<% name = query[:relation] || query[:table] %>
|
56
|
-
<% if @space_stats_enabled %>
|
57
|
-
<%= link_to name, relation_space_path(name, schema: query[:schema]), target: "_blank", style: "color: inherit;" %>
|
58
|
-
<% else %>
|
59
|
-
<%= name %>
|
60
|
-
<% end %>
|
61
|
-
</span>
|
62
|
-
<% if query[:schema] != "public" %>
|
63
|
-
<span class="text-muted"><%= query[:schema] %></span>
|
64
|
-
<% end %>
|
65
|
-
<% if @unused_index_names.include?(query[:relation]) %>
|
66
|
-
<span class="unused-index">UNUSED</span>
|
67
|
-
<% end %>
|
68
|
-
</td>
|
69
|
-
<td><%= query[:size] %></td>
|
46
|
+
<th><%= link_to (@only_tables ? "Table" : "Relation"), @header_options.merge(sort: "name") %></th>
|
47
|
+
<th class="width-15"><%= link_to "Size", @header_options %></th>
|
70
48
|
<% if @space_stats_enabled %>
|
71
|
-
<
|
72
|
-
<% if @growth_bytes_by_relation[[query[:schema], query[:relation]]] %>
|
73
|
-
<% if @growth_bytes_by_relation[[query[:schema], query[:relation]]] < 0 %>-<% end %><%= PgHero.pretty_size(@growth_bytes_by_relation[[query[:schema], query[:relation]]].abs) %>
|
74
|
-
<% else %>
|
75
|
-
<span class="text-muted">Unknown</span>
|
76
|
-
<% end %>
|
77
|
-
</td>
|
49
|
+
<th class="width-15"><%= link_to "#{@days}d Growth", @header_options.merge(sort: "growth") %></th>
|
78
50
|
<% end %>
|
79
51
|
</tr>
|
80
|
-
|
81
|
-
|
82
|
-
|
52
|
+
</thead>
|
53
|
+
<tbody>
|
54
|
+
<% @relation_sizes.each do |query| %>
|
55
|
+
<tr>
|
56
|
+
<td class="<%= query[:type] == "index" ? "space-index" : "" %>">
|
57
|
+
<span class="break-all">
|
58
|
+
<% name = query[:relation] || query[:table] %>
|
59
|
+
<% if @space_stats_enabled %>
|
60
|
+
<%= link_to name, relation_space_path(name, schema: query[:schema]), target: "_blank", class: "relation-link" %>
|
61
|
+
<% else %>
|
62
|
+
<%= name %>
|
63
|
+
<% end %>
|
64
|
+
</span>
|
65
|
+
<% if query[:schema] != "public" %>
|
66
|
+
<span class="text-muted"><%= query[:schema] %></span>
|
67
|
+
<% end %>
|
68
|
+
<% if @unused_index_names.include?(query[:relation]) %>
|
69
|
+
<span class="unused-index">UNUSED</span>
|
70
|
+
<% end %>
|
71
|
+
</td>
|
72
|
+
<td><%= query[:size] %></td>
|
73
|
+
<% if @space_stats_enabled %>
|
74
|
+
<td>
|
75
|
+
<% if @growth_bytes_by_relation[[query[:schema], query[:relation]]] %>
|
76
|
+
<% if @growth_bytes_by_relation[[query[:schema], query[:relation]]] < 0 %>-<% end %><%= PgHero.pretty_size(@growth_bytes_by_relation[[query[:schema], query[:relation]]].abs) %>
|
77
|
+
<% else %>
|
78
|
+
<span class="text-muted">Unknown</span>
|
79
|
+
<% end %>
|
80
|
+
</td>
|
81
|
+
<% end %>
|
82
|
+
</tr>
|
83
|
+
<% end %>
|
84
|
+
</tbody>
|
85
|
+
</table>
|
86
|
+
<% end %>
|
83
87
|
</div>
|
@@ -1,34 +1,34 @@
|
|
1
1
|
<div class="content">
|
2
2
|
<p id="periods">
|
3
3
|
<% @periods.each do |name, options| %>
|
4
|
-
<%= link_to name, system_path(options) %>
|
4
|
+
<%= link_to name, system_path(params: options) %>
|
5
5
|
<% end %>
|
6
6
|
</p>
|
7
|
-
<% path_options = {duration: @duration, period: @period} %>
|
7
|
+
<% path_options = {params: {duration: @duration, period: @period}} %>
|
8
8
|
|
9
9
|
<h1>CPU</h1>
|
10
|
-
<div id="chart-1" class="chart"
|
11
|
-
|
12
|
-
new Chartkick.LineChart("chart-1", <%=
|
13
|
-
|
10
|
+
<div id="chart-1" class="chart">Loading...</div>
|
11
|
+
<%= javascript_tag nonce: true do %>
|
12
|
+
new Chartkick.LineChart("chart-1", <%= pghero_js_value(cpu_usage_path(path_options)) %>, {max: 100, colors: ["#5bc0de"], suffix: "%", library: {plugins: {tooltip: {intersect: false, mode: "index"}}}})
|
13
|
+
<% end %>
|
14
14
|
|
15
15
|
<h1>Load</h1>
|
16
|
-
<div id="chart-2" class="chart"
|
17
|
-
|
18
|
-
new Chartkick.LineChart("chart-2", <%=
|
19
|
-
|
16
|
+
<div id="chart-2" class="chart">Loading...</div>
|
17
|
+
<%= javascript_tag nonce: true do %>
|
18
|
+
new Chartkick.LineChart("chart-2", <%= pghero_js_value(load_stats_path(path_options)) %>, {colors: ["#5bc0de", "#d9534f"], library: {plugins: {tooltip: {intersect: false, mode: "nearest"}}}})
|
19
|
+
<% end %>
|
20
20
|
|
21
21
|
<h1>Connections</h1>
|
22
|
-
<div id="chart-3" class="chart"
|
23
|
-
|
24
|
-
new Chartkick.LineChart("chart-3", <%=
|
25
|
-
|
22
|
+
<div id="chart-3" class="chart">Loading...</div>
|
23
|
+
<%= javascript_tag nonce: true do %>
|
24
|
+
new Chartkick.LineChart("chart-3", <%= pghero_js_value(connection_stats_path(path_options)) %>, {colors: ["#5bc0de"], library: {plugins: {tooltip: {intersect: false, mode: "index"}}}})
|
25
|
+
<% end %>
|
26
26
|
|
27
27
|
<% if @database.replica? %>
|
28
28
|
<h1>Replication Lag</h1>
|
29
|
-
<div id="chart-4" class="chart"
|
30
|
-
|
31
|
-
new Chartkick.LineChart("chart-4", <%=
|
32
|
-
|
29
|
+
<div id="chart-4" class="chart">Loading...</div>
|
30
|
+
<%= javascript_tag nonce: true do %>
|
31
|
+
new Chartkick.LineChart("chart-4", <%= pghero_js_value(replication_lag_stats_path(path_options)) %>, {colors: ["#5bc0de"], library: {plugins: {tooltip: {intersect: false, mode: "index"}}}})
|
32
|
+
<% end %>
|
33
33
|
<% end %>
|
34
34
|
</div>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<thead>
|
6
6
|
<tr>
|
7
7
|
<th>Setting</th>
|
8
|
-
<th
|
8
|
+
<th class="width-20">Value</th>
|
9
9
|
</tr>
|
10
10
|
</thead>
|
11
11
|
<tbody>
|
@@ -30,7 +30,7 @@
|
|
30
30
|
<thead>
|
31
31
|
<tr>
|
32
32
|
<th>Setting</th>
|
33
|
-
<th
|
33
|
+
<th class="width-20">Value</th>
|
34
34
|
</tr>
|
35
35
|
</thead>
|
36
36
|
<tbody>
|
data/lib/pghero/database.rb
CHANGED
@@ -126,7 +126,7 @@ module PgHero
|
|
126
126
|
# rough check for Postgres adapter
|
127
127
|
# keep this message generic so it's useful
|
128
128
|
# when empty url set in Docker image pghero.yml
|
129
|
-
unless @connection_model.
|
129
|
+
unless @connection_model.connection_db_config.adapter.to_s.match?(/postg/i)
|
130
130
|
raise Error, "Invalid connection URL"
|
131
131
|
end
|
132
132
|
@adapter_checked = true
|
@@ -145,7 +145,7 @@ module PgHero
|
|
145
145
|
config_options = {env_name: PgHero.env, PgHero.spec_name_key => config["spec"], PgHero.include_replicas_key => true}
|
146
146
|
resolved = ActiveRecord::Base.configurations.configs_for(**config_options)
|
147
147
|
raise Error, "Spec not found: #{config["spec"]}" unless resolved
|
148
|
-
url =
|
148
|
+
url = resolved.configuration_hash
|
149
149
|
end
|
150
150
|
|
151
151
|
url = url.dup
|
data/lib/pghero/engine.rb
CHANGED
@@ -4,8 +4,8 @@ module PgHero
|
|
4
4
|
|
5
5
|
initializer "pghero", group: :all do |app|
|
6
6
|
# check if Rails api mode
|
7
|
-
if app.config.respond_to?(:assets)
|
8
|
-
if
|
7
|
+
if app.config.respond_to?(:assets) && defined?(Sprockets)
|
8
|
+
if Sprockets::VERSION.to_i >= 4
|
9
9
|
app.config.assets.precompile << "pghero/application.js"
|
10
10
|
app.config.assets.precompile << "pghero/application.css"
|
11
11
|
app.config.assets.precompile << "pghero/favicon.png"
|
@@ -17,7 +17,8 @@ module PgHero
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
file_config = PgHero.file_config || {}
|
21
|
+
PgHero.time_zone = file_config["time_zone"] if file_config["time_zone"]
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|