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 +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +11 -226
- data/app/controllers/pg_hero/home_controller.rb +47 -9
- data/app/views/layouts/pg_hero/application.html.erb +43 -16
- data/app/views/pg_hero/home/_live_queries_table.html.erb +27 -0
- data/app/views/pg_hero/home/_queries_table.html.erb +25 -14
- data/app/views/pg_hero/home/index.html.erb +22 -2
- data/app/views/pg_hero/home/{indexes.html.erb → index_usage.html.erb} +1 -1
- data/app/views/pg_hero/home/live_queries.html.erb +9 -0
- data/app/views/pg_hero/home/queries.html.erb +13 -5
- data/app/views/pg_hero/home/space.html.erb +8 -5
- data/app/views/pg_hero/home/system.html.erb +14 -0
- data/config/routes.rb +25 -14
- data/guides/Docker.md +5 -0
- data/guides/Heroku.md +58 -0
- data/guides/Linux.md +203 -0
- data/guides/Query-Stats.md +60 -0
- data/guides/Rails.md +187 -0
- data/lib/pghero.rb +95 -9
- data/lib/pghero/version.rb +1 -1
- metadata +11 -6
- data/app/views/pg_hero/home/_query_stats_table.html.erb +0 -38
- data/app/views/pg_hero/home/query_stats.html.erb +0 -17
- data/app/views/pg_hero/home/system_stats.html.erb +0 -9
@@ -0,0 +1,27 @@
|
|
1
|
+
<table class="table queries">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th style="width: 10%;">Pid</th>
|
5
|
+
<th style="width: 10%;">State</th>
|
6
|
+
<th>Source</th>
|
7
|
+
<th style="width: 10%;">Waiting</th>
|
8
|
+
<th style="width: 15%;">Duration</th>
|
9
|
+
<th style="width: 10%;"></th>
|
10
|
+
</tr>
|
11
|
+
</thead>
|
12
|
+
<tbody>
|
13
|
+
<% queries.each do |query| %>
|
14
|
+
<tr>
|
15
|
+
<td><%= query["pid"] %></td>
|
16
|
+
<td><%= query["state"] %></td>
|
17
|
+
<td><%= query["source"] %></td>
|
18
|
+
<td><%= query["waiting"] == "t" ? "true" : "false" %></td>
|
19
|
+
<td><%= query["started_at"] ? time_ago_in_words(query["started_at"], include_seconds: true) : nil %></td>
|
20
|
+
<td class="text-right"><%= button_to "Kill", kill_path(pid: query["pid"]), class: "btn btn-info" %></td>
|
21
|
+
</tr>
|
22
|
+
<tr>
|
23
|
+
<td colspan="6" style="border-top: none; padding: 0;"><pre><%= query["query"] %></pre></td>
|
24
|
+
</tr>
|
25
|
+
<% end %>
|
26
|
+
</tbody>
|
27
|
+
</table>
|
@@ -1,26 +1,37 @@
|
|
1
|
-
<table class="table
|
1
|
+
<table class="table">
|
2
2
|
<thead>
|
3
3
|
<tr>
|
4
|
-
<th style="width:
|
5
|
-
<th style="width:
|
6
|
-
<th>
|
7
|
-
<th style="width: 10%;">Waiting</th>
|
8
|
-
<th style="width: 15%;">Duration</th>
|
9
|
-
<th style="width: 10%;"></th>
|
4
|
+
<th style="width: 33.33%;">Total Time</th>
|
5
|
+
<th style="width: 33.33%;">Average Time</th>
|
6
|
+
<th style="width: 33.33%;">Calls</th>
|
10
7
|
</tr>
|
11
8
|
</thead>
|
12
9
|
<tbody>
|
13
10
|
<% queries.each do |query| %>
|
14
11
|
<tr>
|
15
|
-
<td
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
<td>
|
13
|
+
<%= number_with_delimiter(query["total_minutes"].to_f.round) %> min
|
14
|
+
<span class="percent">
|
15
|
+
<% percent = query["total_percent"].to_f %>
|
16
|
+
<% if percent > 1 %>
|
17
|
+
<%= percent.round %>%
|
18
|
+
<% elsif percent > 0.1 %>
|
19
|
+
<%= percent.round(1) %>%
|
20
|
+
<% else %>
|
21
|
+
< 0.1%
|
22
|
+
<% end %>
|
23
|
+
</span>
|
24
|
+
</td>
|
25
|
+
<td><%= number_with_delimiter(query["average_time"].to_f.round) %> ms</td>
|
26
|
+
<td><%= number_with_delimiter(query["calls"].to_i) %></td>
|
21
27
|
</tr>
|
22
28
|
<tr>
|
23
|
-
<td colspan="
|
29
|
+
<td colspan="3" style="border-top: none; padding: 0;">
|
30
|
+
<pre><%= query["query"] %></pre>
|
31
|
+
<% if query["query"] == "<insufficient privilege>" %>
|
32
|
+
<p class="text-muted">For security reasons, only superusers can see queries executed by other users.</p>
|
33
|
+
<% end %>
|
34
|
+
</td>
|
24
35
|
</tr>
|
25
36
|
<% end %>
|
26
37
|
</tbody>
|
@@ -1,4 +1,14 @@
|
|
1
1
|
<div id="status">
|
2
|
+
<% if @replica %>
|
3
|
+
<div class="alert alert-<%= @good_replication_lag ? "success" : "warning" %>">
|
4
|
+
<% if @good_replication_lag %>
|
5
|
+
Healthy replication lag
|
6
|
+
<% else %>
|
7
|
+
High replication lag
|
8
|
+
<% end %>
|
9
|
+
<span class="tiny"><%= number_with_delimiter((@replication_lag * 1000).round) %> ms</span>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
2
12
|
<div class="alert alert-<%= @long_running_queries.empty? ? "success" : "warning" %>">
|
3
13
|
<% if @long_running_queries.any? %>
|
4
14
|
<%= pluralize(@long_running_queries.size, "long running query") %>
|
@@ -19,6 +29,7 @@
|
|
19
29
|
<% else %>
|
20
30
|
High number of connections
|
21
31
|
<% end %>
|
32
|
+
<span class="tiny"><%= @total_connections %></span>
|
22
33
|
</div>
|
23
34
|
<div class="alert alert-<%= @query_stats_enabled && @slow_queries.empty? ? "success" : "warning" %>">
|
24
35
|
<% if !@query_stats_enabled %>
|
@@ -45,11 +56,20 @@
|
|
45
56
|
</div>
|
46
57
|
</div>
|
47
58
|
|
59
|
+
<% if @replica && !@good_replication_lag %>
|
60
|
+
<div class="content">
|
61
|
+
<h1>High Replication Lag</h1>
|
62
|
+
|
63
|
+
<p><%= pluralize(@replication_lag.round, "second") %></p>
|
64
|
+
</div>
|
65
|
+
<% end %>
|
66
|
+
|
48
67
|
<% if @long_running_queries.any? %>
|
49
68
|
<div class="content">
|
69
|
+
<%= button_to "Kill All", kill_long_running_queries_path, class: "btn btn-danger", style: "float: right;" %>
|
50
70
|
<h1>Long Running Queries</h1>
|
51
71
|
|
52
|
-
<%= render partial: "
|
72
|
+
<%= render partial: "live_queries_table", locals: {queries: @long_running_queries} %>
|
53
73
|
</div>
|
54
74
|
<% end %>
|
55
75
|
|
@@ -102,7 +122,7 @@ pg_stat_statements.track = all</pre>
|
|
102
122
|
<p>Slow queries take <%= PgHero.slow_query_ms %> ms or more on average and have been called at least <%= PgHero.slow_query_calls %> times.</p>
|
103
123
|
<p><%= link_to "Explain queries", explain_path %> to see where to add indexes.</p>
|
104
124
|
|
105
|
-
<%= render partial: "
|
125
|
+
<%= render partial: "queries_table", locals: {queries: @slow_queries} %>
|
106
126
|
</div>
|
107
127
|
<% end %>
|
108
128
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<div class="content">
|
2
|
+
<h1>Live Queries</h1>
|
3
|
+
|
4
|
+
<%= render partial: "live_queries_table", locals: {queries: @running_queries} %>
|
5
|
+
|
6
|
+
<p><%= button_to "Kill all connections", kill_all_path, class: "btn btn-danger" %></p>
|
7
|
+
|
8
|
+
<p class="text-muted">You may need to restart your Rails server afterwards.</p>
|
9
|
+
</div>
|
@@ -1,9 +1,17 @@
|
|
1
1
|
<div class="content">
|
2
|
-
|
2
|
+
<% if @query_stats_enabled %>
|
3
|
+
<%= button_to "Reset", reset_query_stats_path, class: "btn btn-danger", style: "float: right;" %>
|
4
|
+
<% end %>
|
3
5
|
|
4
|
-
|
6
|
+
<h1>Queries</h1>
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
<% if @query_stats_enabled %>
|
9
|
+
<% if @query_stats.any? %>
|
10
|
+
<%= render partial: "queries_table", locals: {queries: @query_stats} %>
|
11
|
+
<% else %>
|
12
|
+
<p>Stats are not available yet. Come back soon!</p>
|
13
|
+
<% end %>
|
14
|
+
<% else %>
|
15
|
+
<p>Query stats are not enabled.</p>
|
16
|
+
<% end %>
|
9
17
|
</div>
|
@@ -1,21 +1,24 @@
|
|
1
1
|
<div class="content">
|
2
|
-
<h1>
|
2
|
+
<h1>Space</h1>
|
3
3
|
|
4
4
|
<p>Database Size: <%= @database_size %></p>
|
5
5
|
|
6
6
|
<table class="table">
|
7
7
|
<thead>
|
8
8
|
<tr>
|
9
|
-
<th>
|
10
|
-
<th style="width: 20%;">Type</th>
|
9
|
+
<th>Relation</th>
|
11
10
|
<th style="width: 20%;">Size</th>
|
12
11
|
</tr>
|
13
12
|
</thead>
|
14
13
|
<tbody>
|
15
14
|
<% @relation_sizes.each do |query| %>
|
16
15
|
<tr>
|
17
|
-
<td
|
18
|
-
|
16
|
+
<td>
|
17
|
+
<%= query["name"] %>
|
18
|
+
<% if query["type"] != "table" %>
|
19
|
+
<span class="text-muted"><%= query["type"] %></span>
|
20
|
+
<% end %>
|
21
|
+
</td>
|
19
22
|
<td><%= query["size"] %></td>
|
20
23
|
</tr>
|
21
24
|
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%= javascript_include_tag "//www.google.com/jsapi", "//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js", "chartkick" %>
|
2
|
+
|
3
|
+
<div class="content">
|
4
|
+
<h1>CPU</h1>
|
5
|
+
<div style="margin-bottom: 20px;"><%= line_chart cpu_usage_path, max: 100, colors: ["#5bc0de"], library: {pointSize: 0, lineWidth: 5} %></div>
|
6
|
+
|
7
|
+
<h1>Connections</h1>
|
8
|
+
<div style="margin-bottom: 20px;"><%= line_chart connection_stats_path, colors: ["#5bc0de"], library: {pointSize: 0, lineWidth: 5} %></div>
|
9
|
+
|
10
|
+
<% if PgHero.replica? %>
|
11
|
+
<h1>Replication Lag</h1>
|
12
|
+
<div style="margin-bottom: 20px;"><%= line_chart replication_lag_stats_path, colors: ["#5bc0de"], library: {pointSize: 0, lineWidth: 5} %></div>
|
13
|
+
<% end %>
|
14
|
+
</div>
|
data/config/routes.rb
CHANGED
@@ -1,17 +1,28 @@
|
|
1
1
|
PgHero::Engine.routes.draw do
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
scope "(:database)", constraints: proc { |req| (PgHero.config["databases"].keys + [nil]).include?(req.params[:database]) } do
|
3
|
+
get "index_usage", to: "home#index_usage"
|
4
|
+
get "space", to: "home#space"
|
5
|
+
get "live_queries", to: "home#live_queries"
|
6
|
+
get "queries", to: "home#queries"
|
7
|
+
get "system", to: "home#system"
|
8
|
+
get "cpu_usage", to: "home#cpu_usage"
|
9
|
+
get "connection_stats", to: "home#connection_stats"
|
10
|
+
get "replication_lag_stats", to: "home#replication_lag_stats"
|
11
|
+
get "explain", to: "home#explain"
|
12
|
+
get "tune", to: "home#tune"
|
13
|
+
get "connections", to: "home#connections"
|
14
|
+
post "kill", to: "home#kill"
|
15
|
+
post "kill_long_running_queries", to: "home#kill_long_running_queries"
|
16
|
+
post "kill_all", to: "home#kill_all"
|
17
|
+
post "enable_query_stats", to: "home#enable_query_stats"
|
18
|
+
post "explain", to: "home#explain"
|
19
|
+
post "reset_query_stats", to: "home#reset_query_stats"
|
11
20
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
21
|
+
# legacy routes
|
22
|
+
get "system_stats" => redirect("system")
|
23
|
+
get "query_stats" => redirect("queries")
|
24
|
+
get "indexes" => redirect("index_usage")
|
25
|
+
|
26
|
+
root to: "home#index"
|
27
|
+
end
|
17
28
|
end
|
data/guides/Docker.md
ADDED
data/guides/Heroku.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# PgHero for Heroku
|
2
|
+
|
3
|
+
One click deployment
|
4
|
+
|
5
|
+
[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/pghero/pghero)
|
6
|
+
|
7
|
+
## Authentication
|
8
|
+
|
9
|
+
Set the following variables in your environment.
|
10
|
+
|
11
|
+
```sh
|
12
|
+
heroku config:set PGHERO_USERNAME=link
|
13
|
+
heroku config:set PGHERO_PASSWORD=hyrule
|
14
|
+
```
|
15
|
+
|
16
|
+
## Query Stats
|
17
|
+
|
18
|
+
Query stats are enabled by default for Heroku databases - there’s nothing to do :tada:
|
19
|
+
|
20
|
+
For databases outside of Heroku, query stats can be enabled from the dashboard.
|
21
|
+
|
22
|
+
If you run into issues, [view the guide](Query-Stats.md).
|
23
|
+
|
24
|
+
## System Stats
|
25
|
+
|
26
|
+
CPU usage is available for Amazon RDS. Add these variables to your environment:
|
27
|
+
|
28
|
+
```sh
|
29
|
+
heroku config:set PGHERO_ACCESS_KEY_ID=accesskey123
|
30
|
+
heroku config:set PGHERO_SECRET_ACCESS_KEY=secret123
|
31
|
+
heroku config:set PGHERO_DB_INSTANCE_IDENTIFIER=epona
|
32
|
+
```
|
33
|
+
|
34
|
+
## Customize
|
35
|
+
|
36
|
+
Minimum time for long running queries
|
37
|
+
|
38
|
+
```sh
|
39
|
+
heroku config:set PGHERO_LONG_RUNNING_QUERY_SEC=60 # default
|
40
|
+
```
|
41
|
+
|
42
|
+
Minimum average time for slow queries
|
43
|
+
|
44
|
+
```sh
|
45
|
+
heroku config:set PGHERO_SLOW_QUERY_MS=20 # default
|
46
|
+
```
|
47
|
+
|
48
|
+
Minimum calls for slow queries
|
49
|
+
|
50
|
+
```sh
|
51
|
+
heroku config:set PGHERO_SLOW_QUERY_CALLS=100 # default
|
52
|
+
```
|
53
|
+
|
54
|
+
Minimum connections for high connections warning
|
55
|
+
|
56
|
+
```sh
|
57
|
+
heroku config:set PGHERO_TOTAL_CONNECTIONS_THRESHOLD=100 # default
|
58
|
+
```
|
data/guides/Linux.md
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
# PgHero for Linux
|
2
|
+
|
3
|
+
Packaged for:
|
4
|
+
|
5
|
+
- Ubuntu 14.04 (Trusty)
|
6
|
+
- Ubuntu 12.04 (Precise)
|
7
|
+
- Debian 7 (Wheezy)
|
8
|
+
- CentOS and RHEL 6
|
9
|
+
- Fedora 20
|
10
|
+
- SUSE Linux Enterprise Server
|
11
|
+
|
12
|
+
64-bit only
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Ubuntu 14.04 (Trusty)
|
17
|
+
|
18
|
+
```sh
|
19
|
+
wget -qO - https://deb.packager.io/key | sudo apt-key add -
|
20
|
+
echo "deb https://deb.packager.io/gh/pghero/pghero trusty master" | sudo tee /etc/apt/sources.list.d/pghero.list
|
21
|
+
sudo apt-get update
|
22
|
+
sudo apt-get install pghero
|
23
|
+
```
|
24
|
+
|
25
|
+
Ubuntu 12.04 (Precise)
|
26
|
+
|
27
|
+
```sh
|
28
|
+
wget -qO - https://deb.packager.io/key | sudo apt-key add -
|
29
|
+
echo "deb https://deb.packager.io/gh/pghero/pghero precise master" | sudo tee /etc/apt/sources.list.d/pghero.list
|
30
|
+
sudo apt-get update
|
31
|
+
sudo apt-get install pghero
|
32
|
+
```
|
33
|
+
|
34
|
+
Debian 7 (Wheezy)
|
35
|
+
|
36
|
+
```sh
|
37
|
+
wget -qO - https://deb.packager.io/key | sudo apt-key add -
|
38
|
+
echo "deb https://deb.packager.io/gh/pghero/pghero wheezy master" | sudo tee /etc/apt/sources.list.d/pghero.list
|
39
|
+
sudo apt-get update
|
40
|
+
sudo apt-get install pghero
|
41
|
+
```
|
42
|
+
|
43
|
+
CentOS and RHEL 6
|
44
|
+
|
45
|
+
```sh
|
46
|
+
sudo rpm --import https://rpm.packager.io/key
|
47
|
+
echo "[pghero]
|
48
|
+
name=Repository for pghero/pghero application.
|
49
|
+
baseurl=https://rpm.packager.io/gh/pghero/pghero/centos6/master
|
50
|
+
enabled=1" | sudo tee /etc/yum.repos.d/pghero.repo
|
51
|
+
sudo yum install pghero
|
52
|
+
```
|
53
|
+
|
54
|
+
Fedora 20
|
55
|
+
|
56
|
+
```sh
|
57
|
+
sudo rpm --import https://rpm.packager.io/key
|
58
|
+
echo "[pghero]
|
59
|
+
name=Repository for pghero/pghero application.
|
60
|
+
baseurl=https://rpm.packager.io/gh/pghero/pghero/fedora20/master
|
61
|
+
enabled=1" | sudo tee /etc/yum.repos.d/pghero.repo
|
62
|
+
sudo yum install pghero
|
63
|
+
```
|
64
|
+
|
65
|
+
SUSE Linux Enterprise Server
|
66
|
+
|
67
|
+
```sh
|
68
|
+
sudo rpm --import https://rpm.packager.io/key
|
69
|
+
sudo zypper addrepo "https://rpm.packager.io/gh/pghero/pghero/sles12/master" "pghero"
|
70
|
+
sudo zypper install pghero
|
71
|
+
```
|
72
|
+
|
73
|
+
## Setup
|
74
|
+
|
75
|
+
Add your database.
|
76
|
+
|
77
|
+
```sh
|
78
|
+
sudo pghero config:set DATABASE_URL=postgres://user:password@hostname:5432/dbname
|
79
|
+
```
|
80
|
+
|
81
|
+
And optional authentication.
|
82
|
+
|
83
|
+
```sh
|
84
|
+
sudo pghero config:set PGHERO_USERNAME=link
|
85
|
+
sudo pghero config:set PGHERO_PASSWORD=hyrule
|
86
|
+
```
|
87
|
+
|
88
|
+
Start the server - defaults to port `6000`.
|
89
|
+
|
90
|
+
```sh
|
91
|
+
sudo pghero scale web=1
|
92
|
+
```
|
93
|
+
|
94
|
+
Confirm it’s running with:
|
95
|
+
|
96
|
+
```sh
|
97
|
+
curl -v http://localhost:6000/
|
98
|
+
```
|
99
|
+
|
100
|
+
To open to the outside world, add a proxy. Here’s how to do it with Nginx on Ubuntu.
|
101
|
+
|
102
|
+
```sh
|
103
|
+
sudo apt-get install -y nginx
|
104
|
+
cat | sudo tee /etc/nginx/sites-available/default <<EOF
|
105
|
+
server {
|
106
|
+
listen 80;
|
107
|
+
server_name "";
|
108
|
+
location / {
|
109
|
+
proxy_pass http://localhost:6000;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
EOF
|
113
|
+
sudo service nginx restart
|
114
|
+
```
|
115
|
+
|
116
|
+
## Management
|
117
|
+
|
118
|
+
Ubuntu, CentOS, and RHEL
|
119
|
+
|
120
|
+
```sh
|
121
|
+
sudo service pghero status
|
122
|
+
sudo service pghero start
|
123
|
+
sudo service pghero stop
|
124
|
+
sudo service pghero restart
|
125
|
+
```
|
126
|
+
|
127
|
+
Debian, Fedora, and SUSE
|
128
|
+
|
129
|
+
```sh
|
130
|
+
#todo
|
131
|
+
```
|
132
|
+
|
133
|
+
## Query Stats
|
134
|
+
|
135
|
+
Query stats can be enabled from the dashboard. If you run into issues, [view the guide](Query-Stats.md).
|
136
|
+
|
137
|
+
## System Stats
|
138
|
+
|
139
|
+
CPU usage is available for Amazon RDS. Add these variables to your environment:
|
140
|
+
|
141
|
+
```sh
|
142
|
+
sudo pghero config:set PGHERO_ACCESS_KEY_ID=accesskey123
|
143
|
+
sudo pghero config:set PGHERO_SECRET_ACCESS_KEY=secret123
|
144
|
+
sudo pghero config:set PGHERO_DB_INSTANCE_IDENTIFIER=epona
|
145
|
+
```
|
146
|
+
|
147
|
+
## Customize
|
148
|
+
|
149
|
+
Change the port - you cannot use a privileged port like `80` or `443`
|
150
|
+
|
151
|
+
```sh
|
152
|
+
sudo pghero config:set PORT=6000 # default
|
153
|
+
```
|
154
|
+
|
155
|
+
Minimum time for long running queries
|
156
|
+
|
157
|
+
```sh
|
158
|
+
sudo pghero config:set PGHERO_LONG_RUNNING_QUERY_SEC=60 # default
|
159
|
+
```
|
160
|
+
|
161
|
+
Minimum average time for slow queries
|
162
|
+
|
163
|
+
```sh
|
164
|
+
sudo pghero config:set PGHERO_SLOW_QUERY_MS=20 # default
|
165
|
+
```
|
166
|
+
|
167
|
+
Minimum calls for slow queries
|
168
|
+
|
169
|
+
```sh
|
170
|
+
sudo pghero config:set PGHERO_SLOW_QUERY_CALLS=100 # default
|
171
|
+
```
|
172
|
+
|
173
|
+
Minimum connections for high connections warning
|
174
|
+
|
175
|
+
```sh
|
176
|
+
sudo pghero config:set PGHERO_TOTAL_CONNECTIONS_THRESHOLD=100 # default
|
177
|
+
```
|
178
|
+
|
179
|
+
## Upgrading
|
180
|
+
|
181
|
+
Ubuntu and Debian
|
182
|
+
|
183
|
+
```sh
|
184
|
+
sudo apt-get update
|
185
|
+
sudo apt-get install --only-upgrade pghero
|
186
|
+
```
|
187
|
+
|
188
|
+
CentOS, RHEL, and Fedora
|
189
|
+
|
190
|
+
```sh
|
191
|
+
sudo yum update
|
192
|
+
sudo yum install pghero
|
193
|
+
```
|
194
|
+
|
195
|
+
SUSE
|
196
|
+
|
197
|
+
```sh
|
198
|
+
sudo zypper update pghero
|
199
|
+
```
|
200
|
+
|
201
|
+
## Credits
|
202
|
+
|
203
|
+
:heart: Made possible by [Packager](https://packager.io/)
|