rails_performance 1.3.3 → 1.4.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -0
- data/app/controllers/rails_performance/rails_performance_controller.rb +8 -1
- data/app/helpers/rails_performance/rails_performance_helper.rb +2 -0
- data/app/views/rails_performance/javascripts/app.js +174 -7
- data/app/views/rails_performance/layouts/rails_performance.html.erb +1 -1
- data/app/views/rails_performance/rails_performance/resources.html.erb +50 -0
- data/app/views/rails_performance/shared/_header.html.erb +3 -0
- data/app/views/rails_performance/stylesheets/bulma.min.css +1 -1
- data/config/routes.rb +1 -0
- data/lib/rails_performance/data_source.rb +16 -3
- data/lib/rails_performance/engine.rb +28 -0
- data/lib/rails_performance/extensions/resources_monitor.rb +103 -0
- data/lib/rails_performance/models/resource_record.rb +47 -0
- data/lib/rails_performance/reports/base_report.rb +35 -2
- data/lib/rails_performance/reports/resources_report.rb +44 -0
- data/lib/rails_performance/version.rb +1 -1
- data/lib/rails_performance.rb +13 -0
- metadata +49 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 524031a11cbbe218cd746b2469a34b05e0867fa33f2f87dc06377a9a6ee983da
|
4
|
+
data.tar.gz: 69ea547a8574ed29550d28057d6d7369f8598509104fdcad002408be71533af6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0122738b6f1fde35c2bca00783e26e1c0f65b84896b4e22130e79dfffd2e59d211d7aec34f9b9b7718c239a713993e8d05656bc87294e253d7695462b9f477ea'
|
7
|
+
data.tar.gz: 5170e8f7e24ce9a9904bf7d9163dbf34eca2063da745fb9824f808793a12e9940b618b5b64ebe8f2fe39e6e12bebcc98f560c9fdd3fd51fb6fc973f880417a8e
|
data/README.md
CHANGED
@@ -10,9 +10,19 @@ This is a **simple and free alternative** to the New Relic APM, Datadog or other
|
|
10
10
|
|
11
11
|
![Demo](docs/rails_performance.gif)
|
12
12
|
|
13
|
+
A new version with P50, P90, P99, throughput, and more is available.
|
14
|
+
|
15
|
+
![Home](docs/rails_performance_updated_home.png)
|
16
|
+
|
17
|
+
Detailed p50, p90, p99 response time information.
|
18
|
+
|
19
|
+
![Home](docs/rails_performance_recent_requests.png)
|
20
|
+
|
13
21
|
It allows you to track:
|
14
22
|
|
15
23
|
- real-time monitoring on the Recent tab
|
24
|
+
- see your p50, p90, p99 response time
|
25
|
+
- monitor system resources (CPU, memory, disk)
|
16
26
|
- monitor slow requests
|
17
27
|
- throughput report (see amount of RPM (requests per minute))
|
18
28
|
- an average response time
|
@@ -165,6 +175,16 @@ You need to configure `config.custom_data_proc`. And you can capture current_use
|
|
165
175
|
![Custom Data](docs/custom_data.png)
|
166
176
|
|
167
177
|
|
178
|
+
### System Monitoring
|
179
|
+
|
180
|
+
You can monitor system resources (CPU, memory, disk) by adding a gem to your Gemfile:
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
gem "sys-filesystem"
|
184
|
+
gem "sys-cpu"
|
185
|
+
gem "get_process_mem"
|
186
|
+
```
|
187
|
+
|
168
188
|
### Custom events
|
169
189
|
|
170
190
|
```ruby
|
@@ -175,6 +195,8 @@ end
|
|
175
195
|
|
176
196
|
## Using with Rails Namespace
|
177
197
|
|
198
|
+
If you want to use Redis namespace (for example when you have multiple apps running on the same server), you can configure it like this:
|
199
|
+
|
178
200
|
```ruby
|
179
201
|
config.redis = Redis::Namespace.new("#{Rails.env}-rails-performance", redis: Redis.new(url: ENV["REDIS_URL"].presence || "redis://127.0.0.1:6379/0"))
|
180
202
|
```
|
@@ -14,6 +14,13 @@ module RailsPerformance
|
|
14
14
|
@percentile_report_data = RailsPerformance::Reports::PercentileReport.new(db).data
|
15
15
|
end
|
16
16
|
|
17
|
+
def resources
|
18
|
+
@datasource = RailsPerformance::DataSource.new(**prepare_query(params), type: :resources)
|
19
|
+
db = @datasource.db
|
20
|
+
|
21
|
+
@resources_report = RailsPerformance::Reports::ResourcesReport.new(db)
|
22
|
+
end
|
23
|
+
|
17
24
|
def summary
|
18
25
|
@datasource = RailsPerformance::DataSource.new(**prepare_query(params), type: :requests)
|
19
26
|
db = @datasource.db
|
@@ -151,7 +158,7 @@ module RailsPerformance
|
|
151
158
|
|
152
159
|
private
|
153
160
|
|
154
|
-
def prepare_query(query)
|
161
|
+
def prepare_query(query = {})
|
155
162
|
RailsPerformance::Rails::QueryBuilder.compose_from(query)
|
156
163
|
end
|
157
164
|
end
|
@@ -132,6 +132,8 @@ module RailsPerformance
|
|
132
132
|
"is-active" if controller_name == "rails_performance" && action_name == "crashes"
|
133
133
|
when :requests
|
134
134
|
"is-active" if controller_name == "rails_performance" && action_name == "requests"
|
135
|
+
when :resources
|
136
|
+
"is-active" if controller_name == "rails_performance" && action_name == "resources"
|
135
137
|
when :recent
|
136
138
|
"is-active" if controller_name == "rails_performance" && action_name == "recent"
|
137
139
|
when :slow
|
@@ -1,8 +1,5 @@
|
|
1
1
|
function showTIRChart(div, data, addon, name) {
|
2
2
|
Highcharts.chart(div, {
|
3
|
-
// time: {
|
4
|
-
// timezone: 'Europe/Kiev'
|
5
|
-
// },
|
6
3
|
chart: {
|
7
4
|
type: 'area',
|
8
5
|
zoomType: 'x',
|
@@ -22,7 +19,7 @@ function showTIRChart(div, data, addon, name) {
|
|
22
19
|
},
|
23
20
|
formatter: function() {
|
24
21
|
if (this.y == 0) {
|
25
|
-
return false;
|
22
|
+
return false;
|
26
23
|
}
|
27
24
|
return this.y + addon;
|
28
25
|
}
|
@@ -84,9 +81,6 @@ function showTIRChart(div, data, addon, name) {
|
|
84
81
|
|
85
82
|
function showRTChart(div, data) {
|
86
83
|
Highcharts.chart(div, {
|
87
|
-
// time: {
|
88
|
-
// timezone: 'Europe/Kiev'
|
89
|
-
// },
|
90
84
|
chart: {
|
91
85
|
type: 'area',
|
92
86
|
zoomType: 'x',
|
@@ -167,6 +161,179 @@ function showRTChart(div, data) {
|
|
167
161
|
});
|
168
162
|
};
|
169
163
|
|
164
|
+
function showPercentageChart(div, data, addon, name) {
|
165
|
+
Highcharts.chart(div, {
|
166
|
+
chart: {
|
167
|
+
type: 'line',
|
168
|
+
zoomType: 'x',
|
169
|
+
},
|
170
|
+
title: {
|
171
|
+
text: ''
|
172
|
+
},
|
173
|
+
tooltip: {
|
174
|
+
borderWidth: 0,
|
175
|
+
backgroundColor: 'yellow',
|
176
|
+
pointFormat: '{point.y}',
|
177
|
+
//headerFormat: '',
|
178
|
+
shadow: false,
|
179
|
+
style: {
|
180
|
+
fontSize: '16px',
|
181
|
+
color: '#000',
|
182
|
+
},
|
183
|
+
formatter: function() {
|
184
|
+
if (this.y == 0) {
|
185
|
+
return false;
|
186
|
+
}
|
187
|
+
return this.y + ' %';
|
188
|
+
}
|
189
|
+
},
|
190
|
+
xAxis: {
|
191
|
+
crosshair: true,
|
192
|
+
type: 'datetime',
|
193
|
+
labels: {
|
194
|
+
style: {
|
195
|
+
color: "#a6b0cf"
|
196
|
+
}
|
197
|
+
}
|
198
|
+
},
|
199
|
+
yAxis: {
|
200
|
+
min: 0,
|
201
|
+
title: {
|
202
|
+
text: '%',
|
203
|
+
style: {
|
204
|
+
color: "#f6f6f6"
|
205
|
+
}
|
206
|
+
},
|
207
|
+
labels: {
|
208
|
+
style: {
|
209
|
+
color: "#a6b0cf"
|
210
|
+
}
|
211
|
+
}
|
212
|
+
},
|
213
|
+
legend: {
|
214
|
+
enabled: false
|
215
|
+
},
|
216
|
+
exporting: {
|
217
|
+
buttons: {
|
218
|
+
contextButton: {
|
219
|
+
theme: {
|
220
|
+
fill: "#eee"
|
221
|
+
}
|
222
|
+
}
|
223
|
+
}
|
224
|
+
},
|
225
|
+
plotOptions: {
|
226
|
+
area: {
|
227
|
+
color: '#ff5b5b',
|
228
|
+
}
|
229
|
+
},
|
230
|
+
series: [{
|
231
|
+
type: 'line',
|
232
|
+
name: name,
|
233
|
+
data: data,
|
234
|
+
fillOpacity: 0.3,
|
235
|
+
lineWidth: 1,
|
236
|
+
states: {
|
237
|
+
hover: {
|
238
|
+
lineWidth: 2
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}]
|
242
|
+
});
|
243
|
+
};
|
244
|
+
|
245
|
+
|
246
|
+
function showUsageChart(div, data, addon, name) {
|
247
|
+
Highcharts.chart(div, {
|
248
|
+
chart: {
|
249
|
+
type: 'line',
|
250
|
+
zoomType: 'x',
|
251
|
+
},
|
252
|
+
title: {
|
253
|
+
text: ''
|
254
|
+
},
|
255
|
+
tooltip: {
|
256
|
+
borderWidth: 0,
|
257
|
+
backgroundColor: 'yellow',
|
258
|
+
pointFormat: '{point.y}',
|
259
|
+
//headerFormat: '',
|
260
|
+
shadow: false,
|
261
|
+
style: {
|
262
|
+
fontSize: '16px',
|
263
|
+
color: '#000',
|
264
|
+
},
|
265
|
+
formatter: function() {
|
266
|
+
if (this.y == 0) {
|
267
|
+
return false;
|
268
|
+
}
|
269
|
+
return bytes(this.y, true);
|
270
|
+
}
|
271
|
+
},
|
272
|
+
xAxis: {
|
273
|
+
crosshair: true,
|
274
|
+
type: 'datetime',
|
275
|
+
labels: {
|
276
|
+
style: {
|
277
|
+
color: "#a6b0cf"
|
278
|
+
}
|
279
|
+
}
|
280
|
+
},
|
281
|
+
yAxis: {
|
282
|
+
min: 0,
|
283
|
+
title: {
|
284
|
+
text: '',
|
285
|
+
style: {
|
286
|
+
color: "#f6f6f6"
|
287
|
+
}
|
288
|
+
},
|
289
|
+
labels: {
|
290
|
+
style: {
|
291
|
+
color: "#a6b0cf"
|
292
|
+
}
|
293
|
+
}
|
294
|
+
},
|
295
|
+
legend: {
|
296
|
+
enabled: false
|
297
|
+
},
|
298
|
+
exporting: {
|
299
|
+
buttons: {
|
300
|
+
contextButton: {
|
301
|
+
theme: {
|
302
|
+
fill: "#eee"
|
303
|
+
}
|
304
|
+
}
|
305
|
+
}
|
306
|
+
},
|
307
|
+
plotOptions: {
|
308
|
+
area: {
|
309
|
+
color: '#ff5b5b',
|
310
|
+
}
|
311
|
+
},
|
312
|
+
series: [{
|
313
|
+
type: 'line',
|
314
|
+
name: name,
|
315
|
+
data: data,
|
316
|
+
fillOpacity: 0.3,
|
317
|
+
lineWidth: 1,
|
318
|
+
states: {
|
319
|
+
hover: {
|
320
|
+
lineWidth: 2
|
321
|
+
}
|
322
|
+
}
|
323
|
+
}]
|
324
|
+
});
|
325
|
+
};
|
326
|
+
|
327
|
+
function bytes(bytes, label) {
|
328
|
+
if (bytes == 0) return '';
|
329
|
+
var s = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
330
|
+
var e = Math.floor(Math.log(bytes)/Math.log(1024));
|
331
|
+
var value = ((bytes/Math.pow(1024, Math.floor(e))).toFixed(2));
|
332
|
+
e = (e<0) ? (-e) : e;
|
333
|
+
if (label) value += ' ' + s[e];
|
334
|
+
return value;
|
335
|
+
}
|
336
|
+
|
170
337
|
const recent = document.getElementById("recent")
|
171
338
|
const autoupdate = document.getElementById("autoupdate")
|
172
339
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<title>System Resources</title>
|
2
|
+
|
3
|
+
<% @resources_report.data.keys.each do |server_key| %>
|
4
|
+
<h1 class="title mt-8 pt-8"><%= server_key.split("///"). join(", ") %></h1>
|
5
|
+
|
6
|
+
<div class="card">
|
7
|
+
<div class="card-content">
|
8
|
+
<h2 class="subtitle">CPU</h2>
|
9
|
+
<div id="cpu_report_<%= server_key.parameterize %>" class="chart"></div>
|
10
|
+
<p class="content is-small">CPU usage %, average per 1 minute</p>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<br/>
|
15
|
+
|
16
|
+
<div class="card">
|
17
|
+
<div class="card-content">
|
18
|
+
<h2 class="subtitle">Memory</h2>
|
19
|
+
<div id="memory_report_<%= server_key.parameterize %>" class="chart"></div>
|
20
|
+
<p class="content is-small">App memory usage</p>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<br/>
|
25
|
+
|
26
|
+
<div class="card">
|
27
|
+
<div class="card-content">
|
28
|
+
<h2 class="subtitle">Disk</h2>
|
29
|
+
<div id="disk_report_<%= server_key.parameterize %>" class="chart"></div>
|
30
|
+
<p class="content is-small">Available disk size</p>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<br>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<% content_for :on_load do %>
|
38
|
+
<script>
|
39
|
+
<% @resources_report.data.keys.each do |server_key| %>
|
40
|
+
var data1 = <%= raw @resources_report.cpu[server_key].to_json %>;
|
41
|
+
showPercentageChart('cpu_report_<%= server_key.parameterize %>', data1, ' %', '%');
|
42
|
+
|
43
|
+
var data2 = <%= raw @resources_report.memory[server_key].to_json %>;
|
44
|
+
showUsageChart('memory_report_<%= server_key.parameterize %>', data2, ' Mb', 'Mb');
|
45
|
+
|
46
|
+
var data3 = <%= raw @resources_report.disk[server_key].to_json %>;
|
47
|
+
showUsageChart('disk_report_<%= server_key.parameterize %>', data3, ' Gb', 'Gb');
|
48
|
+
<% end %>
|
49
|
+
</script>
|
50
|
+
<% end %>
|
@@ -17,6 +17,9 @@
|
|
17
17
|
<%= link_to 'Dashboard', rails_performance.rails_performance_url, class: "navbar-item #{active?(:dashboard)}" %>
|
18
18
|
<%= link_to 'Requests Analysis', rails_performance.rails_performance_requests_url, class: "navbar-item #{active?(:requests)}" %>
|
19
19
|
<%= link_to 'Recent Requests', rails_performance.rails_performance_recent_url, class: "navbar-item #{active?(:recent)}" %>
|
20
|
+
<% if RailsPerformance._resource_monitor_enabled %>
|
21
|
+
<%= link_to 'System', rails_performance.rails_performance_resources_url, class: "navbar-item #{active?(:resources)}" %>
|
22
|
+
<% end %>
|
20
23
|
<%= link_to 'Slow Requests', rails_performance.rails_performance_slow_url, class: "navbar-item #{active?(:slow)}" %>
|
21
24
|
<%= link_to '500 Errors', rails_performance.rails_performance_crashes_url, class: "navbar-item #{active?(:crashes)}" %>
|
22
25
|
<% if defined?(Sidekiq) %>
|