rails_performance 1.2.3 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -13
- data/Rakefile +14 -14
- data/app/assets/images/download.svg +3 -0
- data/app/controllers/rails_performance/base_controller.rb +21 -21
- data/app/controllers/rails_performance/concerns/csv_exportable.rb +29 -0
- data/app/controllers/rails_performance/rails_performance_controller.rb +96 -49
- data/app/helpers/rails_performance/rails_performance_helper.rb +152 -156
- data/app/views/rails_performance/javascripts/app.js +2 -2
- data/app/views/rails_performance/rails_performance/_export.html.erb +3 -0
- data/app/views/rails_performance/rails_performance/crashes.html.erb +8 -1
- data/app/views/rails_performance/rails_performance/index.html.erb +29 -0
- data/app/views/rails_performance/rails_performance/recent.html.erb +8 -6
- data/app/views/rails_performance/rails_performance/requests.html.erb +15 -1
- data/app/views/rails_performance/rails_performance/slow.html.erb +3 -0
- data/app/views/rails_performance/shared/_header.html.erb +0 -1
- data/app/views/rails_performance/stylesheets/style.css +10 -0
- data/config/routes.rb +16 -18
- data/lib/generators/rails_performance/install/install_generator.rb +1 -1
- data/lib/generators/rails_performance/install/templates/initializer.rb +56 -42
- data/lib/rails_performance/data_source.rb +120 -121
- data/lib/rails_performance/engine.rb +8 -8
- data/lib/rails_performance/extensions/trace.rb +32 -33
- data/lib/rails_performance/gems/custom_ext.rb +31 -34
- data/lib/rails_performance/gems/delayed_job_ext.rb +50 -54
- data/lib/rails_performance/gems/grape_ext.rb +33 -35
- data/lib/rails_performance/gems/rake_ext.rb +41 -44
- data/lib/rails_performance/gems/sidekiq_ext.rb +34 -37
- data/lib/rails_performance/instrument/metrics_collector.rb +50 -50
- data/lib/rails_performance/models/base_record.rb +33 -36
- data/lib/rails_performance/models/collection.rb +35 -36
- data/lib/rails_performance/models/custom_record.rb +47 -48
- data/lib/rails_performance/models/delayed_job_record.rb +61 -62
- data/lib/rails_performance/models/grape_record.rb +60 -61
- data/lib/rails_performance/models/rake_record.rb +48 -49
- data/lib/rails_performance/models/request_record.rb +128 -120
- data/lib/rails_performance/models/sidekiq_record.rb +65 -66
- data/lib/rails_performance/models/trace_record.rb +18 -19
- data/lib/rails_performance/rails/middleware.rb +75 -76
- data/lib/rails_performance/rails/query_builder.rb +18 -20
- data/lib/rails_performance/reports/base_report.rb +60 -60
- data/lib/rails_performance/reports/breakdown_report.rb +15 -18
- data/lib/rails_performance/reports/crash_report.rb +15 -17
- data/lib/rails_performance/reports/percentile_report.rb +14 -0
- data/lib/rails_performance/reports/recent_requests_report.rb +24 -24
- data/lib/rails_performance/reports/requests_report.rb +30 -27
- data/lib/rails_performance/reports/response_time_report.rb +17 -17
- data/lib/rails_performance/reports/slow_requests_report.rb +4 -4
- data/lib/rails_performance/reports/throughput_report.rb +15 -17
- data/lib/rails_performance/reports/trace_report.rb +16 -18
- data/lib/rails_performance/thread/current_request.rb +33 -34
- data/lib/rails_performance/utils.rb +64 -54
- data/lib/rails_performance/version.rb +2 -2
- data/lib/rails_performance.rb +35 -36
- metadata +21 -17
@@ -1,66 +1,65 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
module Models
|
3
|
-
class SidekiqRecord < BaseRecord
|
4
|
-
attr_accessor :queue, :worker, :jid, :datetimei, :enqueued_ati, :datetime, :start_timei, :status, :duration, :message
|
5
|
-
|
6
|
-
# key = job-performance
|
7
|
-
# |queue|default
|
8
|
-
# |worker|SimpleWorker
|
9
|
-
# |jid|7d48fbf20976c224510dbc60
|
10
|
-
# |datetime|20200124T0523
|
11
|
-
# |datetimei|1583146613
|
12
|
-
# |enqueued_ati|1583146613
|
13
|
-
# |start_timei|1583146614
|
14
|
-
# |status|success|END|1.0.0
|
15
|
-
# value = JSON
|
16
|
-
def
|
17
|
-
items = key.split("|")
|
18
|
-
|
19
|
-
SidekiqRecord.new(
|
20
|
-
queue: items[2],
|
21
|
-
worker: items[4],
|
22
|
-
jid: items[6],
|
23
|
-
datetime: items[8],
|
24
|
-
datetimei: items[10],
|
25
|
-
enqueued_ati: items[12],
|
26
|
-
start_timei: items[14],
|
27
|
-
status: items[16],
|
28
|
-
json: value
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
def initialize(queue:, worker:, jid:, datetime:, datetimei:, enqueued_ati:, start_timei:, status: nil, duration: nil, json: "{}")
|
33
|
-
@queue
|
34
|
-
@worker
|
35
|
-
@jid
|
36
|
-
@datetime
|
37
|
-
@datetimei
|
38
|
-
@enqueued_ati = enqueued_ati
|
39
|
-
@start_timei
|
40
|
-
@status
|
41
|
-
@duration
|
42
|
-
@json
|
43
|
-
end
|
44
|
-
|
45
|
-
def record_hash
|
46
|
-
{
|
47
|
-
worker:
|
48
|
-
queue:
|
49
|
-
jid:
|
50
|
-
status:
|
51
|
-
datetimei: datetimei,
|
52
|
-
datetime: Time.at(
|
53
|
-
duration:
|
54
|
-
message: value[
|
55
|
-
}
|
56
|
-
end
|
57
|
-
|
58
|
-
def save
|
59
|
-
key
|
60
|
-
value = {
|
61
|
-
Utils.save_to_redis(key, value)
|
62
|
-
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
1
|
+
module RailsPerformance
|
2
|
+
module Models
|
3
|
+
class SidekiqRecord < BaseRecord
|
4
|
+
attr_accessor :queue, :worker, :jid, :datetimei, :enqueued_ati, :datetime, :start_timei, :status, :duration, :message
|
5
|
+
|
6
|
+
# key = job-performance
|
7
|
+
# |queue|default
|
8
|
+
# |worker|SimpleWorker
|
9
|
+
# |jid|7d48fbf20976c224510dbc60
|
10
|
+
# |datetime|20200124T0523
|
11
|
+
# |datetimei|1583146613
|
12
|
+
# |enqueued_ati|1583146613
|
13
|
+
# |start_timei|1583146614
|
14
|
+
# |status|success|END|1.0.0
|
15
|
+
# value = JSON
|
16
|
+
def self.from_db(key, value)
|
17
|
+
items = key.split("|")
|
18
|
+
|
19
|
+
SidekiqRecord.new(
|
20
|
+
queue: items[2],
|
21
|
+
worker: items[4],
|
22
|
+
jid: items[6],
|
23
|
+
datetime: items[8],
|
24
|
+
datetimei: items[10],
|
25
|
+
enqueued_ati: items[12],
|
26
|
+
start_timei: items[14],
|
27
|
+
status: items[16],
|
28
|
+
json: value
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(queue:, worker:, jid:, datetime:, datetimei:, enqueued_ati:, start_timei:, status: nil, duration: nil, json: "{}")
|
33
|
+
@queue = queue
|
34
|
+
@worker = worker
|
35
|
+
@jid = jid
|
36
|
+
@datetime = datetime
|
37
|
+
@datetimei = datetimei.to_i
|
38
|
+
@enqueued_ati = enqueued_ati
|
39
|
+
@start_timei = start_timei
|
40
|
+
@status = status
|
41
|
+
@duration = duration
|
42
|
+
@json = json
|
43
|
+
end
|
44
|
+
|
45
|
+
def record_hash
|
46
|
+
{
|
47
|
+
worker: worker,
|
48
|
+
queue: queue,
|
49
|
+
jid: jid,
|
50
|
+
status: status,
|
51
|
+
datetimei: datetimei,
|
52
|
+
datetime: Time.at(start_timei.to_i),
|
53
|
+
duration: value["duration"],
|
54
|
+
message: value["message"]
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def save
|
59
|
+
key = "sidekiq|queue|#{queue}|worker|#{worker}|jid|#{jid}|datetime|#{datetime}|datetimei|#{datetimei}|enqueued_ati|#{enqueued_ati}|start_timei|#{start_timei}|status|#{status}|END|#{RailsPerformance::SCHEMA}"
|
60
|
+
value = {message: message, duration: duration}
|
61
|
+
Utils.save_to_redis(key, value)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -1,19 +1,18 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
module Models
|
3
|
-
class TraceRecord < BaseRecord
|
4
|
-
attr_accessor :request_id, :value
|
5
|
-
|
6
|
-
def initialize(request_id:, value:)
|
7
|
-
@request_id = request_id
|
8
|
-
@value
|
9
|
-
end
|
10
|
-
|
11
|
-
def save
|
12
|
-
return if value.empty?
|
13
|
-
|
14
|
-
Utils.save_to_redis("trace|#{request_id}|END|#{RailsPerformance::SCHEMA}", value, RailsPerformance.recent_requests_time_window.to_i)
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
1
|
+
module RailsPerformance
|
2
|
+
module Models
|
3
|
+
class TraceRecord < BaseRecord
|
4
|
+
attr_accessor :request_id, :value
|
5
|
+
|
6
|
+
def initialize(request_id:, value:)
|
7
|
+
@request_id = request_id
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def save
|
12
|
+
return if value.empty?
|
13
|
+
|
14
|
+
Utils.save_to_redis("trace|#{request_id}|END|#{RailsPerformance::SCHEMA}", value, RailsPerformance.recent_requests_time_window.to_i)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,76 +1,75 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
module Rails
|
3
|
-
class MiddlewareTraceStorerAndCleanup
|
4
|
-
def initialize(app)
|
5
|
-
@app = app
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(env)
|
9
|
-
dup.call!(env)
|
10
|
-
end
|
11
|
-
|
12
|
-
def call!(env)
|
13
|
-
if %r{#{RailsPerformance.mount_at}}.match?(env["PATH_INFO"])
|
14
|
-
RailsPerformance.skip = true
|
15
|
-
end
|
16
|
-
|
17
|
-
@status, @headers, @response = @app.call(env)
|
18
|
-
|
19
|
-
if !RailsPerformance.skip
|
20
|
-
RailsPerformance::Models::TraceRecord.new(
|
21
|
-
request_id: CurrentRequest.current.request_id,
|
22
|
-
value: CurrentRequest.current.tracings
|
23
|
-
).save
|
24
|
-
end
|
25
|
-
|
26
|
-
CurrentRequest.cleanup
|
27
|
-
|
28
|
-
[@status, @headers, @response]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class Middleware
|
33
|
-
def initialize(app)
|
34
|
-
@app = app
|
35
|
-
end
|
36
|
-
|
37
|
-
def call(env)
|
38
|
-
dup.call!(env)
|
39
|
-
end
|
40
|
-
|
41
|
-
def call!(env)
|
42
|
-
@status, @headers, @response = @app.call(env)
|
43
|
-
|
44
|
-
#t = Time.current
|
45
|
-
if !RailsPerformance.skip
|
46
|
-
if !CurrentRequest.current.ignore.include?(:performance) # grape is executed first, and than ignore regular future storage of "controller"-like request
|
47
|
-
if data = CurrentRequest.current.data
|
48
|
-
record = RailsPerformance::Models::RequestRecord.new(**data.merge({request_id: CurrentRequest.current.request_id}))
|
49
|
-
|
50
|
-
# for 500 errors
|
51
|
-
record.status ||= @status
|
52
|
-
|
53
|
-
# capture referer from where this page was opened
|
54
|
-
record.http_referer = env["HTTP_REFERER"] if record.status == 404
|
55
|
-
|
56
|
-
# we can add custom data, for example Http User-Agent
|
57
|
-
# or even devise current_user
|
58
|
-
if RailsPerformance.custom_data_proc
|
59
|
-
# just to be sure it won't break format how we store in redis
|
60
|
-
record.custom_data = RailsPerformance.custom_data_proc.call(env)
|
61
|
-
end
|
62
|
-
|
63
|
-
# store for section "recent requests"
|
64
|
-
# store request information (regular rails request)
|
65
|
-
record.save
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
#puts "==> store performance data: #{(Time.current - t).round(3)}ms"
|
70
|
-
|
71
|
-
[@status, @headers, @response]
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
1
|
+
module RailsPerformance
|
2
|
+
module Rails
|
3
|
+
class MiddlewareTraceStorerAndCleanup
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
dup.call!(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call!(env)
|
13
|
+
if %r{#{RailsPerformance.mount_at}}.match?(env["PATH_INFO"])
|
14
|
+
RailsPerformance.skip = true
|
15
|
+
end
|
16
|
+
|
17
|
+
@status, @headers, @response = @app.call(env)
|
18
|
+
|
19
|
+
if !RailsPerformance.skip
|
20
|
+
RailsPerformance::Models::TraceRecord.new(
|
21
|
+
request_id: CurrentRequest.current.request_id,
|
22
|
+
value: CurrentRequest.current.tracings
|
23
|
+
).save
|
24
|
+
end
|
25
|
+
|
26
|
+
CurrentRequest.cleanup
|
27
|
+
|
28
|
+
[@status, @headers, @response]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Middleware
|
33
|
+
def initialize(app)
|
34
|
+
@app = app
|
35
|
+
end
|
36
|
+
|
37
|
+
def call(env)
|
38
|
+
dup.call!(env)
|
39
|
+
end
|
40
|
+
|
41
|
+
def call!(env)
|
42
|
+
@status, @headers, @response = @app.call(env)
|
43
|
+
|
44
|
+
# t = Time.current
|
45
|
+
if !RailsPerformance.skip
|
46
|
+
if !CurrentRequest.current.ignore.include?(:performance) # grape is executed first, and than ignore regular future storage of "controller"-like request
|
47
|
+
if (data = CurrentRequest.current.data)
|
48
|
+
record = RailsPerformance::Models::RequestRecord.new(**data.merge({request_id: CurrentRequest.current.request_id}))
|
49
|
+
|
50
|
+
# for 500 errors
|
51
|
+
record.status ||= @status
|
52
|
+
|
53
|
+
# capture referer from where this page was opened
|
54
|
+
record.http_referer = env["HTTP_REFERER"] if record.status == 404
|
55
|
+
|
56
|
+
# we can add custom data, for example Http User-Agent
|
57
|
+
# or even devise current_user
|
58
|
+
if RailsPerformance.custom_data_proc
|
59
|
+
# just to be sure it won't break format how we store in redis
|
60
|
+
record.custom_data = RailsPerformance.custom_data_proc.call(env)
|
61
|
+
end
|
62
|
+
|
63
|
+
# store for section "recent requests"
|
64
|
+
# store request information (regular rails request)
|
65
|
+
record.save
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
# puts "==> store performance data: #{(Time.current - t).round(3)}ms"
|
70
|
+
|
71
|
+
[@status, @headers, @response]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,20 +1,18 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
module Rails
|
3
|
-
class QueryBuilder
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
result[:
|
9
|
-
result[:
|
10
|
-
result[:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
1
|
+
module RailsPerformance
|
2
|
+
module Rails
|
3
|
+
class QueryBuilder
|
4
|
+
def self.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
|
+
result[:status] = params[:status_eq]
|
11
|
+
|
12
|
+
result.delete_if { |k, v| v.nil? }
|
13
|
+
|
14
|
+
{q: result}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,60 +1,60 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
module Reports
|
3
|
-
class BaseReport
|
4
|
-
attr_reader :db, :group, :sort, :title
|
5
|
-
|
6
|
-
def initialize(db, group: nil, sort: nil, title: nil)
|
7
|
-
@db
|
8
|
-
@group
|
9
|
-
@sort
|
10
|
-
@title
|
11
|
-
|
12
|
-
set_defaults
|
13
|
-
end
|
14
|
-
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def self.time_in_app_time_zone(time)
|
25
|
-
app_time_zone = ::Rails.application.config.time_zone
|
26
|
-
if app_time_zone.present?
|
27
|
-
time.in_time_zone(app_time_zone)
|
28
|
-
else
|
29
|
-
time
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def calculate_data
|
34
|
-
now
|
35
|
-
stop
|
36
|
-
offset
|
37
|
-
current
|
38
|
-
|
39
|
-
@data
|
40
|
-
all
|
41
|
-
|
42
|
-
# read current values
|
43
|
-
db.group_by(group).each do |(k, v)|
|
44
|
-
yield(all, k, v)
|
45
|
-
end
|
46
|
-
|
47
|
-
# add blank columns
|
48
|
-
while current <= stop
|
49
|
-
key
|
50
|
-
views = all[key].presence || 0
|
51
|
-
@data << [(current.to_i + offset) * 1000, views.round(2)]
|
52
|
-
current += 1.minute
|
53
|
-
end
|
54
|
-
|
55
|
-
# sort by time
|
56
|
-
@data.sort!
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
1
|
+
module RailsPerformance
|
2
|
+
module Reports
|
3
|
+
class BaseReport
|
4
|
+
attr_reader :db, :group, :sort, :title
|
5
|
+
|
6
|
+
def initialize(db, group: nil, sort: nil, title: nil)
|
7
|
+
@db = db
|
8
|
+
@group = group
|
9
|
+
@sort = sort
|
10
|
+
@title = title
|
11
|
+
|
12
|
+
set_defaults
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_defaults
|
16
|
+
end
|
17
|
+
|
18
|
+
def collect
|
19
|
+
db.group_by(group).each_with_object([]) do |(k, v), res|
|
20
|
+
res << yield(k, v)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.time_in_app_time_zone(time)
|
25
|
+
app_time_zone = ::Rails.application.config.time_zone
|
26
|
+
if app_time_zone.present?
|
27
|
+
time.in_time_zone(app_time_zone)
|
28
|
+
else
|
29
|
+
time
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def calculate_data
|
34
|
+
now = Time.current
|
35
|
+
stop = Time.at(60 * (now.to_i / 60))
|
36
|
+
offset = RailsPerformance::Reports::BaseReport.time_in_app_time_zone(now).utc_offset
|
37
|
+
current = stop - RailsPerformance.duration
|
38
|
+
|
39
|
+
@data = []
|
40
|
+
all = {}
|
41
|
+
|
42
|
+
# read current values
|
43
|
+
db.group_by(group).each do |(k, v)|
|
44
|
+
yield(all, k, v)
|
45
|
+
end
|
46
|
+
|
47
|
+
# add blank columns
|
48
|
+
while current <= stop
|
49
|
+
key = current.strftime(RailsPerformance::FORMAT)
|
50
|
+
views = all[key].presence || 0
|
51
|
+
@data << [(current.to_i + offset) * 1000, views.round(2)]
|
52
|
+
current += 1.minute
|
53
|
+
end
|
54
|
+
|
55
|
+
# sort by time
|
56
|
+
@data.sort!
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,18 +1,15 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
module Reports
|
3
|
-
class BreakdownReport < BaseReport
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|
1
|
+
module RailsPerformance
|
2
|
+
module Reports
|
3
|
+
class BreakdownReport < BaseReport
|
4
|
+
def set_defaults
|
5
|
+
@sort ||= :datetimei
|
6
|
+
end
|
7
|
+
|
8
|
+
def data
|
9
|
+
db.data
|
10
|
+
.collect { |e| e.record_hash }
|
11
|
+
.sort { |a, b| b[sort] <=> a[sort] }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,17 +1,15 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
module Reports
|
3
|
-
class CrashReport < BaseReport
|
4
|
-
def set_defaults
|
5
|
-
@sort ||= :datetimei
|
6
|
-
end
|
7
|
-
|
8
|
-
def data
|
9
|
-
db.data
|
10
|
-
.collect{|e| e.record_hash}
|
11
|
-
.sort{|a, b| b[sort] <=> a[sort]}
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
1
|
+
module RailsPerformance
|
2
|
+
module Reports
|
3
|
+
class CrashReport < BaseReport
|
4
|
+
def set_defaults
|
5
|
+
@sort ||= :datetimei
|
6
|
+
end
|
7
|
+
|
8
|
+
def data
|
9
|
+
db.data
|
10
|
+
.collect { |e| e.record_hash }
|
11
|
+
.sort { |a, b| b[sort] <=> a[sort] }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RailsPerformance
|
2
|
+
module Reports
|
3
|
+
class PercentileReport < BaseReport
|
4
|
+
def data
|
5
|
+
durations = db.data.collect(&:duration)
|
6
|
+
{
|
7
|
+
p50: RailsPerformance::Utils.percentile(durations, 50),
|
8
|
+
p95: RailsPerformance::Utils.percentile(durations, 95),
|
9
|
+
p99: RailsPerformance::Utils.percentile(durations, 99)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,24 +1,24 @@
|
|
1
|
-
module RailsPerformance
|
2
|
-
module Reports
|
3
|
-
class RecentRequestsReport < BaseReport
|
4
|
-
def set_defaults
|
5
|
-
@sort ||= :datetimei
|
6
|
-
end
|
7
|
-
|
8
|
-
def data(from_timei = nil)
|
9
|
-
time_agoi = [RailsPerformance.recent_requests_time_window.ago.to_i, from_timei.to_i].reject(&:blank?).max
|
10
|
-
db.data
|
11
|
-
.collect{|e| e.record_hash}
|
12
|
-
.select{|e| e if e[sort] > time_agoi}
|
13
|
-
.sort{|a, b| b[sort] <=> a[sort]}
|
14
|
-
.first(limit)
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def limit
|
20
|
-
RailsPerformance.recent_requests_limit ? RailsPerformance.recent_requests_limit.to_i : 100_000
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
1
|
+
module RailsPerformance
|
2
|
+
module Reports
|
3
|
+
class RecentRequestsReport < BaseReport
|
4
|
+
def set_defaults
|
5
|
+
@sort ||= :datetimei
|
6
|
+
end
|
7
|
+
|
8
|
+
def data(from_timei = nil)
|
9
|
+
time_agoi = [RailsPerformance.recent_requests_time_window.ago.to_i, from_timei.to_i].reject(&:blank?).max
|
10
|
+
db.data
|
11
|
+
.collect { |e| e.record_hash }
|
12
|
+
.select { |e| e if e[sort] > time_agoi }
|
13
|
+
.sort { |a, b| b[sort] <=> a[sort] }
|
14
|
+
.first(limit)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def limit
|
20
|
+
RailsPerformance.recent_requests_limit ? RailsPerformance.recent_requests_limit.to_i : 100_000
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|