pghero 2.2.1 → 2.7.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.

Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +100 -53
  3. data/README.md +20 -8
  4. data/app/assets/javascripts/pghero/Chart.bundle.js +16260 -15580
  5. data/app/assets/javascripts/pghero/application.js +8 -7
  6. data/app/assets/javascripts/pghero/chartkick.js +1973 -1325
  7. data/app/assets/javascripts/pghero/highlight.pack.js +2 -2
  8. data/app/assets/javascripts/pghero/jquery.js +3605 -4015
  9. data/app/assets/javascripts/pghero/nouislider.js +2479 -0
  10. data/app/assets/stylesheets/pghero/application.css +1 -1
  11. data/app/assets/stylesheets/pghero/nouislider.css +299 -0
  12. data/app/controllers/pg_hero/home_controller.rb +97 -42
  13. data/app/helpers/pg_hero/home_helper.rb +11 -0
  14. data/app/views/pg_hero/home/_live_queries_table.html.erb +14 -3
  15. data/app/views/pg_hero/home/connections.html.erb +9 -0
  16. data/app/views/pg_hero/home/index.html.erb +49 -10
  17. data/app/views/pg_hero/home/live_queries.html.erb +1 -1
  18. data/app/views/pg_hero/home/maintenance.html.erb +16 -2
  19. data/app/views/pg_hero/home/relation_space.html.erb +2 -2
  20. data/app/views/pg_hero/home/show_query.html.erb +4 -5
  21. data/app/views/pg_hero/home/space.html.erb +3 -3
  22. data/app/views/pg_hero/home/system.html.erb +4 -4
  23. data/app/views/pg_hero/home/tune.html.erb +2 -1
  24. data/lib/generators/pghero/config_generator.rb +1 -1
  25. data/lib/generators/pghero/query_stats_generator.rb +3 -20
  26. data/lib/generators/pghero/space_stats_generator.rb +3 -20
  27. data/lib/generators/pghero/templates/config.yml.tt +21 -1
  28. data/lib/pghero.rb +82 -17
  29. data/lib/pghero/database.rb +104 -19
  30. data/lib/pghero/methods/basic.rb +34 -25
  31. data/lib/pghero/methods/connections.rb +35 -0
  32. data/lib/pghero/methods/constraints.rb +30 -0
  33. data/lib/pghero/methods/explain.rb +1 -1
  34. data/lib/pghero/methods/indexes.rb +1 -1
  35. data/lib/pghero/methods/maintenance.rb +3 -1
  36. data/lib/pghero/methods/queries.rb +7 -3
  37. data/lib/pghero/methods/query_stats.rb +93 -25
  38. data/lib/pghero/methods/sequences.rb +1 -1
  39. data/lib/pghero/methods/space.rb +4 -0
  40. data/lib/pghero/methods/suggested_indexes.rb +1 -1
  41. data/lib/pghero/methods/system.rb +219 -23
  42. data/lib/pghero/methods/users.rb +4 -0
  43. data/lib/pghero/query_stats.rb +1 -3
  44. data/lib/pghero/space_stats.rb +5 -0
  45. data/lib/pghero/stats.rb +6 -0
  46. data/lib/pghero/version.rb +1 -1
  47. data/lib/tasks/pghero.rake +10 -4
  48. metadata +15 -12
  49. data/app/assets/javascripts/pghero/jquery.nouislider.min.js +0 -31
  50. data/app/assets/stylesheets/pghero/jquery.nouislider.css +0 -165
@@ -15,5 +15,16 @@ module PgHero
15
15
  def pghero_js_var(name, value)
16
16
  "var #{name} = #{json_escape(value.to_json(root: false))};".html_safe
17
17
  end
18
+
19
+ def pghero_remove_index(query)
20
+ if query[:columns]
21
+ columns = query[:columns].map(&:to_sym)
22
+ columns = columns.first if columns.size == 1
23
+ end
24
+ ret = String.new("remove_index #{query[:table].to_sym.inspect}")
25
+ ret << ", name: #{(query[:name] || query[:index]).to_s.inspect}"
26
+ ret << ", column: #{columns.inspect}" if columns
27
+ ret
28
+ end
18
29
  end
