rails_performance 0.0.1.6 → 0.0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/rails_performance_controller.rb +10 -3
- data/app/helpers/rails_performance_helper.rb +19 -0
- data/app/views/javascripts/app.js +31 -11
- data/app/views/rails_performance/_crash_report.html.erb +41 -0
- data/app/views/rails_performance/breakdown.html.erb +17 -9
- data/app/views/rails_performance/index.html.erb +18 -10
- data/lib/rails_performance.rb +6 -3
- data/lib/rails_performance/data_source.rb +2 -2
- data/lib/rails_performance/engine.rb +4 -4
- data/lib/rails_performance/instrument/metrics_collector.rb +39 -0
- data/lib/rails_performance/models/record.rb +1 -1
- data/lib/rails_performance/rails/middleware.rb +34 -0
- data/lib/rails_performance/rails/query_builder.rb +20 -0
- data/lib/rails_performance/reports/crash_report.rb +28 -0
- data/lib/rails_performance/reports/response_time_report.rb +1 -1
- data/lib/rails_performance/reports/throughput_report.rb +1 -1
- data/lib/rails_performance/version.rb +1 -1
- metadata +7 -5
- data/lib/rails_performance/metrics_collector.rb +0 -40
- data/lib/rails_performance/middleware.rb +0 -32
- data/lib/rails_performance/query_builder.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad863c06b721b0cc4310bc0ed47ea24260d1d4506b84ff77dc89884efe039407
|
4
|
+
data.tar.gz: 4cd6dfae47e6331e1c0094566f9777e65b8eaec9eaf4b4defdbc0e26e0b8a758
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9199bca9141f1e8a9753b71cd517f592ab611ae8b00bf2b41bb7f4585b2189661f9ebcead00614483e0878b2cc6c87569edc978efa252f9a27767d87ef169adf
|
7
|
+
data.tar.gz: 40cacc58ffbbe33da582912aee967ab64cf71f527ce5bcc60d684d84787f21c967e2ce4e6ddbba33580c544a275776a09ed8e166dce41b833958432544c5f524
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class RailsPerformanceController < ActionController::Base
|
2
2
|
|
3
3
|
def index
|
4
|
-
@datasource
|
5
|
-
db
|
4
|
+
@datasource = RP::DataSource.new(RP::Rails::QueryBuilder.compose_from(params))
|
5
|
+
db = @datasource.db
|
6
6
|
|
7
7
|
@throughput_report = RP::Reports::ThroughputReport.new(db)
|
8
8
|
@throughput_report_data = @throughput_report.data
|
@@ -12,10 +12,17 @@ class RailsPerformanceController < ActionController::Base
|
|
12
12
|
|
13
13
|
@global_report = RP::Reports::RequestsReport.new(db, group: :controller_action_format, sort: :db_runtime_slowest)
|
14
14
|
@global_report_data = @global_report.data
|
15
|
+
|
16
|
+
@crash_ds = RP::DataSource.new(RP::Rails::QueryBuilder.compose_from({status_eq: 500}))
|
17
|
+
crash_db = @crash_ds.db
|
18
|
+
@crash_report = RP::Reports::CrashReport.new(crash_db)
|
19
|
+
@crash_report_data = @crash_report.data
|
20
|
+
|
21
|
+
# binding.pry
|
15
22
|
end
|
16
23
|
|
17
24
|
def breakdown
|
18
|
-
@datasource = RP::DataSource.new(RP::QueryBuilder.compose_from(params))
|
25
|
+
@datasource = RP::DataSource.new(RP::Rails::QueryBuilder.compose_from(params))
|
19
26
|
db = @datasource.db
|
20
27
|
|
21
28
|
@breakdown_report = RP::Reports::BreakdownReport.new(db, title: "Breakdown Report: #{@datasource.q.to_param}")
|
@@ -23,7 +23,26 @@ module RailsPerformanceHelper
|
|
23
23
|
link_to title, rails_performance_path(options), target: '_blank'
|
24
24
|
end
|
25
25
|
|
26
|
+
def status_tag(status)
|
27
|
+
klass = case status.to_s
|
28
|
+
when /^5/
|
29
|
+
"tag is-danger"
|
30
|
+
when /^4/
|
31
|
+
"tag is-warning"
|
32
|
+
when /^3/
|
33
|
+
"tag is-info"
|
34
|
+
when /^2/
|
35
|
+
"tag is-success"
|
36
|
+
else
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
content_tag(:span, class: klass) do
|
40
|
+
status
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
26
44
|
def stats_icon
|
45
|
+
# https://www.iconfinder.com/iconsets/vivid
|
27
46
|
'<?xml version="1.0" ?><svg height="48" id="graph-bar" viewBox="0 0 48 48" width="48" xmlns="http://www.w3.org/2000/svg"><defs><style> .vi-primary { fill: #FF6E6E; } .vi-primary, .vi-accent { stroke: #fff; stroke-linecap: round; stroke-width: 0; } .vi-accent { fill: #0C0058; } </style></defs><rect class="vi-accent" height="4" width="36" x="6" y="35"/><path class="vi-primary" d="M9,20h5V35H9V20Zm8,5h5V35H17V25Zm8-9h5V35H25V16Zm8-7h5V35H33V9Z"/></svg>'
|
28
47
|
end
|
29
48
|
|
@@ -10,6 +10,23 @@ function showTIRChart(div, data) {
|
|
10
10
|
title: {
|
11
11
|
text: ''
|
12
12
|
},
|
13
|
+
tooltip: {
|
14
|
+
borderWidth: 0,
|
15
|
+
backgroundColor: 'yellow',
|
16
|
+
pointFormat: '{point.y}',
|
17
|
+
//headerFormat: '',
|
18
|
+
shadow: false,
|
19
|
+
style: {
|
20
|
+
fontSize: '16px',
|
21
|
+
color: '#000',
|
22
|
+
},
|
23
|
+
formatter: function() {
|
24
|
+
if (this.y == 0) {
|
25
|
+
return "";
|
26
|
+
}
|
27
|
+
return this.y + ' rpm';
|
28
|
+
}
|
29
|
+
},
|
13
30
|
xAxis: {
|
14
31
|
crosshair: true,
|
15
32
|
type: 'datetime',
|
@@ -52,10 +69,15 @@ function showTIRChart(div, data) {
|
|
52
69
|
},
|
53
70
|
series: [{
|
54
71
|
type: 'area',
|
55
|
-
name: '
|
72
|
+
name: 'RPM',
|
56
73
|
data: data,
|
57
74
|
fillOpacity: 0.3,
|
58
|
-
lineWidth: 1
|
75
|
+
lineWidth: 1,
|
76
|
+
states: {
|
77
|
+
hover: {
|
78
|
+
lineWidth: 1
|
79
|
+
}
|
80
|
+
}
|
59
81
|
}]
|
60
82
|
});
|
61
83
|
};
|
@@ -74,15 +96,8 @@ function showRTChart(div, data) {
|
|
74
96
|
},
|
75
97
|
|
76
98
|
tooltip: {
|
77
|
-
// positioner: function () {
|
78
|
-
// return {
|
79
|
-
// // right aligned
|
80
|
-
// x: this.chart.chartWidth - this.label.width - 30,
|
81
|
-
// y: 5 // align to title
|
82
|
-
// };
|
83
|
-
// },
|
84
99
|
borderWidth: 0,
|
85
|
-
backgroundColor: '
|
100
|
+
backgroundColor: 'yellow',
|
86
101
|
pointFormat: '{point.y}',
|
87
102
|
//headerFormat: '',
|
88
103
|
shadow: false,
|
@@ -142,7 +157,12 @@ function showRTChart(div, data) {
|
|
142
157
|
name: 'Response Time',
|
143
158
|
data: data,
|
144
159
|
fillOpacity: 0.3,
|
145
|
-
lineWidth: 1
|
160
|
+
lineWidth: 1,
|
161
|
+
states: {
|
162
|
+
hover: {
|
163
|
+
lineWidth: 1
|
164
|
+
}
|
165
|
+
}
|
146
166
|
}]
|
147
167
|
});
|
148
168
|
};
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<div class="card">
|
2
|
+
<div class="card-content">
|
3
|
+
<h2 class="title">Crash Report<h1>
|
4
|
+
<table class="table is-fullwidth is-hoverable is-narrow">
|
5
|
+
<thead>
|
6
|
+
<tr>
|
7
|
+
<th>Datetime</th>
|
8
|
+
<th>Controller#Action</th>
|
9
|
+
<th>Format</th>
|
10
|
+
<th>Method</th>
|
11
|
+
<th>Path</th>
|
12
|
+
<th>Status</th>
|
13
|
+
<th>Duration</th>
|
14
|
+
<th>Views</th>
|
15
|
+
<th>DB</th>
|
16
|
+
</tr>
|
17
|
+
</thead>
|
18
|
+
<tbody>
|
19
|
+
<% @crash_report_data.each do |e| %>
|
20
|
+
<tr>
|
21
|
+
<td><%= l e[:datetime], format: :short %></td>
|
22
|
+
<td><%= e[:controller] + '#' + e[:action] %></td>
|
23
|
+
<td><%= e[:format] %></td>
|
24
|
+
<td><%= e[:method] %></td>
|
25
|
+
<td>
|
26
|
+
<% if e[:method] == 'GET' %>
|
27
|
+
<%= link_to e[:path], e[:path], target: '_blank' %>
|
28
|
+
<% else %>
|
29
|
+
<%= e[:path] %>
|
30
|
+
<% end %>
|
31
|
+
</td>
|
32
|
+
<td><%= status_tag e[:status] %></td>
|
33
|
+
<td><%= round_it e[:duration] %> ms</td>
|
34
|
+
<td><%= round_it e[:view_runtime] %> ms</td>
|
35
|
+
<td><%= round_it e[:db_runtime] %> ms</td>
|
36
|
+
</tr>
|
37
|
+
<% end %>
|
38
|
+
</tbody>
|
39
|
+
</table>
|
40
|
+
</div>
|
41
|
+
</div>
|
@@ -3,30 +3,38 @@
|
|
3
3
|
<div class="card">
|
4
4
|
<div class="card-content">
|
5
5
|
<h1 class="title"><%= @breakdown_report.title %><h1>
|
6
|
-
<table class="table is-fullwidth">
|
6
|
+
<table class="table is-fullwidth is-hoverable is-narrow">
|
7
7
|
<thead>
|
8
8
|
<tr>
|
9
|
-
<th>
|
10
|
-
<th>
|
9
|
+
<th>Datetime</th>
|
10
|
+
<th>Controller#Action</th>
|
11
11
|
<th>Method</th>
|
12
|
+
<th>Path</th>
|
12
13
|
<th>Format</th>
|
14
|
+
<th>Status</th>
|
13
15
|
<th>Duration</th>
|
14
16
|
<th>Views</th>
|
15
17
|
<th>DB</th>
|
16
|
-
<th>Datetime</th>
|
17
18
|
</tr>
|
18
19
|
</thead>
|
19
20
|
<tbody>
|
20
21
|
<% @breakdown_report_data.each do |e| %>
|
21
22
|
<tr>
|
23
|
+
<td><%= l e[:datetime], format: :short %></td>
|
22
24
|
<td><%= e[:controller] + '#' + e[:action] %></td>
|
23
|
-
<td><%= e[:path] %></td>
|
24
25
|
<td><%= e[:method] %></td>
|
26
|
+
<td>
|
27
|
+
<% if e[:method] == 'GET' %>
|
28
|
+
<%= link_to e[:path], e[:path], target: '_blank' %>
|
29
|
+
<% else %>
|
30
|
+
<%= e[:path] %>
|
31
|
+
<% end %>
|
32
|
+
</td>
|
25
33
|
<td><%= e[:format] %></td>
|
26
|
-
<td><%=
|
27
|
-
<td><%= round_it e[:
|
28
|
-
<td><%= round_it e[:
|
29
|
-
<td><%=
|
34
|
+
<td><%= status_tag e[:status] %></td>
|
35
|
+
<td><%= round_it e[:duration] %> ms</td>
|
36
|
+
<td><%= round_it e[:view_runtime] %> ms</td>
|
37
|
+
<td><%= round_it e[:db_runtime] %> ms</td>
|
30
38
|
</tr>
|
31
39
|
<% end %>
|
32
40
|
</tbody>
|
@@ -12,6 +12,8 @@
|
|
12
12
|
</div>
|
13
13
|
</div>
|
14
14
|
|
15
|
+
<br/>
|
16
|
+
|
15
17
|
<div class="card">
|
16
18
|
<div class="card-content">
|
17
19
|
<h2 class="title">Average Response Time Report<h1>
|
@@ -20,15 +22,17 @@
|
|
20
22
|
</div>
|
21
23
|
</div>
|
22
24
|
|
25
|
+
<br/>
|
26
|
+
|
23
27
|
<div class="card">
|
24
28
|
<div class="card-content">
|
25
29
|
<h2 class="title">Requests (path, total number, average response time)<h1>
|
26
|
-
<table class="table is-fullwidth">
|
30
|
+
<table class="table is-fullwidth is-hoverable is-narrow">
|
27
31
|
<thead>
|
28
32
|
<tr>
|
29
33
|
<th colspan='3'>Name</th>
|
30
|
-
<th colspan='3'>Average
|
31
|
-
<th colspan='3'>Slowest
|
34
|
+
<th colspan='3'>Average</th>
|
35
|
+
<th colspan='3'>Slowest</th>
|
32
36
|
</tr>
|
33
37
|
<tr>
|
34
38
|
<th>Controller#Action</th>
|
@@ -53,14 +57,14 @@
|
|
53
57
|
<%= raw(stats_icon) %>
|
54
58
|
<% end %>
|
55
59
|
</td>
|
56
|
-
<td><%= groups[1]&.upcase %></td>
|
60
|
+
<td><%= statistics_link groups[1]&.upcase, @global_report, e[:group] %></td>
|
57
61
|
<td><%= e[:count] %></td>
|
58
|
-
<td><%= round_it e[:duration_average]
|
59
|
-
<td><%= round_it e[:view_runtime_average]
|
60
|
-
<td><%= round_it e[:db_runtime_average]
|
61
|
-
<td><%= round_it e[:duration_slowest]
|
62
|
-
<td><%= round_it e[:view_runtime_slowest]
|
63
|
-
<td><%= round_it e[:db_runtime_slowest]
|
62
|
+
<td><%= round_it e[:duration_average] %> ms</td>
|
63
|
+
<td><%= round_it e[:view_runtime_average] %> ms</td>
|
64
|
+
<td><%= round_it e[:db_runtime_average] %> ms</td>
|
65
|
+
<td><%= round_it e[:duration_slowest] %> ms</td>
|
66
|
+
<td><%= round_it e[:view_runtime_slowest] %> ms</td>
|
67
|
+
<td><%= round_it e[:db_runtime_slowest] %> ms</td>
|
64
68
|
</tr>
|
65
69
|
<% end %>
|
66
70
|
</tbody>
|
@@ -68,6 +72,10 @@
|
|
68
72
|
</div>
|
69
73
|
</div>
|
70
74
|
|
75
|
+
<br/>
|
76
|
+
|
77
|
+
<%= render '/rails_performance/crash_report' %>
|
78
|
+
|
71
79
|
<% content_for :on_load do %>
|
72
80
|
<script>
|
73
81
|
var data1 = <%= raw @throughput_report_data.to_json %>;
|
data/lib/rails_performance.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require "redis"
|
2
2
|
require "redis-namespace"
|
3
|
-
require_relative "rails_performance/query_builder.rb"
|
4
|
-
require_relative "rails_performance/middleware.rb"
|
3
|
+
require_relative "rails_performance/rails/query_builder.rb"
|
4
|
+
require_relative "rails_performance/rails/middleware.rb"
|
5
5
|
require_relative "rails_performance/data_source.rb"
|
6
6
|
require_relative "rails_performance/models/record.rb"
|
7
7
|
require_relative "rails_performance/utils.rb"
|
8
8
|
require_relative "rails_performance/reports/base_report.rb"
|
9
9
|
require_relative "rails_performance/reports/requests_report.rb"
|
10
|
+
require_relative "rails_performance/reports/crash_report.rb"
|
10
11
|
require_relative "rails_performance/reports/response_time_report.rb"
|
11
12
|
require_relative "rails_performance/reports/throughput_report.rb"
|
12
13
|
require_relative "rails_performance/reports/breakdown_report.rb"
|
@@ -14,8 +15,10 @@ require_relative "rails_performance/reports/breakdown_report.rb"
|
|
14
15
|
require "rails_performance/engine"
|
15
16
|
|
16
17
|
module RailsPerformance
|
18
|
+
FORMAT = "%Y%m%dT%H%M"
|
19
|
+
|
17
20
|
mattr_accessor :redis
|
18
|
-
@@redis = Redis::Namespace.new("#{Rails.env}-rails-performance", redis: Redis.new)
|
21
|
+
@@redis = Redis::Namespace.new("#{::Rails.env}-rails-performance", redis: Redis.new)
|
19
22
|
|
20
23
|
mattr_accessor :duration
|
21
24
|
@@duration = 24.hours
|
@@ -11,7 +11,7 @@ module RailsPerformance
|
|
11
11
|
|
12
12
|
def db
|
13
13
|
result = RP::Models::Collection.new
|
14
|
-
RP::Utils.days.times do |e|
|
14
|
+
(RP::Utils.days + 1).times do |e|
|
15
15
|
RP::DataSource.new(q: self.q.merge({ on: e.days.ago.to_date })).add_to(result)
|
16
16
|
end
|
17
17
|
result
|
@@ -29,7 +29,7 @@ module RailsPerformance
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def store
|
32
|
-
#
|
32
|
+
#puts "\n\n [REDIS QUERY] --> #{query}\n\n"
|
33
33
|
|
34
34
|
keys = RP.redis.keys(query)
|
35
35
|
return [] if keys.blank?
|
@@ -1,17 +1,17 @@
|
|
1
|
-
require_relative './middleware.rb'
|
1
|
+
require_relative './rails/middleware.rb'
|
2
2
|
require_relative './models/collection.rb'
|
3
|
-
require_relative './metrics_collector.rb'
|
3
|
+
require_relative './instrument/metrics_collector.rb'
|
4
4
|
|
5
5
|
module RailsPerformance
|
6
6
|
class Engine < ::Rails::Engine
|
7
7
|
|
8
8
|
#config.app_middleware.use RailsPerformance::Middleware
|
9
|
-
config.app_middleware.insert_after ActionDispatch::Executor, RailsPerformance::Middleware
|
9
|
+
config.app_middleware.insert_after ActionDispatch::Executor, RailsPerformance::Rails::Middleware
|
10
10
|
|
11
11
|
initializer :configure_metrics, after: :initialize_logger do
|
12
12
|
ActiveSupport::Notifications.subscribe(
|
13
13
|
"process_action.action_controller",
|
14
|
-
RailsPerformance::MetricsCollector.new
|
14
|
+
RailsPerformance::Instrument::MetricsCollector.new
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RailsPerformance
|
2
|
+
module Instrument
|
3
|
+
class MetricsCollector
|
4
|
+
# payload
|
5
|
+
# {
|
6
|
+
# controller: "PostsController",
|
7
|
+
# action: "index",
|
8
|
+
# params: {"action" => "index", "controller" => "posts"},
|
9
|
+
# headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
|
10
|
+
# format: :html,
|
11
|
+
# method: "GET",
|
12
|
+
# path: "/posts",
|
13
|
+
# status: 200,
|
14
|
+
# view_runtime: 46.848,
|
15
|
+
# db_runtime: 0.157
|
16
|
+
# }
|
17
|
+
|
18
|
+
def call(event_name, started, finished, event_id, payload)
|
19
|
+
event = ActiveSupport::Notifications::Event.new(event_name, started, finished, event_id, payload)
|
20
|
+
|
21
|
+
record = {
|
22
|
+
controller: event.payload[:controller],
|
23
|
+
action: event.payload[:action],
|
24
|
+
format: event.payload[:format],
|
25
|
+
status: event.payload[:status],
|
26
|
+
datetime: finished.strftime(RailsPerformance::FORMAT),
|
27
|
+
datetimei: finished.to_i,
|
28
|
+
method: event.payload[:method],
|
29
|
+
path: event.payload[:path],
|
30
|
+
view_runtime: event.payload[:view_runtime],
|
31
|
+
db_runtime: event.payload[:db_runtime],
|
32
|
+
duration: event.duration
|
33
|
+
}
|
34
|
+
|
35
|
+
Thread.current["RP_request_info"] = record
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RailsPerformance
|
2
|
+
module Rails
|
3
|
+
class Middleware
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
@status, @headers, @response = @app.call(env)
|
10
|
+
|
11
|
+
if record = Thread.current["RP_request_info"]
|
12
|
+
record[:status] ||= @status
|
13
|
+
|
14
|
+
rand(500).times do |e|
|
15
|
+
finished = Time.now - rand(2000).minutes
|
16
|
+
record[:datetime] = finished.strftime(RailsPerformance::FORMAT)
|
17
|
+
record[:datetimei] = finished.to_i
|
18
|
+
record[:duration] = 50 + rand(100) + rand(50.0) + rand(e)
|
19
|
+
record[:db_runtime] = rand(50.0)
|
20
|
+
record[:view_runtime] = rand(50.0)
|
21
|
+
RP::Utils.log_in_redis(record)
|
22
|
+
end
|
23
|
+
|
24
|
+
RP::Utils.log_in_redis(record)
|
25
|
+
|
26
|
+
Thread.current["RP_request_info"] = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
[@status, @headers, @response]
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RailsPerformance
|
2
|
+
module Rails
|
3
|
+
class QueryBuilder
|
4
|
+
|
5
|
+
def QueryBuilder.compose_from(params)
|
6
|
+
result = {}
|
7
|
+
|
8
|
+
result[:controller] = params[:controller_eq]
|
9
|
+
result[:action] = params[:action_eq]
|
10
|
+
result[:format] = params[:format_eq]
|
11
|
+
result[:status] = params[:status_eq]
|
12
|
+
|
13
|
+
result.delete_if {|k, v| v.nil?}
|
14
|
+
|
15
|
+
{ q: result }
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RailsPerformance
|
2
|
+
module Reports
|
3
|
+
class CrashReport < BaseReport
|
4
|
+
def set_defaults
|
5
|
+
@sort ||= :datetime
|
6
|
+
end
|
7
|
+
|
8
|
+
def data
|
9
|
+
db.data.collect do |record|
|
10
|
+
{
|
11
|
+
controller: record.controller,
|
12
|
+
action: record.action,
|
13
|
+
format: record.format,
|
14
|
+
status: record.status,
|
15
|
+
method: record.method,
|
16
|
+
path: record.path,
|
17
|
+
datetime: Time.parse(record.datetime),
|
18
|
+
duration: record.value['duration'],
|
19
|
+
db_runtime: record.value['db_runtime'],
|
20
|
+
view_runtime: record.value['view_runtime'],
|
21
|
+
}
|
22
|
+
end.sort{|a, b| b[sort] <=> a[sort]}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -24,7 +24,7 @@ module RailsPerformance
|
|
24
24
|
|
25
25
|
# add blank columns
|
26
26
|
while current <= stop
|
27
|
-
views = all[current.strftime(
|
27
|
+
views = all[current.strftime(RailsPerformance::FORMAT)] || 0
|
28
28
|
@data << [(current.to_i + offset) * 1000, views.round(2)]
|
29
29
|
current += 1.minute
|
30
30
|
end
|
@@ -23,7 +23,7 @@ module RailsPerformance
|
|
23
23
|
|
24
24
|
# add blank columns
|
25
25
|
while current <= stop
|
26
|
-
views = all[current.strftime(
|
26
|
+
views = all[current.strftime(RailsPerformance::FORMAT)] || 0
|
27
27
|
@data << [(current.to_i + offset) * 1000, views.to_i]
|
28
28
|
current += 1.minute
|
29
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_performance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.
|
4
|
+
version: 0.0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- app/views/javascripts/_javascripts.html.erb
|
97
97
|
- app/views/javascripts/app.js
|
98
98
|
- app/views/layouts/rails_performance.html.erb
|
99
|
+
- app/views/rails_performance/_crash_report.html.erb
|
99
100
|
- app/views/rails_performance/breakdown.html.erb
|
100
101
|
- app/views/rails_performance/index.html.erb
|
101
102
|
- app/views/stylesheets/_stylesheets.html.erb
|
@@ -105,13 +106,14 @@ files:
|
|
105
106
|
- lib/rails_performance.rb
|
106
107
|
- lib/rails_performance/data_source.rb
|
107
108
|
- lib/rails_performance/engine.rb
|
108
|
-
- lib/rails_performance/metrics_collector.rb
|
109
|
-
- lib/rails_performance/middleware.rb
|
109
|
+
- lib/rails_performance/instrument/metrics_collector.rb
|
110
110
|
- lib/rails_performance/models/collection.rb
|
111
111
|
- lib/rails_performance/models/record.rb
|
112
|
-
- lib/rails_performance/
|
112
|
+
- lib/rails_performance/rails/middleware.rb
|
113
|
+
- lib/rails_performance/rails/query_builder.rb
|
113
114
|
- lib/rails_performance/reports/base_report.rb
|
114
115
|
- lib/rails_performance/reports/breakdown_report.rb
|
116
|
+
- lib/rails_performance/reports/crash_report.rb
|
115
117
|
- lib/rails_performance/reports/requests_report.rb
|
116
118
|
- lib/rails_performance/reports/response_time_report.rb
|
117
119
|
- lib/rails_performance/reports/throughput_report.rb
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
class MetricsCollector
|
3
|
-
FORMAT = "%Y%m%dT%H%M"
|
4
|
-
|
5
|
-
# payload
|
6
|
-
# {
|
7
|
-
# controller: "PostsController",
|
8
|
-
# action: "index",
|
9
|
-
# params: {"action" => "index", "controller" => "posts"},
|
10
|
-
# headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
|
11
|
-
# format: :html,
|
12
|
-
# method: "GET",
|
13
|
-
# path: "/posts",
|
14
|
-
# status: 200,
|
15
|
-
# view_runtime: 46.848,
|
16
|
-
# db_runtime: 0.157
|
17
|
-
# }
|
18
|
-
|
19
|
-
def call(event_name, started, finished, event_id, payload)
|
20
|
-
event = ActiveSupport::Notifications::Event.new(event_name, started, finished, event_id, payload)
|
21
|
-
|
22
|
-
record = {
|
23
|
-
controller: event.payload[:controller],
|
24
|
-
action: event.payload[:action],
|
25
|
-
format: event.payload[:format],
|
26
|
-
status: event.payload[:status],
|
27
|
-
datetime: finished.strftime(RailsPerformance::MetricsCollector::FORMAT),
|
28
|
-
datetimei: finished.to_i,
|
29
|
-
method: event.payload[:method],
|
30
|
-
path: event.payload[:path],
|
31
|
-
view_runtime: event.payload[:view_runtime],
|
32
|
-
db_runtime: event.payload[:db_runtime],
|
33
|
-
duration: event.duration
|
34
|
-
}
|
35
|
-
|
36
|
-
Thread.current["RP_request_info"] = record
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
class Middleware
|
3
|
-
def initialize(app)
|
4
|
-
@app = app
|
5
|
-
end
|
6
|
-
|
7
|
-
def call(env)
|
8
|
-
@status, @headers, @response = @app.call(env)
|
9
|
-
|
10
|
-
if record = Thread.current["RP_request_info"]
|
11
|
-
record[:status] ||= @status
|
12
|
-
|
13
|
-
# rand(100).times do |e|
|
14
|
-
# finished = Time.now - rand(2000).minutes
|
15
|
-
# record[:datetime] = finished.strftime(RailsPerformance::MetricsCollector::FORMAT)
|
16
|
-
# record[:datetimei] = finished.to_i
|
17
|
-
# record[:duration] = 50 + rand(100) + rand(50.0)
|
18
|
-
# record[:db_runtime] = rand(50.0)
|
19
|
-
# record[:view_runtime] = rand(50.0)
|
20
|
-
# RP::Utils.log_in_redis(record)
|
21
|
-
# end
|
22
|
-
|
23
|
-
RP::Utils.log_in_redis(record)
|
24
|
-
|
25
|
-
Thread.current["RP_request_info"] = nil
|
26
|
-
end
|
27
|
-
|
28
|
-
[@status, @headers, @response]
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
class QueryBuilder
|
3
|
-
|
4
|
-
def QueryBuilder.compose_from(params)
|
5
|
-
result = {}
|
6
|
-
|
7
|
-
result[:controller] = params[:controller_eq]
|
8
|
-
result[:action] = params[:action_eq]
|
9
|
-
result[:format] = params[:format_eq]
|
10
|
-
|
11
|
-
result.delete_if {|k, v| v.nil?}
|
12
|
-
|
13
|
-
{ q: result }
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|