pgbouncerhero 1.0.1 → 2.0.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/.gitignore +1 -0
- data/CHANGELOG.md +5 -1
- data/README.md +1 -20
- data/app/assets/javascripts/pgbouncerhero/application.js +1 -0
- data/app/views/layouts/pg_bouncer_hero/application.html.erb +32 -0
- data/app/views/pg_bouncer_hero/database/_actions.html.erb +10 -0
- data/app/views/pg_bouncer_hero/database/_clients.html.erb +27 -0
- data/app/views/pg_bouncer_hero/database/_conf.html.erb +27 -0
- data/app/views/pg_bouncer_hero/database/_databases.html.erb +27 -0
- data/app/views/pg_bouncer_hero/database/_menu.html.erb +21 -0
- data/app/views/pg_bouncer_hero/database/_pools.html.erb +27 -0
- data/app/views/pg_bouncer_hero/database/_stats.html.erb +37 -0
- data/app/views/pg_bouncer_hero/database/clients.html.erb +4 -0
- data/app/views/pg_bouncer_hero/database/conf.html.erb +4 -0
- data/app/views/pg_bouncer_hero/database/databases.html.erb +4 -0
- data/app/views/pg_bouncer_hero/database/pools.html.erb +4 -0
- data/app/views/pg_bouncer_hero/database/stats.html.erb +4 -0
- data/app/views/pg_bouncer_hero/database/summary.js.erb +5 -0
- data/app/views/pg_bouncer_hero/home/_card.html.erb +26 -0
- data/app/views/pg_bouncer_hero/home/_card_content.html.erb +43 -0
- data/app/views/pg_bouncer_hero/home/_card_loading_content.html.erb +7 -0
- data/app/views/pg_bouncer_hero/home/{index.html.haml → index.html.erb} +20 -10
- data/app/views/shared/_alert.html.erb +6 -0
- data/app/views/shared/_flash_messages.html.erb +3 -0
- data/lib/pgbouncerhero/version.rb +1 -1
- data/lib/pgbouncerhero.rb +4 -0
- data/pgbouncerhero.gemspec +1 -1
- metadata +25 -26
- data/app/views/layouts/pg_bouncer_hero/application.html.haml +0 -20
- data/app/views/pg_bouncer_hero/database/_actions.html.haml +0 -10
- data/app/views/pg_bouncer_hero/database/_clients.html.haml +0 -15
- data/app/views/pg_bouncer_hero/database/_conf.html.haml +0 -15
- data/app/views/pg_bouncer_hero/database/_databases.html.haml +0 -15
- data/app/views/pg_bouncer_hero/database/_menu.html.haml +0 -15
- data/app/views/pg_bouncer_hero/database/_pools.html.haml +0 -15
- data/app/views/pg_bouncer_hero/database/_stats.html.haml +0 -20
- data/app/views/pg_bouncer_hero/database/clients.html.haml +0 -4
- data/app/views/pg_bouncer_hero/database/conf.html.haml +0 -4
- data/app/views/pg_bouncer_hero/database/databases.html.haml +0 -5
- data/app/views/pg_bouncer_hero/database/pools.html.haml +0 -4
- data/app/views/pg_bouncer_hero/database/stats.html.haml +0 -4
- data/app/views/pg_bouncer_hero/database/summary.js.haml +0 -5
- data/app/views/pg_bouncer_hero/home/_card.html.haml +0 -13
- data/app/views/pg_bouncer_hero/home/_card_content.html.haml +0 -28
- data/app/views/pg_bouncer_hero/home/_card_loading_content.html.haml +0 -5
- data/app/views/shared/_alert.html.haml +0 -4
- data/app/views/shared/_flash_messages.html.haml +0 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0beaacfe8514247e5d6aa9a5a2cee2432f830a265911faaab2998fd406c23aab
|
|
4
|
+
data.tar.gz: cf85e4ce7b62d81ab756be4031fc1aa268f9823329fd108f372c0f930c6fb068
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '09add1cb73ceb2c23e35f7261eeece28bb87d503087cb7d61d26937f78e0843b7df1205542512b1bef76d8a0244e3ca8f5b5ce0b55259e327ef36f8a7fcc0c2b'
|
|
7
|
+
data.tar.gz: 3f7caf907cfc1334b6f319c5d85104a71c41f70780fbac948f1bd790ee4c01bf99a774c56dc90652d223f2ba8c3adbb0241cbf3b95c084ed0d58e660212c81dc
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -16,11 +16,6 @@ Add those dependencies to your application’s Gemfile:
|
|
|
16
16
|
|
|
17
17
|
```ruby
|
|
18
18
|
gem 'pgbouncerhero'
|
|
19
|
-
gem 'jquery-rails'
|
|
20
|
-
gem 'sass-rails'
|
|
21
|
-
gem 'semantic-ui-sass'
|
|
22
|
-
gem 'haml-rails'
|
|
23
|
-
gem 'pg'
|
|
24
19
|
```
|
|
25
20
|
|
|
26
21
|
And mount the engine in your `config/routes.rb`:
|
|
@@ -29,20 +24,6 @@ And mount the engine in your `config/routes.rb`:
|
|
|
29
24
|
mount PgBouncerHero::Engine, at: "pgbouncerhero"
|
|
30
25
|
```
|
|
31
26
|
|
|
32
|
-
Add the following line in your `application.css`:
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
*= require pgbouncerhero/application
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Add the following lines in your `application.js`:
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
//= require jquery
|
|
42
|
-
//= require jquery_ujs
|
|
43
|
-
//= require pgbouncerhero/application
|
|
44
|
-
```
|
|
45
|
-
|
|
46
27
|
### Basic Authentication
|
|
47
28
|
|
|
48
29
|
Set the following variables in your environment or an initializer.
|
|
@@ -98,7 +79,7 @@ production:
|
|
|
98
79
|
# License
|
|
99
80
|
|
|
100
81
|
```plain
|
|
101
|
-
Copyright (c)
|
|
82
|
+
Copyright (c) 2022 Quentin Rousseau <contact@quent.in>
|
|
102
83
|
|
|
103
84
|
MIT License
|
|
104
85
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8"/>
|
|
5
|
+
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>
|
|
6
|
+
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0" name="viewport"/>
|
|
7
|
+
<title>
|
|
8
|
+
<%= [@groups.size > 1 ? "#{@database.group.name} | #{@database.name}" : "PgBouncerHero", @title].compact.join(" / ") %>
|
|
9
|
+
</title>
|
|
10
|
+
<%= stylesheet_link_tag 'pgbouncerhero/application', media: 'all', 'data-turbolinks-track': true %>
|
|
11
|
+
<%= javascript_include_tag "pgbouncerhero/application" %>
|
|
12
|
+
<%= csrf_meta_tags %>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<div class="ui fixed menu">
|
|
16
|
+
<div class="ui container">
|
|
17
|
+
<%= link_to'PGBouncerHero', root_path, class: 'header item' %>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="pusher">
|
|
21
|
+
<div class="ui main container">
|
|
22
|
+
<div class="row" id="flash">
|
|
23
|
+
<%= render partial: 'shared/flash_messages', flash: flash %>
|
|
24
|
+
</div>
|
|
25
|
+
<%= yield %>
|
|
26
|
+
</div>
|
|
27
|
+
<% if content_for? :inline_script %>
|
|
28
|
+
<%= yield :inline_script %>
|
|
29
|
+
<% end %>
|
|
30
|
+
</div>
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<div class="ui active segment">
|
|
2
|
+
<h4 class="ui header">
|
|
3
|
+
<div class="content">Actions</div>
|
|
4
|
+
</h4>
|
|
5
|
+
<button class="ui negative basic button">Pause</button>
|
|
6
|
+
<button class="ui positive basic button">Resume</button>
|
|
7
|
+
<button class="ui negative basic button">Disable</button>
|
|
8
|
+
<button class="ui positive basic button">Enable</button>
|
|
9
|
+
<button class="ui negative basic button">Kill</button>
|
|
10
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div class="ui active segment">
|
|
2
|
+
<h4 class="ui header">
|
|
3
|
+
<div class="content">Clients</div>
|
|
4
|
+
</h4>
|
|
5
|
+
<table class="ui compact table">
|
|
6
|
+
<thead>
|
|
7
|
+
<tr>
|
|
8
|
+
<% clients.first.keys.each do |key| %>
|
|
9
|
+
<th>
|
|
10
|
+
<%= key.titleize %>
|
|
11
|
+
</th>
|
|
12
|
+
<% end %>
|
|
13
|
+
</tr>
|
|
14
|
+
</thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
<% clients.each do |row| %>
|
|
17
|
+
<tr>
|
|
18
|
+
<% row.each do |k,v| %>
|
|
19
|
+
<td>
|
|
20
|
+
<%= v %>
|
|
21
|
+
</td>
|
|
22
|
+
<% end %>
|
|
23
|
+
</tr>
|
|
24
|
+
<% end %>
|
|
25
|
+
</tbody>
|
|
26
|
+
</table>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div class="ui active segment">
|
|
2
|
+
<h4 class="ui header">
|
|
3
|
+
<div class="content">Confs</div>
|
|
4
|
+
</h4>
|
|
5
|
+
<table class="ui compact table">
|
|
6
|
+
<thead>
|
|
7
|
+
<tr>
|
|
8
|
+
<% conf.first.keys.each do |key| %>
|
|
9
|
+
<th>
|
|
10
|
+
<%= key.titleize %>
|
|
11
|
+
</th>
|
|
12
|
+
<% end %>
|
|
13
|
+
</tr>
|
|
14
|
+
</thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
<% conf.each do |row| %>
|
|
17
|
+
<tr>
|
|
18
|
+
<% row.each do |k,v| %>
|
|
19
|
+
<td>
|
|
20
|
+
<%= v %>
|
|
21
|
+
</td>
|
|
22
|
+
<% end %>
|
|
23
|
+
</tr>
|
|
24
|
+
<% end %>
|
|
25
|
+
</tbody>
|
|
26
|
+
</table>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div class="ui active segment">
|
|
2
|
+
<h4 class="ui header">
|
|
3
|
+
<div class="content">Databases</div>
|
|
4
|
+
</h4>
|
|
5
|
+
<table class="ui compact table">
|
|
6
|
+
<thead>
|
|
7
|
+
<tr>
|
|
8
|
+
<% databases.first.keys.each do |key| %>
|
|
9
|
+
<th>
|
|
10
|
+
<%= key.titleize %>
|
|
11
|
+
</th>
|
|
12
|
+
<% end %>
|
|
13
|
+
</tr>
|
|
14
|
+
</thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
<% databases.each do |row| %>
|
|
17
|
+
<tr>
|
|
18
|
+
<% row.each do |k,v| %>
|
|
19
|
+
<td>
|
|
20
|
+
<%= v %>
|
|
21
|
+
</td>
|
|
22
|
+
<% end %>
|
|
23
|
+
</tr>
|
|
24
|
+
<% end %>
|
|
25
|
+
</tbody>
|
|
26
|
+
</table>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<div class="ui pointing menu">
|
|
2
|
+
<div class="header item">
|
|
3
|
+
<%= "#{database.group.name} > #{database.name}" %>
|
|
4
|
+
</div>
|
|
5
|
+
<%= link_to "Databases", databases_path(database: database.name.parameterize), class: "item #{is_active('databases')}" %>
|
|
6
|
+
<%= link_to "Stats", stats_path(database: database.name.parameterize), class: "item #{is_active('stats')}" %>
|
|
7
|
+
<%= link_to "Pools", pools_path(database: database.name.parameterize), class: "item #{is_active('pools')}" %>
|
|
8
|
+
<%= link_to "Clients", clients_path(database: database.name.parameterize), class: "item #{is_active('clients')}" %>
|
|
9
|
+
<%= link_to "Configuration", conf_path(database: database.name.parameterize), class: "item #{is_active('conf')}" %>
|
|
10
|
+
<div class="right menu">
|
|
11
|
+
<div class="item">
|
|
12
|
+
<%= link_to 'Reload', reload_path(database: database.name.parameterize), remote: :true, method: :post, class: 'ui button basic positive button', data: { confirm: 'Are you sure?' } %>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="item">
|
|
15
|
+
<%= link_to 'Suspend', suspend_path(database: database.name.parameterize), remote: :true, method: :post, class: 'ui button basic primary button', data: { confirm: 'Are you sure?' } %>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="item">
|
|
18
|
+
<%= link_to 'Shutdown', shutdown_path(database: database.name.parameterize), remote: :true, method: :post, class: 'ui button basic negative button', data: { confirm: 'Are you sure?' } %>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div class="ui active segment">
|
|
2
|
+
<h4 class="ui header">
|
|
3
|
+
<div class="content">Pools</div>
|
|
4
|
+
</h4>
|
|
5
|
+
<table class="ui compact table">
|
|
6
|
+
<thead>
|
|
7
|
+
<tr>
|
|
8
|
+
<% pools.first.keys.each do |key| %>
|
|
9
|
+
<th>
|
|
10
|
+
<%= key.titleize %>
|
|
11
|
+
</th>
|
|
12
|
+
<% end %>
|
|
13
|
+
</tr>
|
|
14
|
+
</thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
<% pools.each do |row| %>
|
|
17
|
+
<tr>
|
|
18
|
+
<% row.each do |k,v| %>
|
|
19
|
+
<td>
|
|
20
|
+
<%= v %>
|
|
21
|
+
</td>
|
|
22
|
+
<% end %>
|
|
23
|
+
</tr>
|
|
24
|
+
<% end %>
|
|
25
|
+
</tbody>
|
|
26
|
+
</table>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<div class="ui active segment">
|
|
2
|
+
<h4 class="ui header">
|
|
3
|
+
<div class="content">Stats</div>
|
|
4
|
+
</h4>
|
|
5
|
+
<table class="ui compact table">
|
|
6
|
+
<thead>
|
|
7
|
+
<tr>
|
|
8
|
+
<% stats.first.keys.each do |key| %>
|
|
9
|
+
<th>
|
|
10
|
+
<%= key.titleize %>
|
|
11
|
+
</th>
|
|
12
|
+
<% end %>
|
|
13
|
+
</tr>
|
|
14
|
+
</thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
<% stats.each do |row| %>
|
|
17
|
+
<tr>
|
|
18
|
+
<% row.each do |k,v| %>
|
|
19
|
+
<% if ['total_received', 'total_sent', 'avg_recv', 'avg_sent'].include? k %>
|
|
20
|
+
<td>
|
|
21
|
+
<%= number_to_human_size(v) %>
|
|
22
|
+
</td>
|
|
23
|
+
<% elsif ['total_query_time', 'avg_query'].include? k %>
|
|
24
|
+
<td>
|
|
25
|
+
<%= humanize_ms(v.to_i) %>
|
|
26
|
+
</td>
|
|
27
|
+
<% else %>
|
|
28
|
+
<td>
|
|
29
|
+
<%= v %>
|
|
30
|
+
</td>
|
|
31
|
+
<% end %>
|
|
32
|
+
<% end %>
|
|
33
|
+
</tr>
|
|
34
|
+
<% end %>
|
|
35
|
+
</tbody>
|
|
36
|
+
</table>
|
|
37
|
+
</div>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
$("#segment_status_<%= @database.group.name.parameterize %>_<%= @database.name.parameterize %>").html("<%= j(@database.connection ? "Online" : "Offline") %>")
|
|
2
|
+
$("#segment_status_<%= @database.group.name.parameterize %>_<%= @database.name.parameterize %>").removeClass("grey negative positive").addClass("<%= j(@database.connection ? "positive" : "negative") %>")
|
|
3
|
+
$("#segment_content_<%= @database.group.name.parameterize %>_<%= @database.name.parameterize %>").replaceWith("<%= j(render partial: 'pg_bouncer_hero/home/card_content', locals: {database: @database, id: "segment_content_#{@database.group.name.parameterize}_#{@database.name.parameterize}"}) %>")
|
|
4
|
+
$("#segment_refreshed_<%= @database.group.name.parameterize %>_<%= @database.name.parameterize %>").css('display', '')
|
|
5
|
+
$("#segment_content_<%= @database.group.name.parameterize %>_<%= @database.name.parameterize %> .ui.progress").each(function(idx, el) { $(el).progress({ text: {active: '{value} of {total} connections'}, autoSuccess: false }); });
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<div class="eight wide column" id="segment_href_<%= database.group.name.parameterize %>_<%= database.name.parameterize %>" data-href="<%= summary_path(group: database.group.name.parameterize, database: database.name.parameterize) %>">
|
|
2
|
+
<%= link_to databases_path(group: database.group.name.parameterize, database: database.name.parameterize), style: 'text-decoration: none !important; color: inherit !important' do %>
|
|
3
|
+
<div class="ui segments" style="margin-bottom: 10px;">
|
|
4
|
+
<div class="ui segment" style="height: 60px;">
|
|
5
|
+
<div style="float: left;">
|
|
6
|
+
<div style="font-size: 16px; font-weight: bold;">
|
|
7
|
+
<%= database.name %>
|
|
8
|
+
</div>
|
|
9
|
+
<div style="font-size: 12px; color: grey">
|
|
10
|
+
<%= database.host %>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
<button class="grey ui button basic button" id="segment_status_<%= database.group.name.parameterize %>_<%= database.name.parameterize %>" style="float: right;">
|
|
14
|
+
<%= 'N/A' %>
|
|
15
|
+
</button>
|
|
16
|
+
</div>
|
|
17
|
+
<%= render partial: partial, locals: {database: database, id: "segment_content_#{database.group.name.parameterize}_#{database.name.parameterize}"} %>
|
|
18
|
+
<div class="ui segment" id="segment_refreshed_<%= database.group.name.parameterize %>_<%= database.name.parameterize %>" style="height: 35px; display: none;">
|
|
19
|
+
<span class="right floated" id="segment_refreshed_span_<%= database.group.name.parameterize %>_<%= database.name.parameterize %>" style="float:right; margin-top: -6px; color: grey">
|
|
20
|
+
Last refresh:
|
|
21
|
+
<%= Time.now.strftime("%H:%M:%S GMT%z (%Z)") %>
|
|
22
|
+
</span>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<% end %>
|
|
26
|
+
</div>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<% connected = database.connection %>
|
|
2
|
+
<% if connected %>
|
|
3
|
+
<div class="ui horizontal segments" id="<%= id %>" style="background-color: white !important;">
|
|
4
|
+
<div class="ui segment">
|
|
5
|
+
<% summary = database.summary %>
|
|
6
|
+
<div>
|
|
7
|
+
<i class="users icon"></i>
|
|
8
|
+
<% number = summary.select { |row| row['list'] == 'users' }.first['items'] %>
|
|
9
|
+
<%= pluralize(number, 'user') %>
|
|
10
|
+
</div>
|
|
11
|
+
<div>
|
|
12
|
+
<i class="database icon"></i>
|
|
13
|
+
<% number = summary.select { |row| row['list'] == 'databases' }.first['items'].to_i - 1 %>
|
|
14
|
+
<%= pluralize(number, 'database') %>
|
|
15
|
+
</div>
|
|
16
|
+
<div>
|
|
17
|
+
<i class="plug icon"></i>
|
|
18
|
+
<% number = summary.select { |row| row['list'] == 'pools' }.first['items'].to_i - 1 %>
|
|
19
|
+
<%= pluralize(number, 'pool') %>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="ui segment">
|
|
23
|
+
<ul style="margin: 0; padding-left: 5px;">
|
|
24
|
+
<% summary.select{ |row| row.key?(:databases_details) }.first[:databases_details].each do |db| %>
|
|
25
|
+
<li style="margin: 0; list-style-type: none;">
|
|
26
|
+
<span>
|
|
27
|
+
<i class="database icon"></i>
|
|
28
|
+
<strong>
|
|
29
|
+
<%= db['name'] %>
|
|
30
|
+
</strong>
|
|
31
|
+
<div class="ui progress small success" style="float:right; width: 150px; margin-top:4px;" data-value="<%= db['current_connections'] %>" data-total="<%= db['max_connections'] %>">
|
|
32
|
+
<div class="bar">
|
|
33
|
+
<div class="progress"></div>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="label">Connections</div>
|
|
36
|
+
</div>
|
|
37
|
+
</span>
|
|
38
|
+
</li>
|
|
39
|
+
<% end %>
|
|
40
|
+
</ul>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<div class="ui segment" id="<%= id %>">
|
|
2
|
+
<div class="ui active inverted dimmer">
|
|
3
|
+
<div class="ui medium text loader">Loading...</div>
|
|
4
|
+
</div>
|
|
5
|
+
<%= image_tag('pgbouncerhero/short-paragraph.png', class: 'ui wireframe image') %>
|
|
6
|
+
<%= image_tag('pgbouncerhero/short-paragraph.png', class: 'ui wireframe image') %>
|
|
7
|
+
</div>
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
<div class="ui pointing menu">
|
|
2
|
+
<div class="header item">
|
|
3
3
|
Overview
|
|
4
|
+
</div>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="ui grid">
|
|
7
|
+
<% @groups.each do |_, group| %>
|
|
8
|
+
<div class="sixteen wide row">
|
|
9
|
+
<div class="sixteen wide column">
|
|
10
|
+
<h3 class="ui dividing header" style="margin-bottom: 10px;">
|
|
11
|
+
<%= group.name %>
|
|
12
|
+
</h3>
|
|
13
|
+
</div>
|
|
14
|
+
<%= render partial: "card", collection: group.databases, as: :database, locals: {partial: 'card_loading_content', lazy: true} %>
|
|
15
|
+
</div>
|
|
16
|
+
<% end %>
|
|
17
|
+
</div>
|
|
18
|
+
<script>
|
|
4
19
|
|
|
5
|
-
.ui.grid
|
|
6
|
-
- @groups.each do |_, group|
|
|
7
|
-
.sixteen.wide.row
|
|
8
|
-
.sixteen.wide.column
|
|
9
|
-
%h3.ui.dividing.header{style: 'margin-bottom: 10px;'}= group.name
|
|
10
|
-
= render partial: "card", collection: group.databases, as: :database, locals: {partial: 'card_loading_content', lazy: true}
|
|
11
|
-
|
|
12
|
-
:javascript
|
|
13
20
|
document.addEventListener("DOMContentLoaded", function(event) {
|
|
14
21
|
// First
|
|
15
22
|
$("[id^='segment_href']").each(function(idx, el) {
|
|
@@ -32,3 +39,6 @@
|
|
|
32
39
|
});
|
|
33
40
|
}, 60 * 1000)
|
|
34
41
|
});
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
</script>
|
data/lib/pgbouncerhero.rb
CHANGED
data/pgbouncerhero.gemspec
CHANGED
|
@@ -21,8 +21,8 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.add_development_dependency "rake"
|
|
22
22
|
spec.add_development_dependency "minitest"
|
|
23
23
|
spec.add_runtime_dependency "sass-rails"
|
|
24
|
+
spec.add_runtime_dependency "jquery-rails"
|
|
24
25
|
spec.add_runtime_dependency "semantic-ui-sass"
|
|
25
|
-
spec.add_runtime_dependency "haml-rails"
|
|
26
26
|
|
|
27
27
|
if RUBY_PLATFORM == "java"
|
|
28
28
|
spec.add_runtime_dependency "pg_jruby"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pgbouncerhero
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Quentin Rousseau
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-02-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -67,7 +67,7 @@ dependencies:
|
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
70
|
+
name: jquery-rails
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - ">="
|
|
@@ -81,7 +81,7 @@ dependencies:
|
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: semantic-ui-sass
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - ">="
|
|
@@ -127,26 +127,26 @@ files:
|
|
|
127
127
|
- app/controllers/pg_bouncer_hero/database_controller.rb
|
|
128
128
|
- app/controllers/pg_bouncer_hero/home_controller.rb
|
|
129
129
|
- app/helpers/pg_bouncer_hero/application_helper.rb
|
|
130
|
-
- app/views/layouts/pg_bouncer_hero/application.html.
|
|
131
|
-
- app/views/pg_bouncer_hero/database/_actions.html.
|
|
132
|
-
- app/views/pg_bouncer_hero/database/_clients.html.
|
|
133
|
-
- app/views/pg_bouncer_hero/database/_conf.html.
|
|
134
|
-
- app/views/pg_bouncer_hero/database/_databases.html.
|
|
135
|
-
- app/views/pg_bouncer_hero/database/_menu.html.
|
|
136
|
-
- app/views/pg_bouncer_hero/database/_pools.html.
|
|
137
|
-
- app/views/pg_bouncer_hero/database/_stats.html.
|
|
138
|
-
- app/views/pg_bouncer_hero/database/clients.html.
|
|
139
|
-
- app/views/pg_bouncer_hero/database/conf.html.
|
|
140
|
-
- app/views/pg_bouncer_hero/database/databases.html.
|
|
141
|
-
- app/views/pg_bouncer_hero/database/pools.html.
|
|
142
|
-
- app/views/pg_bouncer_hero/database/stats.html.
|
|
143
|
-
- app/views/pg_bouncer_hero/database/summary.js.
|
|
144
|
-
- app/views/pg_bouncer_hero/home/_card.html.
|
|
145
|
-
- app/views/pg_bouncer_hero/home/_card_content.html.
|
|
146
|
-
- app/views/pg_bouncer_hero/home/_card_loading_content.html.
|
|
147
|
-
- app/views/pg_bouncer_hero/home/index.html.
|
|
148
|
-
- app/views/shared/_alert.html.
|
|
149
|
-
- app/views/shared/_flash_messages.html.
|
|
130
|
+
- app/views/layouts/pg_bouncer_hero/application.html.erb
|
|
131
|
+
- app/views/pg_bouncer_hero/database/_actions.html.erb
|
|
132
|
+
- app/views/pg_bouncer_hero/database/_clients.html.erb
|
|
133
|
+
- app/views/pg_bouncer_hero/database/_conf.html.erb
|
|
134
|
+
- app/views/pg_bouncer_hero/database/_databases.html.erb
|
|
135
|
+
- app/views/pg_bouncer_hero/database/_menu.html.erb
|
|
136
|
+
- app/views/pg_bouncer_hero/database/_pools.html.erb
|
|
137
|
+
- app/views/pg_bouncer_hero/database/_stats.html.erb
|
|
138
|
+
- app/views/pg_bouncer_hero/database/clients.html.erb
|
|
139
|
+
- app/views/pg_bouncer_hero/database/conf.html.erb
|
|
140
|
+
- app/views/pg_bouncer_hero/database/databases.html.erb
|
|
141
|
+
- app/views/pg_bouncer_hero/database/pools.html.erb
|
|
142
|
+
- app/views/pg_bouncer_hero/database/stats.html.erb
|
|
143
|
+
- app/views/pg_bouncer_hero/database/summary.js.erb
|
|
144
|
+
- app/views/pg_bouncer_hero/home/_card.html.erb
|
|
145
|
+
- app/views/pg_bouncer_hero/home/_card_content.html.erb
|
|
146
|
+
- app/views/pg_bouncer_hero/home/_card_loading_content.html.erb
|
|
147
|
+
- app/views/pg_bouncer_hero/home/index.html.erb
|
|
148
|
+
- app/views/shared/_alert.html.erb
|
|
149
|
+
- app/views/shared/_flash_messages.html.erb
|
|
150
150
|
- config/routes.rb
|
|
151
151
|
- doc/screenshot-1.png
|
|
152
152
|
- doc/screenshot-2.png
|
|
@@ -180,8 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
180
180
|
- !ruby/object:Gem::Version
|
|
181
181
|
version: '0'
|
|
182
182
|
requirements: []
|
|
183
|
-
|
|
184
|
-
rubygems_version: 2.7.6
|
|
183
|
+
rubygems_version: 3.0.3.1
|
|
185
184
|
signing_key:
|
|
186
185
|
specification_version: 4
|
|
187
186
|
summary: A graphical user interface for your PGBouncers
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
!!!
|
|
2
|
-
%html
|
|
3
|
-
%head
|
|
4
|
-
%meta{charset: "utf-8"}
|
|
5
|
-
%meta{content: "IE=edge,chrome=1", "http-equiv" => "X-UA-Compatible"}
|
|
6
|
-
%meta{content: "width=device-width, initial-scale=1.0, maximum-scale=1.0", name: "viewport"}
|
|
7
|
-
%title= [@groups.size > 1 ? "#{@database.group.name} | #{@database.name}" : "PgBouncerHero", @title].compact.join(" / ")
|
|
8
|
-
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': true
|
|
9
|
-
= csrf_meta_tags
|
|
10
|
-
%body
|
|
11
|
-
.ui.fixed.menu
|
|
12
|
-
.ui.container
|
|
13
|
-
= link_to'PGBouncerHero', root_path, class: 'header item'
|
|
14
|
-
.pusher
|
|
15
|
-
.ui.main.container
|
|
16
|
-
#flash.row= render partial: 'shared/flash_messages', flash: flash
|
|
17
|
-
= yield
|
|
18
|
-
= javascript_include_tag 'application'
|
|
19
|
-
- if content_for? :inline_script
|
|
20
|
-
= yield :inline_script
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
.ui.active.segment
|
|
2
|
-
|
|
3
|
-
%h4.ui.header
|
|
4
|
-
.content Actions
|
|
5
|
-
|
|
6
|
-
%button.ui.negative.basic.button Pause
|
|
7
|
-
%button.ui.positive.basic.button Resume
|
|
8
|
-
%button.ui.negative.basic.button Disable
|
|
9
|
-
%button.ui.positive.basic.button Enable
|
|
10
|
-
%button.ui.negative.basic.button Kill
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
.ui.pointing.menu
|
|
2
|
-
.header.item
|
|
3
|
-
= "#{database.group.name} > #{database.name}"
|
|
4
|
-
= link_to "Databases", databases_path(database: database.name.parameterize), class: "item #{is_active('databases')}"
|
|
5
|
-
= link_to "Stats", stats_path(database: database.name.parameterize), class: "item #{is_active('stats')}"
|
|
6
|
-
= link_to "Pools", pools_path(database: database.name.parameterize), class: "item #{is_active('pools')}"
|
|
7
|
-
= link_to "Clients", clients_path(database: database.name.parameterize), class: "item #{is_active('clients')}"
|
|
8
|
-
= link_to "Configuration", conf_path(database: database.name.parameterize), class: "item #{is_active('conf')}"
|
|
9
|
-
.right.menu
|
|
10
|
-
.item
|
|
11
|
-
= link_to 'Reload', reload_path(database: database.name.parameterize), remote: :true, method: :post, class: 'ui button basic positive button', data: { confirm: 'Are you sure?' }
|
|
12
|
-
.item
|
|
13
|
-
= link_to 'Suspend', suspend_path(database: database.name.parameterize), remote: :true, method: :post, class: 'ui button basic primary button', data: { confirm: 'Are you sure?' }
|
|
14
|
-
.item
|
|
15
|
-
= link_to 'Shutdown', shutdown_path(database: database.name.parameterize), remote: :true, method: :post, class: 'ui button basic negative button', data: { confirm: 'Are you sure?' }
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
.ui.active.segment
|
|
2
|
-
|
|
3
|
-
%h4.ui.header
|
|
4
|
-
.content Stats
|
|
5
|
-
|
|
6
|
-
%table.ui.compact.table
|
|
7
|
-
%thead
|
|
8
|
-
%tr
|
|
9
|
-
- stats.first.keys.each do |key|
|
|
10
|
-
%th= key.titleize
|
|
11
|
-
%tbody
|
|
12
|
-
- stats.each do |row|
|
|
13
|
-
%tr
|
|
14
|
-
- row.each do |k,v|
|
|
15
|
-
- if ['total_received', 'total_sent', 'avg_recv', 'avg_sent'].include? k
|
|
16
|
-
%td= number_to_human_size(v)
|
|
17
|
-
- elsif ['total_query_time', 'avg_query'].include? k
|
|
18
|
-
%td= humanize_ms(v.to_i)
|
|
19
|
-
- else
|
|
20
|
-
%td= v
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
$("#segment_status_#{@database.group.name.parameterize}_#{@database.name.parameterize}").html("#{j(@database.connection ? "Online" : "Offline")}")
|
|
2
|
-
$("#segment_status_#{@database.group.name.parameterize}_#{@database.name.parameterize}").removeClass("grey negative positive").addClass("#{j(@database.connection ? "positive" : "negative")}")
|
|
3
|
-
$("#segment_content_#{@database.group.name.parameterize}_#{@database.name.parameterize}").replaceWith("#{j(render partial: 'pg_bouncer_hero/home/card_content', locals: {database: @database, id: "segment_content_#{@database.group.name.parameterize}_#{@database.name.parameterize}"})}")
|
|
4
|
-
$("#segment_refreshed_#{@database.group.name.parameterize}_#{@database.name.parameterize}").css('display', '')
|
|
5
|
-
$("#segment_content_#{@database.group.name.parameterize}_#{@database.name.parameterize} .ui.progress").each(function(idx, el) { $(el).progress({ text: {active: '{value} of {total} connections'}, autoSuccess: false }); });
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
.eight.wide.column{id: "segment_href_#{database.group.name.parameterize}_#{database.name.parameterize}", data: {href: summary_path(group: database.group.name.parameterize, database: database.name.parameterize)}}
|
|
2
|
-
= link_to databases_path(group: database.group.name.parameterize, database: database.name.parameterize), style: 'text-decoration: none !important; color: inherit !important' do
|
|
3
|
-
.ui.segments{style: 'margin-bottom: 10px;'}
|
|
4
|
-
.ui.segment{style: 'height: 60px;'}
|
|
5
|
-
%div{style: 'float: left;'}
|
|
6
|
-
%div{style: 'font-size: 16px; font-weight: bold;'}= database.name
|
|
7
|
-
%div{style: 'font-size: 12px; color: grey'}= database.host
|
|
8
|
-
%button.ui.button.basic.button{id: "segment_status_#{database.group.name.parameterize}_#{database.name.parameterize}", style: 'float: right;', class: 'grey'}= 'N/A'
|
|
9
|
-
= render partial: partial, locals: {database: database, id: "segment_content_#{database.group.name.parameterize}_#{database.name.parameterize}"}
|
|
10
|
-
.ui.segment{id: "segment_refreshed_#{database.group.name.parameterize}_#{database.name.parameterize}", style: 'height: 35px; display: none;'}
|
|
11
|
-
%span.right.floated{id: "segment_refreshed_span_#{database.group.name.parameterize}_#{database.name.parameterize}", style: 'float:right; margin-top: -6px; color: grey'}
|
|
12
|
-
Last refresh:
|
|
13
|
-
= Time.now.strftime("%H:%M:%S GMT%z (%Z)") # Same as new Date().toTimeString() in JS
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
- connected = database.connection
|
|
2
|
-
- if connected
|
|
3
|
-
.ui.horizontal.segments{id: id, style: 'background-color: white !important;'}
|
|
4
|
-
.ui.segment
|
|
5
|
-
- summary = database.summary
|
|
6
|
-
%div
|
|
7
|
-
%i.users.icon
|
|
8
|
-
- number = summary.select { |row| row['list'] == 'users' }.first['items']
|
|
9
|
-
= pluralize(number, 'user')
|
|
10
|
-
%div
|
|
11
|
-
%i.database.icon
|
|
12
|
-
- number = summary.select { |row| row['list'] == 'databases' }.first['items'].to_i - 1 # Removed pgbouncer
|
|
13
|
-
= pluralize(number, 'database')
|
|
14
|
-
%div
|
|
15
|
-
%i.plug.icon
|
|
16
|
-
- number = summary.select { |row| row['list'] == 'pools' }.first['items'].to_i - 1 # Removed pgbouncer
|
|
17
|
-
= pluralize(number, 'pool')
|
|
18
|
-
.ui.segment
|
|
19
|
-
%ul{style: 'margin: 0; padding-left: 5px;'}
|
|
20
|
-
- summary.select{ |row| row.key?(:databases_details) }.first[:databases_details].each do |db|
|
|
21
|
-
%li{style: 'margin: 0; list-style-type: none;'}
|
|
22
|
-
%span
|
|
23
|
-
%i.database.icon
|
|
24
|
-
%strong=db['name']
|
|
25
|
-
.ui.progress.small.success{data:{value: db['current_connections'], total: db['max_connections']}, style: 'float:right; width: 150px; margin-top:4px;'}
|
|
26
|
-
.bar
|
|
27
|
-
.progress
|
|
28
|
-
.label Connections
|