19
30
  end
@@ -11,7 +11,17 @@
11
11
  <% queries.reverse.each do |query| %>
12
12
  <tr>
13
13
  <td><%= query[:pid] %></td>
14
- <td><%= number_with_delimiter(query[:duration_ms].round) %> ms</td>
14
+ <td>
15
+ <% sec = query[:duration_ms] / 1000.0 %>
16
+ <% if sec < 1.minute %>
17
+ <%= sec.round(1) %> s
18
+ <% elsif sec < 1.day %>
19
+ <%= Time.at(sec).utc.strftime("%H:%M:%S") %>
20
+ <% else %>
21
+ <% days = (sec / 1.day).floor %>
22
+ <%= days %>d <%= Time.at(sec - days.days).utc.strftime("%H:%M:%S") %>
23
+ <% end %>
24
+ </td>
15
25
  <td>
16
26
  <%= query[:state] %>
17
27
  <% if vacuum_progress[query[:pid]] %>
@@ -20,8 +30,9 @@
20
30
  <% end %>
21
31
  </td>
22
32
  <td class="text-right">
23
- <% button_path, button_options = Rails.version >= "4.1" ? [explain_path, {params: {query: query[:query]}}] : [explain_path(query: query[:query]), {}] %>
24
- <%= button_to "Explain", button_path, button_options.merge(form: {target: "_blank"}, class: "btn btn-info") %>
33
+ <% unless @database.filter_data %>
34
+ <%= button_to "Explain", explain_path, params: {query: query[:query]}, form: {target: "_blank"}, class: "btn btn-info" %>
35
+ <% end %>
25
36
  <%= button_to "Kill", kill_path(pid: query[:pid]), class: "btn btn-danger" %>
26
37
  </td>
27
38
  </tr>
@@ -18,6 +18,15 @@
18
18
  new Chartkick.PieChart("chart-2", <%= json_escape(@connections_by_user.to_json).html_safe %>);
19
19
  </script>
20
20
 
21
+ <% if @connections_by_ssl_status %>
22
+ <h3>By Security</h3>
23
+
24
+ <div id="chart-3" class="chart" style="height: 260px; line-height: 260px; margin-bottom: 20px;">Loading...</div>
25
+ <script>
26
+ new Chartkick.PieChart("chart-3", <%= json_escape(@connections_by_ssl_status.to_json).html_safe %>);
27
+ </script>
28
+ <% end %>
29
+
21
30
  <%= render partial: "connections_table", locals: {connection_sources: @connection_sources} %>
22
31
  <% end %>
23
32
  </div>
@@ -62,11 +62,17 @@
62
62
  (<%= link_to pluralize(@unreadable_sequences.size, "unreadable sequence", "unreadable sequences"), {unreadable: "t"} %>)
63
63
  <% end %>
64
64
  </div>
65
- <div class="alert alert-<%= @invalid_indexes.empty? ? "success" : "warning" %>">
66
- <% if @invalid_indexes.any? %>
67
- <%= pluralize(@invalid_indexes.size, "invalid index", "invalid indexes") %>
65
+ <div class="alert alert-<%= @invalid_indexes.empty? && @invalid_constraints.empty? ? "success" : "warning" %>">
66
+ <% if @invalid_indexes.empty? && @invalid_constraints.empty? %>
67
+ No invalid indexes or constraints
68
68
  <% else %>
69
- No invalid indexes
69
+ <% if @invalid_indexes.any? %>
70
+ <%= pluralize(@invalid_indexes.size, "invalid index", "invalid indexes") %>
71
+ <% end %>
72
+ <% if @invalid_constraints.any? %>
73
+ <% if @invalid_indexes.any? %>and<% end %>
74
+ <%= pluralize(@invalid_constraints.size, "invalid constraint", "invalid constraints") %>
75
+ <% end %>
70
76
  <% end %>
