rails_performance 1.6.0 → 1.7.0.beta1
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/README.md +9 -3
- data/app/controllers/rails_performance/rails_performance_controller.rb +15 -4
- data/app/engine_assets/javascripts/charts.js +3 -3
- data/app/engine_assets/stylesheets/style.css +12 -0
- data/app/helpers/rails_performance/rails_performance_helper.rb +3 -1
- data/app/views/rails_performance/layouts/rails_performance.html.erb +56 -55
- data/app/views/rails_performance/rails_performance/_card.html.erb +8 -0
- data/app/views/rails_performance/rails_performance/_chart.html.erb +9 -0
- data/app/views/rails_performance/rails_performance/index.html.erb +9 -54
- data/app/views/rails_performance/rails_performance/jobs.html.erb +69 -0
- data/app/views/rails_performance/shared/_header.html.erb +3 -0
- data/config/routes.rb +1 -0
- data/lib/generators/rails_performance/install/templates/initializer.rb +1 -1
- data/lib/rails_performance/data_source.rb +13 -1
- data/lib/rails_performance/engine.rb +5 -0
- data/lib/rails_performance/gems/active_job_ext.rb +42 -0
- data/lib/rails_performance/gems/sidekiq_ext.rb +3 -1
- data/lib/rails_performance/models/active_job_record.rb +60 -0
- data/lib/rails_performance/reports/base_report.rb +2 -1
- data/lib/rails_performance/reports/resources_report.rb +1 -1
- data/lib/rails_performance/system_monitor/resources_monitor.rb +2 -4
- data/lib/rails_performance/version.rb +1 -1
- data/lib/rails_performance/widgets/base.rb +15 -0
- data/lib/rails_performance/widgets/card.rb +17 -0
- data/lib/rails_performance/widgets/chart.rb +37 -0
- data/lib/rails_performance/widgets/percentile_card.rb +21 -0
- data/lib/rails_performance/{system_monitor → widgets}/resource_chart.rb +13 -2
- data/lib/rails_performance/widgets/response_time_chart.rb +29 -0
- data/lib/rails_performance/widgets/throughput_chart.rb +33 -0
- data/lib/rails_performance.rb +17 -2
- metadata +13 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ba9c4e66c3715ddb38e423cc32ca0f20c2d9ce0dde5439e1126cd061e6e7b41d
|
|
4
|
+
data.tar.gz: 930d0a2f8a2a916cfea4e1330f7e4f5fe38f9afa651223e95ead8132a2900b67
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f608b9e9ad54d01c96ee82669df77b7d7cbeffb442c68ec80bc3163a8325c3f63183ebdcc8bdd710e093be056dc0a37a62322941a5f8e0eff30731507edb3ebc
|
|
7
|
+
data.tar.gz: 1087574e48fc087161d2ed3d1a7088fbe1f82d44c66f43d3ae6dd0e84ef52acc3f98de710cadcf3ca3dddd56e82a371b1375746eee0bd285900821c6ff4326df
|
data/README.md
CHANGED
|
@@ -36,6 +36,8 @@ It allows you to track:
|
|
|
36
36
|
- simple 500-crashes reports
|
|
37
37
|
- deployment events (or custom events)
|
|
38
38
|
- Sidekiq jobs
|
|
39
|
+
- SolidQueue jobs
|
|
40
|
+
- ActiveJob jobs
|
|
39
41
|
- Delayed Job jobs
|
|
40
42
|
- Grape API inside Rails app
|
|
41
43
|
- Rake tasks performance
|
|
@@ -69,7 +71,7 @@ RailsPerformance.setup do |config|
|
|
|
69
71
|
config.redis = Redis.new(url: ENV["REDIS_URL"].presence || "redis://127.0.0.1:6379/0") # or Redis::Namespace.new("rails-performance", redis: Redis.new), see below in README
|
|
70
72
|
config.duration = 4.hours
|
|
71
73
|
|
|
72
|
-
config.debug = false
|
|
74
|
+
config.debug = false
|
|
73
75
|
config.enabled = true
|
|
74
76
|
|
|
75
77
|
# configure Recent tab (time window and limit of requests)
|
|
@@ -310,8 +312,12 @@ Just clone the repo, setup dummy app (`rails db:migrate`).
|
|
|
310
312
|
|
|
311
313
|
After this:
|
|
312
314
|
|
|
313
|
-
- rails s
|
|
314
|
-
-
|
|
315
|
+
- `rails s`
|
|
316
|
+
- `cd test/dummy` and `bundle exec rails db:migrate:queue`
|
|
317
|
+
- `cd test/dummy` and `bundle exec bin/jobs` (if you want to test ActiveJob)
|
|
318
|
+
- `rake test`
|
|
319
|
+
|
|
320
|
+
If you need to start with solid queue `SOLID_QUEUE_IN_PUMA=true rails s`.
|
|
315
321
|
|
|
316
322
|
If you need quickly clear Redis data, you can use `rails runner 'RailsPerformance.redis.flushdb'`.
|
|
317
323
|
|
|
@@ -7,11 +7,14 @@ module RailsPerformance
|
|
|
7
7
|
if RailsPerformance.enabled
|
|
8
8
|
def index
|
|
9
9
|
@datasource = RailsPerformance::DataSource.new(**prepare_query(params), type: :requests)
|
|
10
|
-
db = @datasource.db
|
|
11
10
|
|
|
12
|
-
@
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
@widgets = RailsPerformance.dashboard_charts.map do |row|
|
|
12
|
+
if row.is_a?(Array)
|
|
13
|
+
row.map { |class_name| Widgets.const_get(class_name).new(@datasource) }
|
|
14
|
+
else
|
|
15
|
+
Widgets.const_get(row).new(@datasource)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
def resources
|
|
@@ -72,6 +75,14 @@ module RailsPerformance
|
|
|
72
75
|
end
|
|
73
76
|
end
|
|
74
77
|
|
|
78
|
+
def jobs
|
|
79
|
+
@datasource = RailsPerformance::DataSource.new(**prepare_query, type: :jobs)
|
|
80
|
+
db = @datasource.db
|
|
81
|
+
@throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
|
|
82
|
+
@response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
|
|
83
|
+
@recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
|
|
84
|
+
end
|
|
85
|
+
|
|
75
86
|
def recent
|
|
76
87
|
@datasource = RailsPerformance::DataSource.new(**prepare_query(params), type: :requests)
|
|
77
88
|
db = @datasource.db
|
|
@@ -43,7 +43,7 @@ class RailsPerformanceChart extends HTMLElement {
|
|
|
43
43
|
updateChart(newData) {
|
|
44
44
|
let incoming = newData;
|
|
45
45
|
if (this.type === 'Usage') {
|
|
46
|
-
const {
|
|
46
|
+
const { bytes } = calculateByteUnit(newData);
|
|
47
47
|
incoming = newData.map(([t, v]) => [t, typeof v === 'number' ? (v / bytes).toFixed(2) : null]);
|
|
48
48
|
}
|
|
49
49
|
this.chart.updateRollingWindow(incoming, { windowSizeMs: this.windowSizeMs });
|
|
@@ -51,9 +51,9 @@ class RailsPerformanceChart extends HTMLElement {
|
|
|
51
51
|
|
|
52
52
|
get windowSizeMs() {
|
|
53
53
|
if (this.type === 'TIR' || this.type === 'RT') {
|
|
54
|
-
return ms("4h")
|
|
54
|
+
return window.railsPerformanceDuration || ms("4h");
|
|
55
55
|
} else {
|
|
56
|
-
return ms("24h")
|
|
56
|
+
return ms("24h");
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -189,3 +189,15 @@ body.has-sticky-footer {
|
|
|
189
189
|
.apexcharts-tooltip {
|
|
190
190
|
background: yellow !important;
|
|
191
191
|
}
|
|
192
|
+
|
|
193
|
+
.row {
|
|
194
|
+
display: flex;
|
|
195
|
+
flex-wrap: wrap;
|
|
196
|
+
gap: 0.75rem;
|
|
197
|
+
margin-bottom: 0.75rem;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.row > .widget {
|
|
201
|
+
flex: 1;
|
|
202
|
+
min-width: 0;
|
|
203
|
+
}
|
|
@@ -71,7 +71,7 @@ module RailsPerformance
|
|
|
71
71
|
|
|
72
72
|
def status_tag(status)
|
|
73
73
|
klass = case status.to_s
|
|
74
|
-
when /error/
|
|
74
|
+
when /error/, /exception/
|
|
75
75
|
"tag is-danger"
|
|
76
76
|
when /^5/
|
|
77
77
|
"tag is-danger"
|
|
@@ -140,6 +140,8 @@ module RailsPerformance
|
|
|
140
140
|
"is-active" if controller_name == "rails_performance" && action_name == "rake"
|
|
141
141
|
when :custom
|
|
142
142
|
"is-active" if controller_name == "rails_performance" && action_name == "custom"
|
|
143
|
+
when :jobs
|
|
144
|
+
"is-active" if controller_name == "rails_performance" && action_name == "jobs"
|
|
143
145
|
end
|
|
144
146
|
end
|
|
145
147
|
end
|
|
@@ -1,55 +1,56 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html class="theme-light">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
-
<title>Rails Performance</title>
|
|
7
|
-
<%= csrf_meta_tags %>
|
|
8
|
-
<%= csp_meta_tag if ::Rails::VERSION::STRING.to_f >= 5.2 %>
|
|
9
|
-
|
|
10
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
|
11
|
-
<%= engine_stylesheet_link_tag "style" %>
|
|
12
|
-
<%= engine_stylesheet_link_tag "panel" %>
|
|
13
|
-
<%= engine_stylesheet_link_tag "responsive" %>
|
|
14
|
-
|
|
15
|
-
<link rel="shortcut icon" href="/favicon.ico">
|
|
16
|
-
|
|
17
|
-
<%= engine_javascript_importmap_tags "application", {
|
|
18
|
-
"@rails/ujs" => "https://cdn.jsdelivr.net/npm/@rails/ujs@7.1.3-4/+esm",
|
|
19
|
-
"jquery" => "https://cdn.jsdelivr.net/npm/jquery@3.7.1/+esm",
|
|
20
|
-
"apexcharts" => "https://cdn.jsdelivr.net/npm/apexcharts@3.45.0/+esm",
|
|
21
|
-
"ms" => "https://cdn.jsdelivr.net/npm/ms@2.1.3/+esm",
|
|
22
|
-
"stupid-table-plugin" => "https://cdn.jsdelivr.net/npm/stupid-table-plugin@1.1.3/+esm",
|
|
23
|
-
"idiomorph" => "https://cdn.jsdelivr.net/npm/idiomorph@0.7.4/+esm"
|
|
24
|
-
} %>
|
|
25
|
-
|
|
26
|
-
<script>
|
|
27
|
-
window.annotationsData = <%= raw RailsPerformance::Reports::AnnotationsReport.new.data.to_json %>;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<%=
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
</
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html class="theme-light">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Rails Performance</title>
|
|
7
|
+
<%= csrf_meta_tags %>
|
|
8
|
+
<%= csp_meta_tag if ::Rails::VERSION::STRING.to_f >= 5.2 %>
|
|
9
|
+
|
|
10
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
|
11
|
+
<%= engine_stylesheet_link_tag "style" %>
|
|
12
|
+
<%= engine_stylesheet_link_tag "panel" %>
|
|
13
|
+
<%= engine_stylesheet_link_tag "responsive" %>
|
|
14
|
+
|
|
15
|
+
<link rel="shortcut icon" href="/favicon.ico">
|
|
16
|
+
|
|
17
|
+
<%= engine_javascript_importmap_tags "application", {
|
|
18
|
+
"@rails/ujs" => "https://cdn.jsdelivr.net/npm/@rails/ujs@7.1.3-4/+esm",
|
|
19
|
+
"jquery" => "https://cdn.jsdelivr.net/npm/jquery@3.7.1/+esm",
|
|
20
|
+
"apexcharts" => "https://cdn.jsdelivr.net/npm/apexcharts@3.45.0/+esm",
|
|
21
|
+
"ms" => "https://cdn.jsdelivr.net/npm/ms@2.1.3/+esm",
|
|
22
|
+
"stupid-table-plugin" => "https://cdn.jsdelivr.net/npm/stupid-table-plugin@1.1.3/+esm",
|
|
23
|
+
"idiomorph" => "https://cdn.jsdelivr.net/npm/idiomorph@0.7.4/+esm"
|
|
24
|
+
} %>
|
|
25
|
+
|
|
26
|
+
<script>
|
|
27
|
+
window.annotationsData = <%= raw RailsPerformance::Reports::AnnotationsReport.new.data.to_json %>;
|
|
28
|
+
window.railsPerformanceDuration = <%= RailsPerformance.duration.to_i * 1000 %>;
|
|
29
|
+
</script>
|
|
30
|
+
</head>
|
|
31
|
+
|
|
32
|
+
<body class="has-sticky-footer">
|
|
33
|
+
<div class="loader-wrapper">
|
|
34
|
+
<div class="loader is-loading"></div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="main-content">
|
|
38
|
+
<section class="section">
|
|
39
|
+
<div class="container is-fluid is-size-7">
|
|
40
|
+
<%= render '/rails_performance/shared/header' %>
|
|
41
|
+
<%= yield %>
|
|
42
|
+
</div>
|
|
43
|
+
</section>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<footer class="footer footer-box">
|
|
47
|
+
<div class="container is-fluid is-size-7">
|
|
48
|
+
© Rails Performance <span class='red'><i class="fas fa-heart"></i></span>
|
|
49
|
+
<%= link_to 'https://github.com/igorkasyanchuk/rails_performance', 'https://github.com/igorkasyanchuk/rails_performance', target: '_blank' %>
|
|
50
|
+
<div class="is-pulled-right">v.<%= RailsPerformance::VERSION %></div>
|
|
51
|
+
</div>
|
|
52
|
+
</footer>
|
|
53
|
+
|
|
54
|
+
<%= render '/rails_performance/panel' %>
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="widget">
|
|
2
|
+
<div class="card">
|
|
3
|
+
<div class="card-content">
|
|
4
|
+
<h2 class="subtitle"><%= chart.subtitle %></h2>
|
|
5
|
+
<%= tag.rails_performance_chart(chart.data.to_json.html_safe, id: chart.id, type: chart.type, legend: chart.legend, units: chart.units, class: "chart") %>
|
|
6
|
+
<p class="content is-small"><%= chart.description %></p>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<title>Number of Requests to the Application</title>
|
|
2
|
-
|
|
3
|
-
<% unless @datasource.default? %>
|
|
4
|
-
<%#= link_to raw("← Back"), rails_performance_path, class: "back_link" %>
|
|
1
|
+
<title>Number of Requests to the Application</title>
|
|
2
|
+
|
|
3
|
+
<% unless @datasource.default? %>
|
|
4
|
+
<%#= link_to raw("← Back"), rails_performance_path, class: "back_link" %>
|
|
5
5
|
<% end %>
|
|
6
6
|
|
|
7
7
|
<div class="has-text-right mb-4">
|
|
@@ -12,53 +12,8 @@
|
|
|
12
12
|
</rails-performance-autoupdate>
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
<div class="
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<p class="content is-size-4">p50</p>
|
|
21
|
-
</div>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<div class="column">
|
|
26
|
-
<div class="card">
|
|
27
|
-
<div class="card-content">
|
|
28
|
-
<h2 class="subtitle is-size-1"><%= ms @percentile_report_data[:p95] %></h2>
|
|
29
|
-
<p class="content is-size-4">p95</p>
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
<div class="column">
|
|
35
|
-
<div class="card">
|
|
36
|
-
<div class="card-content">
|
|
37
|
-
<h2 class="subtitle is-size-1"><%= ms @percentile_report_data[:p99] %></h2>
|
|
38
|
-
<p class="content is-size-4">p99</p>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
|
|
44
|
-
<div class="card">
|
|
45
|
-
<div class="card-content">
|
|
46
|
-
<h2 class="subtitle">Throughput Report</h2>
|
|
47
|
-
<rails-performance-chart id="throughput_report_chart" type="TIR" legend="RPM" units="rpm" class="chart">
|
|
48
|
-
<%= raw @throughput_report_data.to_json %>
|
|
49
|
-
</rails-performance-chart>
|
|
50
|
-
<p class="content is-small">All requests (site visitors, search engines, bots, etc)</p>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
|
|
54
|
-
<br/>
|
|
55
|
-
|
|
56
|
-
<div class="card">
|
|
57
|
-
<div class="card-content">
|
|
58
|
-
<h2 class="subtitle">Average Response Time Report</h2>
|
|
59
|
-
<rails-performance-chart id="response_time_report_chart" type="RT" legend="Response Time" class="chart">
|
|
60
|
-
<%= raw @response_time_report_data.to_json %>
|
|
61
|
-
</rails-performance-chart>
|
|
62
|
-
<p class="content is-small">All requests (site visitors, search engines, bots, etc)</p>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
15
|
+
<% @widgets.each do |row| %>
|
|
16
|
+
<div class="row">
|
|
17
|
+
<%= render row %>
|
|
18
|
+
</div>
|
|
19
|
+
<% end %>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<title>ActiveJob</title>
|
|
2
|
+
|
|
3
|
+
<% unless @datasource.default? %>
|
|
4
|
+
<%#= link_to raw("← Back"), rails_performance_path, class: "back_link" %>
|
|
5
|
+
<% end %>
|
|
6
|
+
|
|
7
|
+
<div class="card">
|
|
8
|
+
<div class="card-content">
|
|
9
|
+
<h2 class="subtitle">ActiveJob Workers Throughput Report</h2>
|
|
10
|
+
<rails-performance-chart id="throughput_report_chart" type="TIR" legend="Jobs" units="jobs / minute" class="chart">
|
|
11
|
+
<%= raw @throughput_report_data.to_json %>
|
|
12
|
+
</rails-performance-chart>
|
|
13
|
+
<p class="content is-small">All active jobs in the application</p>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<br/>
|
|
18
|
+
|
|
19
|
+
<div class="card">
|
|
20
|
+
<div class="card-content">
|
|
21
|
+
<h2 class="subtitle">Average Execution Time</h2>
|
|
22
|
+
<rails-performance-chart id="response_time_report_chart" type="RT" legend="Response Time" class="chart">
|
|
23
|
+
<%= raw @response_time_report_data.to_json %>
|
|
24
|
+
</rails-performance-chart>
|
|
25
|
+
<p class="content is-small">All workers in the application</p>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<br/>
|
|
30
|
+
|
|
31
|
+
<div class="card">
|
|
32
|
+
<div class="card-content">
|
|
33
|
+
<h2 class="subtitle">Recent Jobs (last <%= RailsPerformance.recent_requests_time_window / 60 %> minutes)<h2>
|
|
34
|
+
|
|
35
|
+
<table class="table is-fullwidth is-hoverable is-narrow">
|
|
36
|
+
<thead>
|
|
37
|
+
<tr>
|
|
38
|
+
<th data-sort="string">Datetime</th>
|
|
39
|
+
<th data-sort="string">Job ID</th>
|
|
40
|
+
<th data-sort="string">Queue</th>
|
|
41
|
+
<th data-sort="string">Worker</th>
|
|
42
|
+
<th data-sort="string">Status</th>
|
|
43
|
+
<th data-sort="float">Duration</th>
|
|
44
|
+
</tr>
|
|
45
|
+
</thead>
|
|
46
|
+
<tbody>
|
|
47
|
+
<% if @recent_report_data.empty? %>
|
|
48
|
+
<tr>
|
|
49
|
+
<td colspan="10">Nothing to show here. Try to make a few requests in the main app.</td>
|
|
50
|
+
</tr>
|
|
51
|
+
<% end %>
|
|
52
|
+
<% @recent_report_data.each do |e| %>
|
|
53
|
+
<tr>
|
|
54
|
+
<td><%= format_datetime e[:datetime] %></td>
|
|
55
|
+
<td><%= e[:jid] %></td>
|
|
56
|
+
<td><%= e[:queue] %></td>
|
|
57
|
+
<td><%= e[:worker] %></td>
|
|
58
|
+
<td>
|
|
59
|
+
<%= status_tag e[:status] %>
|
|
60
|
+
</td>
|
|
61
|
+
<td class="nowrap">
|
|
62
|
+
<%= ms e[:duration], 1 %>
|
|
63
|
+
</td>
|
|
64
|
+
</tr>
|
|
65
|
+
<% end %>
|
|
66
|
+
</tbody>
|
|
67
|
+
</table>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
<% end %>
|
|
23
23
|
<%= link_to 'Slow Requests', rails_performance.rails_performance_slow_url, class: "navbar-item #{active?(:slow)}" %>
|
|
24
24
|
<%= link_to '500 Errors', rails_performance.rails_performance_crashes_url, class: "navbar-item #{active?(:crashes)}" %>
|
|
25
|
+
<% if defined?(::ActiveJob) %>
|
|
26
|
+
<%= link_to 'ActiveJob', rails_performance.rails_performance_jobs_url, class: "navbar-item #{active?(:jobs)}" %>
|
|
27
|
+
<% end %>
|
|
25
28
|
<% if defined?(Sidekiq) %>
|
|
26
29
|
<%= link_to 'Sidekiq', rails_performance.rails_performance_sidekiq_url, class: "navbar-item #{active?(:sidekiq)}" %>
|
|
27
30
|
<% end %>
|
data/config/routes.rb
CHANGED
|
@@ -15,6 +15,7 @@ RailsPerformance::Engine.routes.draw do
|
|
|
15
15
|
get "/rake" => "rails_performance#rake", :as => :rails_performance_rake
|
|
16
16
|
get "/custom" => "rails_performance#custom", :as => :rails_performance_custom
|
|
17
17
|
get "/resources" => "rails_performance#resources", :as => :rails_performance_resources
|
|
18
|
+
get "/jobs" => "rails_performance#jobs", :as => :rails_performance_jobs
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
Rails.application.routes.draw do
|
|
@@ -15,7 +15,7 @@ if defined?(RailsPerformance)
|
|
|
15
15
|
# config.slow_requests_limit = 500 # number of slow requests
|
|
16
16
|
config.slow_requests_threshold = 500 # ms
|
|
17
17
|
|
|
18
|
-
config.debug = false
|
|
18
|
+
config.debug = false
|
|
19
19
|
config.enabled = true
|
|
20
20
|
|
|
21
21
|
# default path where to mount gem
|
|
@@ -7,7 +7,8 @@ module RailsPerformance
|
|
|
7
7
|
grape: RailsPerformance::Models::GrapeRecord,
|
|
8
8
|
rake: RailsPerformance::Models::RakeRecord,
|
|
9
9
|
custom: RailsPerformance::Models::CustomRecord,
|
|
10
|
-
resources: RailsPerformance::Models::ResourceRecord
|
|
10
|
+
resources: RailsPerformance::Models::ResourceRecord,
|
|
11
|
+
jobs: RailsPerformance::Models::ActiveJobRecord
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
attr_reader :q, :klass, :type, :days
|
|
@@ -68,6 +69,8 @@ module RailsPerformance
|
|
|
68
69
|
"rake|*#{compile_rake_query}*|END|#{RailsPerformance::SCHEMA}"
|
|
69
70
|
when :custom
|
|
70
71
|
"custom|*#{compile_custom_query}*|END|#{RailsPerformance::SCHEMA}"
|
|
72
|
+
when :jobs
|
|
73
|
+
"active_job|*#{compile_active_job_query}*|END|#{RailsPerformance::SCHEMA}"
|
|
71
74
|
else
|
|
72
75
|
raise "wrong type: \"#{type}\" for datasource query builder"
|
|
73
76
|
end
|
|
@@ -94,6 +97,15 @@ module RailsPerformance
|
|
|
94
97
|
str.join("*")
|
|
95
98
|
end
|
|
96
99
|
|
|
100
|
+
def compile_active_job_query
|
|
101
|
+
str = []
|
|
102
|
+
str << "queue|#{q[:queue]}|" if q[:queue].present?
|
|
103
|
+
str << "worker|#{q[:worker]}|" if q[:worker].present?
|
|
104
|
+
str << "datetime|#{q[:on].strftime("%Y%m%d")}*|" if q[:on].present?
|
|
105
|
+
str << "status|#{q[:status]}|" if q[:status].present?
|
|
106
|
+
str.join("*")
|
|
107
|
+
end
|
|
108
|
+
|
|
97
109
|
def compile_resource_query
|
|
98
110
|
str = []
|
|
99
111
|
str << "server|#{q[:server]}|" if q[:server].present?
|
|
@@ -57,6 +57,11 @@ module RailsPerformance
|
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
if defined?(::ActiveJob)
|
|
61
|
+
require_relative "gems/active_job_ext"
|
|
62
|
+
RailsPerformance::Gems::ActiveJobExt.init
|
|
63
|
+
end
|
|
64
|
+
|
|
60
65
|
if defined?(::Grape)
|
|
61
66
|
require_relative "gems/grape_ext"
|
|
62
67
|
RailsPerformance::Gems::GrapeExt.init
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module RailsPerformance
|
|
2
|
+
module Gems
|
|
3
|
+
class ActiveJobExt
|
|
4
|
+
module AroundPerform
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
around_perform do |job, block|
|
|
9
|
+
now = RailsPerformance::Utils.time
|
|
10
|
+
exception = nil
|
|
11
|
+
record = RailsPerformance::Models::ActiveJobRecord.new(
|
|
12
|
+
worker: job.class.name,
|
|
13
|
+
queue: job.queue_name,
|
|
14
|
+
enqueued_ati: job.enqueued_at.to_i,
|
|
15
|
+
datetimei: job.scheduled_at.to_i,
|
|
16
|
+
jid: job.job_id,
|
|
17
|
+
start_timei: now.to_i,
|
|
18
|
+
datetime: now.strftime(RailsPerformance::FORMAT)
|
|
19
|
+
)
|
|
20
|
+
result = block.call
|
|
21
|
+
record.status = "success"
|
|
22
|
+
result
|
|
23
|
+
rescue Exception => ex # rubocop:disable Lint/RescueException
|
|
24
|
+
record.status = "exception"
|
|
25
|
+
record.message = ex.message
|
|
26
|
+
exception = ex
|
|
27
|
+
ensure
|
|
28
|
+
# store in ms instead of seconds
|
|
29
|
+
record.duration = (RailsPerformance::Utils.time - now) * 1000
|
|
30
|
+
record.save
|
|
31
|
+
CurrentRequest.cleanup
|
|
32
|
+
raise exception if exception
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.init
|
|
38
|
+
ActiveJob::Base.send :include, AroundPerform
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -6,6 +6,7 @@ module RailsPerformance
|
|
|
6
6
|
|
|
7
7
|
def call(worker, msg, queue)
|
|
8
8
|
now = RailsPerformance::Utils.time
|
|
9
|
+
exception = nil
|
|
9
10
|
record = RailsPerformance::Models::SidekiqRecord.new(
|
|
10
11
|
enqueued_ati: msg["enqueued_at"].to_i,
|
|
11
12
|
datetimei: msg["created_at"].to_i,
|
|
@@ -22,12 +23,13 @@ module RailsPerformance
|
|
|
22
23
|
rescue Exception => ex # rubocop:disable Lint/RescueException
|
|
23
24
|
record.status = "exception"
|
|
24
25
|
record.message = ex.message
|
|
25
|
-
|
|
26
|
+
exception = ex
|
|
26
27
|
ensure
|
|
27
28
|
# store in ms instead of seconds
|
|
28
29
|
record.duration = (RailsPerformance::Utils.time - now) * 1000
|
|
29
30
|
record.save
|
|
30
31
|
CurrentRequest.cleanup
|
|
32
|
+
raise exception if exception
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module RailsPerformance
|
|
2
|
+
module Models
|
|
3
|
+
class ActiveJobRecord < BaseRecord
|
|
4
|
+
attr_accessor :queue, :worker, :jid, :datetimei, :enqueued_ati, :datetime, :start_timei, :duration, :status, :message
|
|
5
|
+
|
|
6
|
+
# deserialize from redis
|
|
7
|
+
def self.from_db(key, value)
|
|
8
|
+
items = key.split("|")
|
|
9
|
+
|
|
10
|
+
ActiveJobRecord.new(
|
|
11
|
+
queue: items[2],
|
|
12
|
+
worker: items[4],
|
|
13
|
+
jid: items[6],
|
|
14
|
+
datetime: items[8],
|
|
15
|
+
datetimei: items[10],
|
|
16
|
+
enqueued_ati: items[12],
|
|
17
|
+
start_timei: items[14],
|
|
18
|
+
status: items[16],
|
|
19
|
+
json: value
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(queue:, worker:, jid:, datetime:, datetimei:, enqueued_ati:, start_timei:, duration: nil, status: nil, message: nil, json: "{}")
|
|
24
|
+
@queue = queue
|
|
25
|
+
@worker = worker
|
|
26
|
+
@jid = jid
|
|
27
|
+
@datetime = datetime
|
|
28
|
+
@datetimei = datetimei.to_i
|
|
29
|
+
@start_timei = start_timei
|
|
30
|
+
@enqueued_ati = enqueued_ati
|
|
31
|
+
@duration = duration
|
|
32
|
+
@status = status
|
|
33
|
+
@message = message
|
|
34
|
+
@json = json
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# For UI
|
|
38
|
+
def record_hash
|
|
39
|
+
{
|
|
40
|
+
worker: worker,
|
|
41
|
+
queue: queue,
|
|
42
|
+
jid: jid,
|
|
43
|
+
datetimei: datetimei,
|
|
44
|
+
datetime: RailsPerformance::Utils.from_datetimei(start_timei.to_i),
|
|
45
|
+
start_timei: start_timei,
|
|
46
|
+
duration: value["duration"],
|
|
47
|
+
message: value["message"],
|
|
48
|
+
status: status
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# serialize to redis
|
|
53
|
+
def save
|
|
54
|
+
key = "active_job|queue|#{queue}|worker|#{worker}|jid|#{jid}|datetime|#{datetime}|datetimei|#{datetimei}|enqueued_ati|#{enqueued_ati}|start_timei|#{start_timei}|status|#{status}|END|#{RailsPerformance::SCHEMA}"
|
|
55
|
+
value = {duration:, message:}
|
|
56
|
+
Utils.save_to_redis(key, value)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -64,7 +64,8 @@ module RailsPerformance
|
|
|
64
64
|
# ....
|
|
65
65
|
# }
|
|
66
66
|
def nil_data(duration = RailsPerformance.duration)
|
|
67
|
-
@
|
|
67
|
+
@nil_data_cache ||= {}
|
|
68
|
+
@nil_data_cache[duration] ||= begin
|
|
68
69
|
result = {}
|
|
69
70
|
now = RailsPerformance::Utils.kind_of_now
|
|
70
71
|
now = now.change(sec: 0, usec: 0)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require "rails_performance/system_monitor/resource_chart"
|
|
2
|
-
|
|
3
1
|
module RailsPerformance
|
|
4
2
|
module SystemMonitor
|
|
5
3
|
class ResourcesMonitor
|
|
@@ -49,7 +47,7 @@ module RailsPerformance
|
|
|
49
47
|
|
|
50
48
|
def monitors
|
|
51
49
|
@monitors ||= RailsPerformance.system_monitors.map do |class_name|
|
|
52
|
-
RailsPerformance::
|
|
50
|
+
RailsPerformance::Widgets.const_get(class_name).new(nil)
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
53
|
|
|
@@ -58,7 +56,7 @@ module RailsPerformance
|
|
|
58
56
|
end
|
|
59
57
|
|
|
60
58
|
def store_data(data)
|
|
61
|
-
|
|
59
|
+
RailsPerformance.log("Server: #{server_id}, Context: #{context}, Role: #{role}, data: #{data}")
|
|
62
60
|
|
|
63
61
|
now = RailsPerformance::Utils.kind_of_now
|
|
64
62
|
now = now.change(sec: 0, usec: 0)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module RailsPerformance
|
|
2
|
+
module Widgets
|
|
3
|
+
class Card < Base
|
|
4
|
+
def label
|
|
5
|
+
raise NotImplementedError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def value
|
|
9
|
+
raise NotImplementedError
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_partial_path
|
|
13
|
+
"rails_performance/rails_performance/card"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module RailsPerformance
|
|
2
|
+
module Widgets
|
|
3
|
+
class Chart < Base
|
|
4
|
+
def id
|
|
5
|
+
raise NotImplementedError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def type
|
|
9
|
+
raise NotImplementedError
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def subtitle
|
|
13
|
+
raise NotImplementedError
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def description
|
|
17
|
+
raise NotImplementedError
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def legend
|
|
21
|
+
raise NotImplementedError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def units
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def data
|
|
29
|
+
raise NotImplementedError
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_partial_path
|
|
33
|
+
"rails_performance/rails_performance/chart"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module RailsPerformance
|
|
2
|
+
module Widgets
|
|
3
|
+
class PercentileCard < Card
|
|
4
|
+
def value
|
|
5
|
+
Reports::PercentileReport.new(datasource.db).data[label.to_sym]
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class P50Card < PercentileCard
|
|
10
|
+
def label = "p50"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class P95Card < PercentileCard
|
|
14
|
+
def label = "p95"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class P99Card < PercentileCard
|
|
18
|
+
def label = "p99"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
module RailsPerformance
|
|
2
|
-
module
|
|
3
|
-
ResourceChart
|
|
2
|
+
module Widgets
|
|
3
|
+
class ResourceChart < Chart
|
|
4
|
+
attr_reader :server, :key, :type, :subtitle, :description, :legend
|
|
5
|
+
|
|
6
|
+
def initialize(server:, key:, type:, subtitle:, description:, legend:)
|
|
7
|
+
@server = server
|
|
8
|
+
@key = key
|
|
9
|
+
@type = type
|
|
10
|
+
@subtitle = subtitle
|
|
11
|
+
@description = description
|
|
12
|
+
@legend = legend
|
|
13
|
+
end
|
|
14
|
+
|
|
4
15
|
def id
|
|
5
16
|
[key, "report", server.key.parameterize].join("_")
|
|
6
17
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module RailsPerformance
|
|
2
|
+
module Widgets
|
|
3
|
+
class ResponseTimeChart < Chart
|
|
4
|
+
def id
|
|
5
|
+
"response_time_report_chart"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def type
|
|
9
|
+
"RT"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def subtitle
|
|
13
|
+
"Average Response Time Report"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def description
|
|
17
|
+
"All requests (site visitors, search engines, bots, etc)"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def legend
|
|
21
|
+
"Response Time"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def data
|
|
25
|
+
Reports::ResponseTimeReport.new(datasource.db).data
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module RailsPerformance
|
|
2
|
+
module Widgets
|
|
3
|
+
class ThroughputChart < Chart
|
|
4
|
+
def id
|
|
5
|
+
"throughput_report_chart"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def type
|
|
9
|
+
"TIR"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def subtitle
|
|
13
|
+
"Throughput Report"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def description
|
|
17
|
+
"All requests (site visitors, search engines, bots, etc)"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def legend
|
|
21
|
+
"RPM"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def units
|
|
25
|
+
"rpm"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def data
|
|
29
|
+
Reports::ThroughputReport.new(datasource.db).data
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/rails_performance.rb
CHANGED
|
@@ -13,6 +13,7 @@ require_relative "rails_performance/models/trace_record"
|
|
|
13
13
|
require_relative "rails_performance/models/rake_record"
|
|
14
14
|
require_relative "rails_performance/models/resource_record"
|
|
15
15
|
require_relative "rails_performance/models/custom_record"
|
|
16
|
+
require_relative "rails_performance/models/active_job_record"
|
|
16
17
|
require_relative "rails_performance/data_source"
|
|
17
18
|
require_relative "rails_performance/utils"
|
|
18
19
|
require_relative "rails_performance/reports/base_report"
|
|
@@ -28,6 +29,13 @@ require_relative "rails_performance/reports/percentile_report"
|
|
|
28
29
|
require_relative "rails_performance/reports/resources_report"
|
|
29
30
|
require_relative "rails_performance/reports/annotations_report"
|
|
30
31
|
require_relative "rails_performance/events/record"
|
|
32
|
+
require_relative "rails_performance/widgets/base"
|
|
33
|
+
require_relative "rails_performance/widgets/chart"
|
|
34
|
+
require_relative "rails_performance/widgets/card"
|
|
35
|
+
require_relative "rails_performance/widgets/throughput_chart"
|
|
36
|
+
require_relative "rails_performance/widgets/response_time_chart"
|
|
37
|
+
require_relative "rails_performance/widgets/percentile_card"
|
|
38
|
+
require_relative "rails_performance/widgets/resource_chart"
|
|
31
39
|
require_relative "rails_performance/extensions/trace"
|
|
32
40
|
require_relative "rails_performance/thread/current_request"
|
|
33
41
|
require_relative "rails_performance/interface"
|
|
@@ -139,6 +147,13 @@ module RailsPerformance
|
|
|
139
147
|
"DiskUsage"
|
|
140
148
|
]
|
|
141
149
|
|
|
150
|
+
mattr_accessor :dashboard_charts
|
|
151
|
+
@@dashboard_charts = [
|
|
152
|
+
["P50Card", "P95Card", "P99Card"],
|
|
153
|
+
"ThroughputChart",
|
|
154
|
+
"ResponseTimeChart"
|
|
155
|
+
]
|
|
156
|
+
|
|
142
157
|
# -- internal usage --
|
|
143
158
|
#
|
|
144
159
|
#
|
|
@@ -164,9 +179,9 @@ module RailsPerformance
|
|
|
164
179
|
return unless RailsPerformance.debug
|
|
165
180
|
|
|
166
181
|
if ::Rails.logger
|
|
167
|
-
|
|
182
|
+
puts(message) if ENV["DEV_LOGS"] == "true"
|
|
168
183
|
::Rails.logger.debug(message)
|
|
169
|
-
|
|
184
|
+
elsif ENV["DEV_LOGS"] == "true"
|
|
170
185
|
puts(message)
|
|
171
186
|
end
|
|
172
187
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_performance
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.7.0.beta1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Igor Kasyanchuk
|
|
@@ -317,6 +317,8 @@ files:
|
|
|
317
317
|
- app/helpers/rails_performance/rails_performance_helper.rb
|
|
318
318
|
- app/views/rails_performance/_panel.html.erb
|
|
319
319
|
- app/views/rails_performance/layouts/rails_performance.html.erb
|
|
320
|
+
- app/views/rails_performance/rails_performance/_card.html.erb
|
|
321
|
+
- app/views/rails_performance/rails_performance/_chart.html.erb
|
|
320
322
|
- app/views/rails_performance/rails_performance/_export.html.erb
|
|
321
323
|
- app/views/rails_performance/rails_performance/_recent_row.html.erb
|
|
322
324
|
- app/views/rails_performance/rails_performance/_summary.html.erb
|
|
@@ -326,6 +328,7 @@ files:
|
|
|
326
328
|
- app/views/rails_performance/rails_performance/delayed_job.html.erb
|
|
327
329
|
- app/views/rails_performance/rails_performance/grape.html.erb
|
|
328
330
|
- app/views/rails_performance/rails_performance/index.html.erb
|
|
331
|
+
- app/views/rails_performance/rails_performance/jobs.html.erb
|
|
329
332
|
- app/views/rails_performance/rails_performance/rake.html.erb
|
|
330
333
|
- app/views/rails_performance/rails_performance/recent.html.erb
|
|
331
334
|
- app/views/rails_performance/rails_performance/requests.html.erb
|
|
@@ -347,6 +350,7 @@ files:
|
|
|
347
350
|
- lib/rails_performance/engine_assets/helper.rb
|
|
348
351
|
- lib/rails_performance/events/record.rb
|
|
349
352
|
- lib/rails_performance/extensions/trace.rb
|
|
353
|
+
- lib/rails_performance/gems/active_job_ext.rb
|
|
350
354
|
- lib/rails_performance/gems/custom_ext.rb
|
|
351
355
|
- lib/rails_performance/gems/delayed_job_ext.rb
|
|
352
356
|
- lib/rails_performance/gems/grape_ext.rb
|
|
@@ -354,6 +358,7 @@ files:
|
|
|
354
358
|
- lib/rails_performance/gems/sidekiq_ext.rb
|
|
355
359
|
- lib/rails_performance/instrument/metrics_collector.rb
|
|
356
360
|
- lib/rails_performance/interface.rb
|
|
361
|
+
- lib/rails_performance/models/active_job_record.rb
|
|
357
362
|
- lib/rails_performance/models/base_record.rb
|
|
358
363
|
- lib/rails_performance/models/collection.rb
|
|
359
364
|
- lib/rails_performance/models/custom_record.rb
|
|
@@ -378,11 +383,17 @@ files:
|
|
|
378
383
|
- lib/rails_performance/reports/slow_requests_report.rb
|
|
379
384
|
- lib/rails_performance/reports/throughput_report.rb
|
|
380
385
|
- lib/rails_performance/reports/trace_report.rb
|
|
381
|
-
- lib/rails_performance/system_monitor/resource_chart.rb
|
|
382
386
|
- lib/rails_performance/system_monitor/resources_monitor.rb
|
|
383
387
|
- lib/rails_performance/thread/current_request.rb
|
|
384
388
|
- lib/rails_performance/utils.rb
|
|
385
389
|
- lib/rails_performance/version.rb
|
|
390
|
+
- lib/rails_performance/widgets/base.rb
|
|
391
|
+
- lib/rails_performance/widgets/card.rb
|
|
392
|
+
- lib/rails_performance/widgets/chart.rb
|
|
393
|
+
- lib/rails_performance/widgets/percentile_card.rb
|
|
394
|
+
- lib/rails_performance/widgets/resource_chart.rb
|
|
395
|
+
- lib/rails_performance/widgets/response_time_chart.rb
|
|
396
|
+
- lib/rails_performance/widgets/throughput_chart.rb
|
|
386
397
|
homepage: https://github.com/igorkasyanchuk/rails_performance
|
|
387
398
|
licenses:
|
|
388
399
|
- MIT
|