rails-server-monitor 0.1.5 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +116 -14
- data/app/controllers/rails_server_monitor/servers_controller.rb +10 -1
- data/app/helpers/rails_server_monitor/application_helper.rb +4 -0
- data/app/models/rails_server_monitor/server.rb +6 -0
- data/app/services/rails_server_monitor/chart_for_server.rb +10 -4
- data/app/services/rails_server_monitor/server_setup.rb +1 -1
- data/app/views/layouts/rails_server_monitor/application.html.erb +13 -8
- data/app/views/rails_server_monitor/page/_footer.html.erb +8 -0
- data/app/views/rails_server_monitor/servers/show.html.erb +10 -9
- data/app/views/rails_server_monitor/servers/show/_chart.html.erb +10 -0
- data/babel.config.js +91 -0
- data/bin/rails +24 -0
- data/bin/rspec +5 -0
- data/bin/start +4 -0
- data/bin/webpack +18 -0
- data/bin/webpack-dev-server +19 -0
- data/lib/rails_server_monitor/compile_locally.rb +26 -0
- data/lib/rails_server_monitor/configuration.rb +6 -2
- data/lib/rails_server_monitor/version.rb +1 -1
- data/lib/tasks/rails_server_monitor_tasks.rake +2 -2
- data/package.json +74 -0
- data/postcss.config.js +14 -0
- data/tailwind.config.js +19 -0
- data/yarn.lock +7686 -0
- metadata +15 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 268207f2f8ac3e85b708ffeaa1832fa6d73695e0607d563da57f8aa10cde2cf7
|
4
|
+
data.tar.gz: 2b95fab09530776702bdc9e69f0a3d76e35a3d6e09e1c046c5ac3c0406c037a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4425081d0efb0055834413d5bbbd5915c2501e1511e0ac018c0e5e33cc90d2f503e521bf95795bf8db5beee95d20c57b4db835e02b558bfc3a9f2a41396e2e8b
|
7
|
+
data.tar.gz: 94d6118f89a7f467f7182a07d3fde1075414b27dc99671303c91df2fc454ca97d953d9cb06e3a236586bdedd484ce309b76221c7554967f9cdb16c5f5e10d284
|
data/README.md
CHANGED
@@ -1,28 +1,130 @@
|
|
1
|
-
# Rails
|
2
|
-
|
1
|
+
# Rails Server Monitor
|
2
|
+
A performance dashboard for rails applications which work with one or multiple servers at once.
|
3
|
+
Stats can be collected from a Rack application or Sidekiq.
|
3
4
|
|
4
|
-
|
5
|
-
How to use my plugin.
|
5
|
+
[See it in action](https://rails-sever-monitor.herokuapp.com)
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
![demo](https://github.com/personal-social-media/rails-server-monitor/raw/master/resources/screenshot-dashboard.jpg)
|
8
|
+
![demo](https://github.com/personal-social-media/rails-server-monitor/raw/master/resources/screenshot1.jpg)
|
9
9
|
|
10
|
+
## Usage
|
11
|
+
#### 1)
|
10
12
|
```ruby
|
11
|
-
gem 'rails-server-monitor'
|
13
|
+
gem 'rails-server-monitor', require: "rails_server_monitor"
|
12
14
|
```
|
13
15
|
|
14
|
-
|
16
|
+
#### 2) generate Rails Server Monitor tables
|
15
17
|
```bash
|
16
|
-
|
18
|
+
rails g rails_server_monitor:install
|
19
|
+
rails db:migrate
|
17
20
|
```
|
18
21
|
|
19
|
-
|
20
|
-
```
|
21
|
-
|
22
|
+
#### 3) hook Rails Server Monitor's rack middleware
|
23
|
+
```ruby
|
24
|
+
# inside config/application.rb
|
25
|
+
config.middleware.use RailsServerMonitor::RackMiddleware
|
26
|
+
```
|
27
|
+
|
28
|
+
#### 4) compile Rails Server Monitor assets locally
|
29
|
+
if you aren't using webpacker already
|
30
|
+
```shell
|
31
|
+
# you don't need to do this in production, it's prepended to rake assets:precompile
|
32
|
+
# but you need to do it again after you after you update the gem locally
|
33
|
+
rake webpacker:compile
|
34
|
+
```
|
35
|
+
|
36
|
+
or if you are using
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# inside bin/webpack-dev-server
|
40
|
+
require "rails_server_monitor/compile_locally"
|
41
|
+
RailsServerMonitor::CompileLocally.compile
|
42
|
+
|
43
|
+
# insert before this before
|
44
|
+
# Dir.chdir(APP_ROOT) do
|
45
|
+
# Webpacker::DevServerRunner.run(ARGV)
|
46
|
+
# end
|
47
|
+
```
|
48
|
+
|
49
|
+
#### 5) (Optional) configure gem
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# inside config/initializers/rails_server_monitor
|
53
|
+
|
54
|
+
RailsServerMonitor.config do |c|
|
55
|
+
c.update_server_interval = 1.hour
|
56
|
+
c.snapshot_server_interval = 15.minutes
|
57
|
+
c.cleanup_snapshots_after = 90.days
|
58
|
+
c.ignore_workers = %w(MyIgnoredWorker)
|
59
|
+
c.ignore_urls = ["/", /ignored-url/]
|
60
|
+
|
61
|
+
c.high_cpu_usage_threshold = 95
|
62
|
+
c.low_memory_threshold = 20
|
63
|
+
c.low_free_disk_disk_threshold = 30
|
64
|
+
c.hostname = -> do
|
65
|
+
`hostname`
|
66
|
+
end # how to retrieve server hostname, heroku generates a hostname each time your app reboots
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
#### 6) Mount engine to routes
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
# inside config/routes.rb
|
74
|
+
constraints LoggedInAsAdmin do
|
75
|
+
mount RailsServerMonitor::Engine => "/system-information"
|
76
|
+
end
|
22
77
|
```
|
23
78
|
|
79
|
+
Your should define a constraint to protect against unauthorized access
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# example LoggedInAsAdmin, this is a basic implementation
|
83
|
+
|
84
|
+
class LoggedInAsAdmin
|
85
|
+
def self.matches?(request)
|
86
|
+
AdminUser.find_by(id: request.session[:admin_id]).present?
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
```
|
92
|
+
|
93
|
+
#### 7) (Optional) Add sidekiq middleware
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
# append to config/sidekiq.rb
|
97
|
+
|
98
|
+
Sidekiq.configure_server do |config|
|
99
|
+
config.server_middleware do |chain|
|
100
|
+
chain.add RailsServerMonitor::SidekiqMiddleware
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
### 8) Result
|
106
|
+
|
107
|
+
you should now go to http://localhost:3000/system-information
|
108
|
+
|
24
109
|
## Contributing
|
25
|
-
|
110
|
+
|
111
|
+
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
112
|
+
|
113
|
+
- [Report bugs](https://github.com/personal-social-media/rails-server-monitor/issues)
|
114
|
+
- Fix bugs and [submit pull requests](https://github.com/personal-social-media/rails-server-monitor/pulls)
|
115
|
+
- Write, clarify, or fix documentation
|
116
|
+
- Suggest or add new features
|
117
|
+
|
118
|
+
### Development
|
119
|
+
|
120
|
+
```shell
|
121
|
+
# fork project, clone
|
122
|
+
bundle install
|
123
|
+
yarn install
|
124
|
+
|
125
|
+
bin/start # to start local server
|
126
|
+
bin/rspec # to run specs
|
127
|
+
```
|
26
128
|
|
27
129
|
## License
|
28
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
130
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -6,11 +6,20 @@ module RailsServerMonitor
|
|
6
6
|
|
7
7
|
def show
|
8
8
|
@server = current_server
|
9
|
-
@chart = RailsServerMonitor::ChartForServer.new(@server)
|
9
|
+
@chart = RailsServerMonitor::ChartForServer.new(@server, timeline: params[:timeline])
|
10
10
|
|
11
11
|
@title = @server.display_name
|
12
12
|
end
|
13
13
|
|
14
|
+
def update
|
15
|
+
update_params = params.require(:server).permit(:custom_name, :custom_description)
|
16
|
+
current_server.update!(update_params)
|
17
|
+
redirect_to server_path(current_server)
|
18
|
+
|
19
|
+
rescue ActiveRecord::RecordInvalid => e
|
20
|
+
render json: { error: e.message }, status: 422
|
21
|
+
end
|
22
|
+
|
14
23
|
def current_server
|
15
24
|
@current_server ||= RailsServerMonitor::Server.find_by(id: params[:id])
|
16
25
|
end
|
@@ -20,8 +20,14 @@ module RailsServerMonitor
|
|
20
20
|
foreign_key: :rails_server_monitor_server_id,
|
21
21
|
dependent: :delete_all
|
22
22
|
|
23
|
+
before_save :squish_text
|
24
|
+
|
23
25
|
def display_name
|
24
26
|
@display_name ||= custom_name.present? ? custom_name : hostname
|
25
27
|
end
|
28
|
+
|
29
|
+
def squish_text
|
30
|
+
self.custom_name = self.custom_name&.squish
|
31
|
+
end
|
26
32
|
end
|
27
33
|
end
|
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
module RailsServerMonitor
|
4
4
|
class ChartForServer
|
5
|
+
AVAILABLE_TIMELINES = %w(today week month all)
|
5
6
|
attr_reader :server, :timeline
|
6
|
-
def initialize(server, timeline:
|
7
|
+
def initialize(server, timeline:)
|
7
8
|
@server = server
|
8
|
-
@timeline = timeline
|
9
|
+
@timeline = timeline.blank? ? "today" : timeline
|
9
10
|
end
|
10
11
|
|
11
12
|
def render_chart
|
@@ -23,10 +24,9 @@ module RailsServerMonitor
|
|
23
24
|
end
|
24
25
|
|
25
26
|
def today?
|
26
|
-
timeline ==
|
27
|
+
timeline == "today"
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
30
|
def last_record
|
31
31
|
@last_record = scope.last
|
32
32
|
end
|
@@ -36,6 +36,12 @@ module RailsServerMonitor
|
|
36
36
|
query = server.server_snapshots.order(id: :asc)
|
37
37
|
if today?
|
38
38
|
query = query.where("created_at > ?", 1.day.ago)
|
39
|
+
elsif timeline == "week"
|
40
|
+
query = query.where("created_at > ?", 7.day.ago)
|
41
|
+
elsif timeline == "month"
|
42
|
+
query = query.where("created_at > ?", 30.day.ago)
|
43
|
+
else
|
44
|
+
query = query.all
|
39
45
|
end
|
40
46
|
@scope = query.to_a
|
41
47
|
end
|
@@ -9,17 +9,22 @@
|
|
9
9
|
<%= safe_render_css "rails-server-application", 'data-turbolinks-track': "reload" %>
|
10
10
|
</head>
|
11
11
|
<body>
|
12
|
+
<div class="flex min-h-screen flex-col justify-between">
|
13
|
+
<div class="flex">
|
14
|
+
<div class="overflow-y-auto fixed top-0 left-0 bottom-0 bg-white w-1/5">
|
15
|
+
<%= render RailsServerMonitor::LeftbarComponent.new(ctx: self) %>
|
16
|
+
</div>
|
17
|
+
<div class="w-1/5 mr-4"></div>
|
12
18
|
|
13
|
-
<div class="flex">
|
14
|
-
|
15
|
-
|
16
|
-
</div>
|
17
|
-
<div class="w-1/5 mr-4"></div>
|
19
|
+
<div class="flex-1">
|
20
|
+
<%= yield %>
|
21
|
+
</div>
|
18
22
|
|
19
|
-
|
20
|
-
|
23
|
+
</div>
|
24
|
+
<div class="p-4 flex">
|
25
|
+
<div class="w-1/5 mr-4"></div>
|
26
|
+
<%= render "rails_server_monitor/page/footer" %>
|
21
27
|
</div>
|
22
28
|
</div>
|
23
|
-
|
24
29
|
</body>
|
25
30
|
</html>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div class="flex-1">
|
2
|
+
<a href="https://github.com/personal-social-media/rails-server-monitor" target="_blank" class="flex items-center mx-auto w-1/4">
|
3
|
+
<i class="fab fa-github fa-3x"></i>
|
4
|
+
<span class="ml-2">
|
5
|
+
Rails Server Monitor V<%= server_version %>
|
6
|
+
</span>
|
7
|
+
</a>
|
8
|
+
</div>
|
@@ -3,11 +3,8 @@
|
|
3
3
|
<%= @server.display_name %>
|
4
4
|
</div>
|
5
5
|
|
6
|
-
|
7
6
|
<div class="flex mt-4">
|
8
|
-
<%=
|
9
|
-
<%= line_chart @chart.render_chart %>
|
10
|
-
<% end %>
|
7
|
+
<%= render(partial: "rails_server_monitor/servers/show/chart") %>
|
11
8
|
|
12
9
|
<% if @chart.today? && @chart.last_record.present? %>
|
13
10
|
<div class="w-1/2 p-2">
|
@@ -49,7 +46,7 @@
|
|
49
46
|
<% end %>
|
50
47
|
</div>
|
51
48
|
|
52
|
-
|
49
|
+
<%= form_with model: @server, html: { class: "mt-20" } do |f| %>
|
53
50
|
<div class="mb-2 text-xl">
|
54
51
|
Sever information:
|
55
52
|
</div>
|
@@ -64,13 +61,13 @@
|
|
64
61
|
Custom name:
|
65
62
|
</div>
|
66
63
|
<div class="p-1">
|
67
|
-
<%=
|
64
|
+
<%= f.text_field :custom_name, class: "border border-solid border-gray-200 p-2 focus:border-gray-300 w-full" %>
|
68
65
|
</div>
|
69
66
|
<div class="bg-blue-300 text-gray-800 p-1">
|
70
67
|
Custom description:
|
71
68
|
</div>
|
72
69
|
<div class="p-1">
|
73
|
-
<%=
|
70
|
+
<%= f.text_area :custom_description, class: "border border-solid border-gray-200 p-2 focus:border-gray-300 w-full" %>
|
74
71
|
</div>
|
75
72
|
<div class="mb-2 text-xl">
|
76
73
|
OS information
|
@@ -110,7 +107,7 @@
|
|
110
107
|
)) %>
|
111
108
|
|
112
109
|
<%= render(RailsServerMonitor::ServerTableRow.new(
|
113
|
-
title: "CPU
|
110
|
+
title: "CPU Cores",
|
114
111
|
value: @server.system_cpu_cores
|
115
112
|
)) %>
|
116
113
|
|
@@ -129,5 +126,9 @@
|
|
129
126
|
value: "#{@server.system_hdd_available_in_gb} GB"
|
130
127
|
)) %>
|
131
128
|
</div>
|
132
|
-
|
129
|
+
|
130
|
+
<div class="mt-20 w-1/2">
|
131
|
+
<%= f.submit "Save custom information", class: "p-2 w-full bg-blue-500 text-white" %>
|
132
|
+
</div>
|
133
|
+
<% end %>
|
133
134
|
</div>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= content_tag :div, class: "#{@chart.today? ? "w-1/2" : "w-full"}" do %>
|
2
|
+
<%= line_chart @chart.render_chart %>
|
3
|
+
|
4
|
+
<div class="flex justify-between">
|
5
|
+
<% RailsServerMonitor::ChartForServer::AVAILABLE_TIMELINES.each do |timeline| %>
|
6
|
+
<%= link_to timeline.humanize, server_path(@server, timeline: timeline),
|
7
|
+
class: "#{@chart.timeline == timeline ? "bg-blue-500 text-white" : "bg-gray-300 text-gray-800" } p-2 rounded hover:bg-blue-400" %>
|
8
|
+
<% end %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
data/babel.config.js
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
module.exports = function(api) {
|
2
|
+
var validEnv = ['development', 'test', 'production']
|
3
|
+
var currentEnv = api.env()
|
4
|
+
var isDevelopmentEnv = api.env('development')
|
5
|
+
var isProductionEnv = api.env('production')
|
6
|
+
var isTestEnv = api.env('test')
|
7
|
+
|
8
|
+
if (!validEnv.includes(currentEnv)) {
|
9
|
+
throw new Error(
|
10
|
+
'Please specify a valid `NODE_ENV` or ' +
|
11
|
+
'`BABEL_ENV` environment variables. Valid values are "development", ' +
|
12
|
+
'"test", and "production". Instead, received: ' +
|
13
|
+
JSON.stringify(currentEnv) +
|
14
|
+
'.'
|
15
|
+
)
|
16
|
+
}
|
17
|
+
|
18
|
+
return {
|
19
|
+
presets: [
|
20
|
+
isTestEnv && [
|
21
|
+
'@babel/preset-env',
|
22
|
+
{
|
23
|
+
targets: {
|
24
|
+
node: 'current'
|
25
|
+
},
|
26
|
+
modules: 'commonjs'
|
27
|
+
},
|
28
|
+
[
|
29
|
+
'@babel/preset-react',
|
30
|
+
{
|
31
|
+
development: true,
|
32
|
+
useBuiltIns: true,
|
33
|
+
runtime: "automatic",
|
34
|
+
}
|
35
|
+
]
|
36
|
+
],
|
37
|
+
(isProductionEnv || isDevelopmentEnv) && [
|
38
|
+
'@babel/preset-env',
|
39
|
+
{
|
40
|
+
forceAllTransforms: true,
|
41
|
+
useBuiltIns: 'entry',
|
42
|
+
corejs: 3,
|
43
|
+
modules: false,
|
44
|
+
loose: false,
|
45
|
+
exclude: ['transform-typeof-symbol']
|
46
|
+
}
|
47
|
+
],
|
48
|
+
[
|
49
|
+
'@babel/preset-react',
|
50
|
+
{
|
51
|
+
development: isDevelopmentEnv || isTestEnv,
|
52
|
+
useBuiltIns: true,
|
53
|
+
runtime: "automatic"
|
54
|
+
}
|
55
|
+
]
|
56
|
+
].filter(Boolean),
|
57
|
+
plugins: [
|
58
|
+
'babel-plugin-macros',
|
59
|
+
'@babel/plugin-syntax-dynamic-import',
|
60
|
+
isTestEnv && 'babel-plugin-dynamic-import-node',
|
61
|
+
'@babel/plugin-transform-destructuring',
|
62
|
+
'@babel/plugin-proposal-class-properties',
|
63
|
+
[
|
64
|
+
'@babel/plugin-proposal-object-rest-spread',
|
65
|
+
{
|
66
|
+
useBuiltIns: true
|
67
|
+
}
|
68
|
+
],
|
69
|
+
[
|
70
|
+
'@babel/plugin-transform-runtime',
|
71
|
+
{
|
72
|
+
helpers: false,
|
73
|
+
regenerator: true,
|
74
|
+
corejs: false
|
75
|
+
}
|
76
|
+
],
|
77
|
+
[
|
78
|
+
'@babel/plugin-transform-regenerator',
|
79
|
+
{
|
80
|
+
async: false
|
81
|
+
}
|
82
|
+
],
|
83
|
+
isProductionEnv && [
|
84
|
+
'babel-plugin-transform-react-remove-prop-types',
|
85
|
+
{
|
86
|
+
removeImport: true
|
87
|
+
}
|
88
|
+
]
|
89
|
+
].filter(Boolean)
|
90
|
+
}
|
91
|
+
}
|