71
77
  </div>
72
78
  <% if @duplicate_indexes %>
@@ -332,6 +338,39 @@
332
338
  </div>
333
339
  <% end %>
334
340
 
341
+ <% if @invalid_constraints.any? %>
342
+ <div class="content">
343
+ <h1>Invalid Constraints</h1>
344
+
345
+ <p>These constraints are marked as <code>NOT VALID</code>. You should validate them.</p>
346
+
347
+ <table class="table">
348
+ <thead>
349
+ <tr>
350
+ <th>Name</th>
351
+ </tr>
352
+ </thead>
353
+ <tbody>
354
+ <% @invalid_constraints.each do |constraint| %>
355
+ <tr>
356
+ <td>
357
+ <%= constraint[:name] %>
358
+ <% if constraint[:schema] != "public" %>
359
+ <span class="text-muted"><%= constraint[:schema] %></span>
360
+ <% end %>
361
+ </td>
362
+ </tr>
363
+ <tr>
364
+ <td style="border-top: none; padding: 0;">
365
+ <pre><code>ALTER TABLE <%= pghero_pretty_ident(constraint[:table], schema: constraint[:schema]) %> VALIDATE CONSTRAINT <%= pghero_pretty_ident(constraint[:name]) %>;</code></pre>
366
+ </td>
367
+ </tr>
368
+ <% end %>
369
+ </tbody>
370
+ </table>
371
+ </div>
372
+ <% end %>
373
+
335
374
  <% if @duplicate_indexes && @duplicate_indexes.any? %>
336
375
  <div class="content">
337
376
  <h1>Duplicate Indexes</h1>
@@ -345,10 +384,10 @@
345
384
  </p>
346
385
 
347
386
  <div id="migration2" style="display: none;">
348
- <pre>rails g migration remove_unneeded_indexes</pre>
387
+ <pre>rails generate migration remove_unneeded_indexes</pre>
349
388
  <p>And paste</p>
350
389
  <pre style="overflow: scroll; white-space: pre; word-break: normal;"><% @duplicate_indexes.each do |query| %>
351
- remove_index <%= query[:unneeded_index][:table].to_sym.inspect %>, name: <%= query[:unneeded_index][:name].to_s.inspect %><% end %></pre>
390
+ <%= pghero_remove_index(query[:unneeded_index]) %><% end %></pre>
352
391
  </div>
353
392
 
354
393
  <table class="table duplicate-indexes">
@@ -387,12 +426,12 @@ remove_index <%= query[:unneeded_index][:table].to_sym.inspect %>, name: <%= que
387
426
  </p>
388
427
 
389
428
  <div id="migration3" style="display: none;">
390
- <pre>rails g migration add_suggested_indexes</pre>
429
+ <pre>rails generate migration add_suggested_indexes</pre>
391
430
  <p>And paste</p>
392
431
  <pre style="overflow: scroll; white-space: pre; word-break: normal;">commit_db_transaction
393
432
  <% @suggested_indexes.each do |index| %>
394
433
  <% if index[:using] && index[:using] != "btree" %>
395
- connection.execute("CREATE INDEX CONCURRENTLY ON <%= index[:table] %><% if index[:using] %> USING <%= index[:using] %><% end %> (<%= index[:columns].join(", ") %>)")
434
+ add_index <%= index[:table].to_sym.inspect %>, <%= index[:columns].first.inspect %>, using: <%= index[:using].inspect %>, algorithm: :concurrently
396
435
  <% else %>
397
436
  add_index <%= index[:table].to_sym.inspect %>, [<%= index[:columns].map(&:to_sym).map(&:inspect).join(", ") %>], algorithm: :concurrently<% end %>
398
437
  <% end %></pre>
@@ -449,10 +488,10 @@ pg_stat_statements.track = all</pre>
449
488
  </p>
