rails_performance 1.2.3 → 1.3.1
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 +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
|