450
489
 
451
490
  <div id="migration" style="display: none;">
452
- <pre>rails g migration remove_unused_indexes</pre>
491
+ <pre>rails generate migration remove_unused_indexes</pre>
453
492
  <p>And paste</p>
454
493
  <pre style="overflow: scroll; white-space: pre; word-break: normal;"><% @unused_indexes.each do |query| %>
455
- remove_index <%= query[:table].to_sym.inspect %>, name: <%= query[:index].to_s.inspect %><% end %></pre>
494
+ <%= pghero_remove_index(query)%><% end %></pre>
456
495
  </div>
457
496
 
458
497
  <table class="table">
@@ -7,5 +7,5 @@
7
7
 
8
8
  <p><%= button_to "Kill all connections", kill_all_path, class: "btn btn-danger" %></p>
9
9
 
10
- <p class="text-muted">You may need to restart your app server afterwards.</p>
10
+ <p class="text-muted">You may need to restart your app servers afterwards.</p>
11
11
  </div>
@@ -7,6 +7,9 @@
7
7
  <th>Table</th>
8
8
  <th style="width: 20%;">Last Vacuum</th>
9
9
  <th style="width: 20%;">Last Analyze</th>
10
+ <% if @show_dead_rows %>
11
+ <th style="width: 20%;">Dead Rows</th>
12
+ <% end %>
10
13
  </tr>
11
14
  </thead>
12
15
  <tbody>
@@ -21,7 +24,7 @@
21
24
  <td>
22
25
  <% time = [table[:last_autovacuum], table[:last_vacuum]].compact.max %>
23
26
  <% if time %>
24
- <%= time.in_time_zone(@time_zone).strftime("%-m/%-e %l:%M %P") %>
27
+ <%= l time.in_time_zone(@time_zone), format: :short %>
25
28
  <% else %>
26
29
  <span class="text-muted">Unknown</span>
27
30
  <% end %>
@@ -29,11 +32,22 @@
29
32
  <td>
30
33
  <% time = [table[:last_autoanalyze], table[:last_analyze]].compact.max %>
31
34
  <% if time %>
32
- <%= time.in_time_zone(@time_zone).strftime("%-m/%-e %l:%M %P") %>
35
+ <%= l time.in_time_zone(@time_zone), format: :short %>
33
36
  <% else %>
34
37
  <span class="text-muted">Unknown</span>
35
38
  <% end %>
36
39
  </td>
40
+ <% if @show_dead_rows %>
41
+ <td>
42
+ <% if table[:live_rows] != 0 %>
43
+ <%# use live rows only for denominator to make it easier to compare with autovacuum_vacuum_scale_factor %>
44
+ <%# it's not a true percentage, since it can go above 100% %>
45
+ <%= (100.0 * table[:dead_rows] / table[:live_rows]).round %>%
46
+ <% else %>
47
+ <span class="text-muted">Unknown</span>
48
+ <% end %>
49
+ </td>
50
+ <% end %>
37
51
  </tr>
38
52
  <% end %>
39
53
  </tbody>
@@ -6,9 +6,9 @@
6
6
  <% end %>
7
7
  </h1>
8
8
 
9
- <h1>Size <small>MB</small></h1>
9
+ <h1>Size</h1>
10
10
  <div id="chart-1" class="chart" style="margin-bottom: 20px;">Loading...</div>
11
11
  <script>
12
- new Chartkick.LineChart("chart-1", <%= json_escape(@chart_data.to_json).html_safe %>, {colors: ["#5bc0de"], legend: false, min: null})
12
+ new Chartkick.LineChart("chart-1", <%= json_escape(@chart_data.to_json).html_safe %>, {colors: ["#5bc0de"], legend: false, min: null, bytes: true, library: {tooltips: {intersect: false, mode: "index"}}})
13
13
  </script>
14
14
  </div>
@@ -6,8 +6,7 @@
6
6
 
7
7
  <% if @explainable_query %>
8
8
  <p>
9
- <% button_path, button_options = Rails.version >= "4.1" ? [explain_path, {params: {query: @explainable_query}}] : [explain_path(query: @explainable_query), {}] %>
10
- <%= button_to "Explain", button_path, button_options.merge(form: {target: "_blank"}, class: "btn btn-info") %>
9
+ <%= button_to "Explain", explain_path, params: {query: @explainable_query}, form: {target: "_blank"}, class: "btn btn-info" %>
11
10
  </p>
12
11
  <% end %>
13
12
 
@@ -50,19 +49,19 @@
50
49
  <h1>Total Time <small>ms</small></h1>
51
50
  <div id="chart-1" class="chart" style="margin-bottom: 20px;">Loading...</div>
52
51
  <script>
53
- new Chartkick.LineChart("chart-1", <%= json_escape(@chart_data.to_json).html_safe %>, {colors: ["#5bc0de"], legend: false})
52
+ new Chartkick.LineChart("chart-1", <%= json_escape(@chart_data.to_json).html_safe %>, {colors: ["#5bc0de"], legend: false, library: {tooltips: {intersect: false, mode: "index"}}})
54
53
  </script>
55
54
 
56
55
  <h1>Average Time <small>ms</small></h1>
57
56
  <div id="chart-2" class="chart" style="margin-bottom: 20px;">Loading...</div>
58
57
  <script>
59
- new Chartkick.LineChart("chart-2", <%= json_escape(@chart2_data.to_json).html_safe %>, {colors: ["#5bc0de"], legend: false})
58
+ new Chartkick.LineChart("chart-2", <%= json_escape(@chart2_data.to_json).html_safe %>, {colors: ["#5bc0de"], legend: false, library: {tooltips: {intersect: false, mode: "index"}}})
60
59
  </script>
61
60
 
62
61
  <h1>Calls</h1>
63
62
  <div id="chart-3" class="chart" style="margin-bottom: 20px;">Loading...</div>
64
63
  <script>
65
- new Chartkick.LineChart("chart-3", <%= json_escape(@chart3_data.to_json).html_safe %>, {colors: ["#5bc0de"], legend: false})
64
+ new Chartkick.LineChart("chart-3", <%= json_escape(@chart3_data.to_json).html_safe %>, {colors: ["#5bc0de"], legend: false, library: {tooltips: {intersect: false, mode: "index"}}})
66
65
  </script>
67
66
  <% else %>
68
67
  <p>
@@ -6,7 +6,7 @@
6
6
  <% if @system_stats_enabled %>
7
7
  <div id="chart-1" class="chart" style="margin-bottom: 20px;">Loading...</div>
8
8
  <script>
9
- new Chartkick.LineChart("chart-1", <%= json_escape(free_space_stats_path.to_json).html_safe %>, {colors: ["#5bc0de"]})
9
+ new Chartkick.LineChart("chart-1", <%= json_escape(free_space_stats_path.to_json).html_safe %>, {colors: ["#5bc0de"], bytes: true, library: {tooltips: {intersect: false, mode: "index"}}})
10
10
  </script>
11
11
  <% end %>
12
12
 
@@ -30,10 +30,10 @@
30
30
  </p>
31
31
 
32
32
  <div id="migration" style="display: none;">
33
- <pre>rails g migration remove_unused_indexes</pre>
33
+ <pre>rails generate migration remove_unused_indexes</pre>
34
34
  <p>And paste</p>
35
35
  <pre style="overflow: scroll; white-space: pre; word-break: normal;"><% @unused_indexes.sort_by { |q| [-q[:size_bytes], q[:index]] }.each do |query| %>
36
- remove_index <%= query[:table].to_sym.inspect %>, name: <%= query[:index].to_s.inspect %><% end %></pre>
36
+ <%= pghero_remove_index(query) %><% end %></pre>
37
37
  </div>
38
38
  <% end %>
39
39
 
@@ -9,26 +9,26 @@
9
9
  <h1>CPU</h1>
10
10
  <div id="chart-1" class="chart" style="margin-bottom: 20px;">Loading...</div>
11
11
  <script>
12
- new Chartkick.LineChart("chart-1", <%= json_escape(cpu_usage_path(path_options).to_json).html_safe %>, {max: 100, colors: ["#5bc0de"]})
12
+ new Chartkick.LineChart("chart-1", <%= json_escape(cpu_usage_path(path_options).to_json).html_safe %>, {max: 100, colors: ["#5bc0de"], suffix: "%", library: {tooltips: {intersect: false, mode: "index"}}})
13
13
  </script>
14
14
 
15
15
  <h1>Load</h1>
16
16
  <div id="chart-2" class="chart" style="margin-bottom: 20px;">Loading...</div>
17
17
  <script>
18
- new Chartkick.LineChart("chart-2", <%= json_escape(load_stats_path(path_options).to_json).html_safe %>, {colors: ["#5bc0de", "#d9534f"]})
18
+ new Chartkick.LineChart("chart-2", <%= json_escape(load_stats_path(path_options).to_json).html_safe %>, {colors: ["#5bc0de", "#d9534f"], library: {tooltips: {intersect: false, mode: "nearest"}}})
19
19
  </script>
20
20
 
21
21
  <h1>Connections</h1>
22
22
  <div id="chart-3" class="chart" style="margin-bottom: 20px;">Loading...</div>
23
23
  <script>
24
- new Chartkick.LineChart("chart-3", <%= json_escape(connection_stats_path(path_options).to_json).html_safe %>, {colors: ["#5bc0de"]})
24
+ new Chartkick.LineChart("chart-3", <%= json_escape(connection_stats_path(path_options).to_json).html_safe %>, {colors: ["#5bc0de"], library: {tooltips: {intersect: false, mode: "index"}}})
25
25
  </script>
26
26
 
27
27
  <% if @database.replica? %>
28
28
  <h1>Replication Lag</h1>
29
29
  <div id="chart-4" class="chart" style="margin-bottom: 20px;">Loading...</div>
30
30
  <script>
31
- new Chartkick.LineChart("chart-4", <%= json_escape(replication_lag_stats_path(path_options).to_json).html_safe %>, {colors: ["#5bc0de"]})
31
+ new Chartkick.LineChart("chart-4", <%= json_escape(replication_lag_stats_path(path_options).to_json).html_safe %>, {colors: ["#5bc0de"], library: {tooltips: {intersect: false, mode: "index"}}})
32
32
  </script>
33
33
  <% end %>
34
34
  </div>
@@ -18,7 +18,8 @@
18
18
  </tbody>
19
19
  </table>
20
20
 
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>
21
+ <% version_parts = @database.server_version.split(" ").first.split(".") %>
22
+ <p>Check out <%= link_to "PgTune", "https://pgtune.leopard.in.ua/", target: "_blank" %> for recommendations. DB version is <%= version_parts[0].to_i >= 10 ? version_parts[0] : version_parts.first(2).join(".") %>.</p>
22
23
  </div>
23
24
 
24
25
  <% if @autovacuum_settings %>
@@ -3,7 +3,7 @@ require "rails/generators"
3
3
  module Pghero
4
4
  module Generators
5
5
  class ConfigGenerator < Rails::Generators::Base
6
- source_root File.expand_path("../templates", __FILE__)
6
+ source_root File.join(__dir__, "templates")
7
7
 
8
8
  def create_initializer
9
9
  template "config.yml", "config/pghero.yml"
@@ -1,34 +1,17 @@
1
- # taken from https://github.com/collectiveidea/audited/blob/master/lib/generators/audited/install_generator.rb
2
- require "rails/generators"
3
- require "rails/generators/migration"
4
- require "active_record"
5
1
  require "rails/generators/active_record"
6
2
 
7
3
  module Pghero
8
4
  module Generators
9
5
  class QueryStatsGenerator < Rails::Generators::Base
10
- include Rails::Generators::Migration
11
-
12
- source_root File.expand_path("../templates", __FILE__)
13
-
14
- # Implement the required interface for Rails::Generators::Migration.
15
- def self.next_migration_number(dirname) #:nodoc:
16
- next_migration_number = current_migration_number(dirname) + 1
17
- if ::ActiveRecord::Base.timestamped_migrations
18
- [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
19
- else
20
- "%.3d" % next_migration_number
21
- end
22
- end
6
+ include ActiveRecord::Generators::Migration
7
+ source_root File.join(__dir__, "templates")
23
8
 
24
9
  def copy_migration
25
10
  migration_template "query_stats.rb", "db/migrate/create_pghero_query_stats.rb", migration_version: migration_version
26
11
  end
27
12
 
28
13
  def migration_version
29
- if ActiveRecord::VERSION::MAJOR >= 5
30
- "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
31
- end
14
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
32
15
  end
33
16
  end
34
17
  end
@@ -1,34 +1,17 @@
1
- # taken from https://github.com/collectiveidea/audited/blob/master/lib/generators/audited/install_generator.rb
2
- require "rails/generators"
3
- require "rails/generators/migration"
4
- require "active_record"
5
1
  require "rails/generators/active_record"
6
2
 
7
3
  module Pghero
8
4
  module Generators
9
5
  class SpaceStatsGenerator < Rails::Generators::Base
10
- include Rails::Generators::Migration
11
-
12
- source_root File.expand_path("../templates", __FILE__)
13
-
14
- # Implement the required interface for Rails::Generators::Migration.
15
- def self.next_migration_number(dirname) #:nodoc:
16
- next_migration_number = current_migration_number(dirname) + 1
17
- if ::ActiveRecord::Base.timestamped_migrations
18
- [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
19
- else
20
- "%.3d" % next_migration_number
21
- end
22
- end
6
+ include ActiveRecord::Generators::Migration
7
+ source_root File.join(__dir__, "templates")
23
8
 
24
9
  def copy_migration
25
10
  migration_template "space_stats.rb", "db/migrate/create_pghero_space_stats.rb", migration_version: migration_version
26
11
  end
27
12
 
28
13
  def migration_version
29
- if ActiveRecord::VERSION::MAJOR >= 5
30
- "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
31
- end
14
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
32
15
  end
33
16
  end
34
17
  end
@@ -1,8 +1,13 @@
1
1
  databases:
2
- main:
2
+ primary:
3
3
  # Database URL (defaults to app database)
4
4
  # url: <%%= ENV["DATABASE_URL"] %>
5
5
 
6
+ # System stats
7
+ # aws_db_instance_identifier: my-instance
8
+ # gcp_database_id: my-project:my-instance
9
+ # azure_resource_id: my-resource-id
10
+
6
11
  # Add more databases
7
12
  # other:
8
13
  # url: <%%= ENV["OTHER_DATABASE_URL"] %>
@@ -24,3 +29,18 @@ databases:
24
29
 
25
30
  # Time zone (defaults to app time zone)
26
31
  # time_zone: "Pacific Time (US & Canada)"
32
+
33
+ # Basic authentication
34
+ # username: admin
35
+ # password: <%%= ENV["PGHERO_PASSWORD"] %>
36
+
37
+ # Stats database URL (defaults to app database)
38
+ # stats_database_url: <%%= ENV["PGHERO_STATS_DATABASE_URL"] %>
39
+
40
+ # AWS configuration (defaults to app AWS config)
41
+ # aws_access_key_id: <%%= ENV["AWS_ACCESS_KEY_ID"] %>
42
+ # aws_secret_access_key: <%%= ENV["AWS_SECRET_ACCESS_KEY"] %>
43
+ # aws_region: us-east-1
44
+
45
+ # Filter data from queries (experimental)
46
+ # filter_data: true