rails_mini_profiler 0.7.0 → 0.7.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 +1 -1
- data/app/controllers/rails_mini_profiler/application_controller.rb +0 -9
- data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +16 -0
- data/app/models/rails_mini_profiler/profiled_request.rb +1 -1
- data/app/models/rails_mini_profiler/trace.rb +0 -15
- data/app/presenters/rails_mini_profiler/controller_trace_presenter.rb +10 -2
- data/app/presenters/rails_mini_profiler/instantiation_trace_presenter.rb +15 -3
- data/app/presenters/rails_mini_profiler/render_partial_trace_presenter.rb +6 -2
- data/app/presenters/rails_mini_profiler/render_template_trace_presenter.rb +6 -2
- data/app/presenters/rails_mini_profiler/sequel_trace_presenter.rb +16 -4
- data/app/presenters/rails_mini_profiler/trace_presenter.rb +1 -1
- data/app/views/rails_mini_profiler/profiled_requests/show/_trace.html.erb +1 -1
- data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +1 -1
- data/lib/rails_mini_profiler/badge.rb +20 -11
- data/lib/rails_mini_profiler/configuration/user_interface.rb +10 -2
- data/lib/rails_mini_profiler/configuration.rb +4 -0
- data/lib/rails_mini_profiler/middleware.rb +10 -10
- data/lib/rails_mini_profiler/request_context.rb +22 -18
- data/lib/rails_mini_profiler/request_wrapper.rb +12 -55
- data/lib/rails_mini_profiler/response_wrapper.rb +21 -17
- data/lib/rails_mini_profiler/{tracing → tracers}/controller_tracer.rb +15 -1
- data/lib/rails_mini_profiler/tracers/instantiation_tracer.rb +17 -0
- data/lib/rails_mini_profiler/{tracing → tracers}/null_trace.rb +1 -1
- data/lib/rails_mini_profiler/tracers/registry.rb +76 -0
- data/lib/rails_mini_profiler/tracers/rmp_tracer.rb +17 -0
- data/lib/rails_mini_profiler/{tracing → tracers}/sequel_tracer.rb +15 -1
- data/lib/rails_mini_profiler/{tracing → tracers}/sequel_tracker.rb +4 -1
- data/lib/rails_mini_profiler/{tracing → tracers}/subscriptions.rb +6 -12
- data/lib/rails_mini_profiler/{tracing → tracers}/trace.rb +2 -2
- data/lib/rails_mini_profiler/tracers/trace_factory.rb +27 -0
- data/lib/rails_mini_profiler/{tracing → tracers}/tracer.rb +15 -1
- data/lib/rails_mini_profiler/tracers/view_tracer.rb +29 -0
- data/lib/rails_mini_profiler/tracers.rb +14 -0
- data/lib/rails_mini_profiler/version.rb +1 -1
- data/lib/rails_mini_profiler.rb +1 -1
- metadata +15 -18
- data/app/models/rails_mini_profiler/controller_trace.rb +0 -37
- data/app/models/rails_mini_profiler/instantiation_trace.rb +0 -37
- data/app/models/rails_mini_profiler/render_partial_trace.rb +0 -37
- data/app/models/rails_mini_profiler/render_template_trace.rb +0 -37
- data/app/models/rails_mini_profiler/rmp_trace.rb +0 -35
- data/app/models/rails_mini_profiler/sequel_trace.rb +0 -37
- data/lib/rails_mini_profiler/tracing/trace_factory.rb +0 -37
- data/lib/rails_mini_profiler/tracing/view_tracer.rb +0 -12
- data/lib/rails_mini_profiler/tracing.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08b93a903a5bb3b16310b3a918a1a52555a9ce5fc2a60624d0f2bb8158e3ddb5'
|
4
|
+
data.tar.gz: 88af5220a54c4f91e4506cd0423a853512dcc67235c65a22990d1c4fc1d92c25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a41fec13f04188e895769fcb17004fdd6436aaddd8942ff4657beaffb7c0f4b63ca64d60f9877d119c1e363194ebd3c97e629216d0bf675fceb82cd49b6dcda
|
7
|
+
data.tar.gz: f5c81dbc3b627e48a0d9097fb587b37c2c299476adb87d01ace6c697e234b32f8fceee942045656f82f8c4d6ef6c082e58ad2f5619ccf2b4114b32764dae8c8f
|
data/README.md
CHANGED
@@ -153,7 +153,7 @@ Rails Mini Profiler allows you to configure various UI features.
|
|
153
153
|
|---------------------|---------------------------|-------------------------------------------------------------------------------------------------|
|
154
154
|
| `badge_enabled` | `true` | Should the hedgehog 🦔 badge be injected into pages? |
|
155
155
|
| `badge_position` | `'top-left'` | Where to display the badge. Options are `'top-left', 'top-right', 'bottom-left, 'bottom-right'` |
|
156
|
-
| `base_controller` | `ApplicationController`
|
156
|
+
| `base_controller` | `ApplicationController` | Which controller UI controllers should inherit from. |
|
157
157
|
| `page_size` | `25` | The page size for lists shown in the UI. |
|
158
158
|
| `webpacker_enabled` | `true` | Use Webpacker if available? Disable to fall back to the asset pipeline. |
|
159
159
|
|
@@ -6,15 +6,6 @@ module RailsMiniProfiler
|
|
6
6
|
|
7
7
|
before_action :check_rmp_user
|
8
8
|
|
9
|
-
protected
|
10
|
-
|
11
|
-
def present(model, presenter_class = nil, **kwargs)
|
12
|
-
klass = presenter_class || "RailsMiniProfiler::#{model.class.to_s.demodulize}Presenter".constantize
|
13
|
-
presenter = klass.new(model, view_context, **kwargs)
|
14
|
-
yield(presenter) if block_given?
|
15
|
-
presenter
|
16
|
-
end
|
17
|
-
|
18
9
|
private
|
19
10
|
|
20
11
|
def handle(error, status = 500)
|
@@ -67,6 +67,22 @@ module RailsMiniProfiler
|
|
67
67
|
@configuration ||= RailsMiniProfiler.configuration
|
68
68
|
end
|
69
69
|
|
70
|
+
def registry
|
71
|
+
@registry ||= RailsMiniProfiler::Tracers::Registry.new(configuration)
|
72
|
+
end
|
73
|
+
|
74
|
+
def present(model, presenter_class = nil, **kwargs)
|
75
|
+
klass = presenter_class || presenter_class(model)
|
76
|
+
klass.new(model, view_context, **kwargs)
|
77
|
+
end
|
78
|
+
|
79
|
+
def presenter_class(model)
|
80
|
+
return ProfiledRequestPresenter if model.is_a?(ProfiledRequest)
|
81
|
+
|
82
|
+
presenters = registry.presenters
|
83
|
+
presenters[model.name] || TracePresenter
|
84
|
+
end
|
85
|
+
|
70
86
|
def payload_column
|
71
87
|
if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
72
88
|
# Cast json field to text to have access to the LIKE operator
|
@@ -43,7 +43,7 @@ module RailsMiniProfiler
|
|
43
43
|
def request=(request)
|
44
44
|
self.request_body = request.body
|
45
45
|
self.request_headers = request.headers
|
46
|
-
self.request_method = request.
|
46
|
+
self.request_method = request.request_method
|
47
47
|
self.request_path = request.path
|
48
48
|
self.request_query_string = request.query_string
|
49
49
|
end
|
@@ -23,24 +23,9 @@
|
|
23
23
|
module RailsMiniProfiler
|
24
24
|
class Trace < RailsMiniProfiler::ApplicationRecord
|
25
25
|
self.table_name = RailsMiniProfiler.storage_configuration.traces_table
|
26
|
-
self.inheritance_column = :name
|
27
26
|
|
28
27
|
belongs_to :profiled_request,
|
29
28
|
class_name: 'RailsMiniProfiler::ProfiledRequest',
|
30
29
|
foreign_key: :rmp_profiled_request_id
|
31
|
-
|
32
|
-
class << self
|
33
|
-
def find_sti_class(name)
|
34
|
-
subclasses = {
|
35
|
-
'process_action.action_controller' => RailsMiniProfiler::ControllerTrace,
|
36
|
-
'sql.active_record' => RailsMiniProfiler::SequelTrace,
|
37
|
-
'instantiation.active_record' => RailsMiniProfiler::InstantiationTrace,
|
38
|
-
'rails_mini_profiler.total_time' => RailsMiniProfiler::RmpTrace,
|
39
|
-
'render_template.action_view' => RailsMiniProfiler::RenderTemplateTrace,
|
40
|
-
'render_partial.action_view' => RailsMiniProfiler::RenderPartialTrace
|
41
|
-
}
|
42
|
-
subclasses[name] || self
|
43
|
-
end
|
44
|
-
end
|
45
30
|
end
|
46
31
|
end
|
@@ -6,10 +6,18 @@ module RailsMiniProfiler
|
|
6
6
|
'Action Controller'
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def view_runtime
|
10
|
+
payload['view_runtime']
|
11
|
+
end
|
12
|
+
|
13
|
+
def db_runtime
|
14
|
+
payload['db_runtime']
|
15
|
+
end
|
16
|
+
|
17
|
+
def content
|
10
18
|
content_tag('div') do
|
11
19
|
content_tag('pre', class: 'trace-payload') do
|
12
|
-
content_tag(:div, "View Time: #{
|
20
|
+
content_tag(:div, "View Time: #{view_runtime} ms, DB Time: #{db_runtime} ms",
|
13
21
|
class: 'sequel-trace-query')
|
14
22
|
end
|
15
23
|
end
|
@@ -3,12 +3,24 @@
|
|
3
3
|
module RailsMiniProfiler
|
4
4
|
class InstantiationTracePresenter < TracePresenter
|
5
5
|
def label
|
6
|
-
"#{
|
6
|
+
"#{class_name} Instantiation"
|
7
|
+
end
|
8
|
+
|
9
|
+
def class_name
|
10
|
+
payload['class_name']
|
11
|
+
end
|
12
|
+
|
13
|
+
def record_count
|
14
|
+
payload['record_count']
|
15
|
+
end
|
16
|
+
|
17
|
+
def db_runtime
|
18
|
+
payload['db_runtime']
|
7
19
|
end
|
8
20
|
|
9
21
|
def description
|
10
|
-
record_string = 'Record'.pluralize(
|
11
|
-
"Instantiated #{
|
22
|
+
record_string = 'Record'.pluralize(record_count)
|
23
|
+
"Instantiated #{record_count} #{class_name} #{record_string}"
|
12
24
|
end
|
13
25
|
end
|
14
26
|
end
|
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
4
|
class RenderPartialTracePresenter < TracePresenter
|
5
|
+
def identifier
|
6
|
+
payload['identifier']
|
7
|
+
end
|
8
|
+
|
5
9
|
def label
|
6
10
|
root = Rails.root.to_s.split('/').to_set
|
7
|
-
|
8
|
-
(root ^
|
11
|
+
id = identifier.split('/').to_set
|
12
|
+
(root ^ id).drop(2).join('/').reverse.truncate(30).reverse
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
4
|
class RenderTemplateTracePresenter < TracePresenter
|
5
|
+
def identifier
|
6
|
+
payload['identifier']
|
7
|
+
end
|
8
|
+
|
5
9
|
def label
|
6
10
|
root = Rails.root.to_s.split('/').to_set
|
7
|
-
|
8
|
-
(root ^
|
11
|
+
id = identifier.split('/').to_set
|
12
|
+
(root ^ id).drop(2).join('/').reverse.truncate(30).reverse
|
9
13
|
end
|
10
14
|
|
11
15
|
def description
|
@@ -6,14 +6,26 @@ module RailsMiniProfiler
|
|
6
6
|
sql_description
|
7
7
|
end
|
8
8
|
|
9
|
+
def name
|
10
|
+
payload['name']
|
11
|
+
end
|
12
|
+
|
13
|
+
def sql
|
14
|
+
payload['sql']
|
15
|
+
end
|
16
|
+
|
17
|
+
def binds
|
18
|
+
payload['binds']
|
19
|
+
end
|
20
|
+
|
9
21
|
alias description label
|
10
22
|
|
11
|
-
def
|
23
|
+
def content
|
12
24
|
return nil if transaction?
|
13
25
|
|
14
26
|
content_tag('div') do
|
15
27
|
content_tag('pre', class: 'trace-payload') do
|
16
|
-
content_tag(:div,
|
28
|
+
content_tag(:div, sql, class: 'sequel-trace-query')
|
17
29
|
end + binding_content
|
18
30
|
end
|
19
31
|
end
|
@@ -57,9 +69,9 @@ module RailsMiniProfiler
|
|
57
69
|
end
|
58
70
|
|
59
71
|
def simple_binds
|
60
|
-
return [] if
|
72
|
+
return [] if binds.nil? || binds.empty?
|
61
73
|
|
62
|
-
|
74
|
+
binds.each_with_object({}) do |hash, object|
|
63
75
|
name = hash['name']
|
64
76
|
value = hash['value']
|
65
77
|
object[name] = value
|
@@ -22,7 +22,7 @@ RailsMiniProfiler.configure do |config|
|
|
22
22
|
# Configure the Rails Mini Profiler User Interface
|
23
23
|
# config.ui.badge_enabled = true
|
24
24
|
# config.ui.badge_position = 'top-left'
|
25
|
-
# config.ui.base_controller =
|
25
|
+
# config.ui.base_controller = ApplicationController
|
26
26
|
# config.ui.page_size = 25
|
27
27
|
# config.ui.webpacker_enabled = true
|
28
28
|
|
@@ -23,30 +23,39 @@ module RailsMiniProfiler
|
|
23
23
|
#
|
24
24
|
# @return [ResponseWrapper] The modified response
|
25
25
|
def render
|
26
|
-
|
27
|
-
return @original_response unless content_type =~ %r{text/html}
|
28
|
-
|
29
|
-
return @original_response unless @configuration.ui.badge_enabled
|
26
|
+
return @original_response unless render_badge?
|
30
27
|
|
31
|
-
modified_response =
|
28
|
+
modified_response = ResponseWrapper.new([], @original_response.status, @original_response.headers)
|
32
29
|
modified_response.write(modified_body)
|
33
30
|
modified_response.finish
|
34
31
|
|
35
|
-
|
36
|
-
response.close if response.respond_to?(:close)
|
32
|
+
@original_response.close if @original_response.respond_to?(:close)
|
37
33
|
|
38
|
-
|
39
|
-
@original_response.headers,
|
40
|
-
modified_response)
|
34
|
+
modified_response
|
41
35
|
end
|
42
36
|
|
43
37
|
private
|
44
38
|
|
39
|
+
def render_badge?
|
40
|
+
content_type = @original_response.headers['Content-Type']
|
41
|
+
unless content_type =~ %r{text/html}
|
42
|
+
RailsMiniProfiler.logger.debug("badge not rendered, response has content type #{content_type}")
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
|
46
|
+
unless @configuration.ui.badge_enabled
|
47
|
+
RailsMiniProfiler.logger.debug('badge not rendered, disabled in configuration')
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
45
54
|
# Modify the body of the original response
|
46
55
|
#
|
47
56
|
# @return String The modified body
|
48
57
|
def modified_body
|
49
|
-
body = @original_response.
|
58
|
+
body = @original_response.body
|
50
59
|
index = body.rindex(%r{</body>}i) || body.rindex(%r{</html>}i)
|
51
60
|
if index
|
52
61
|
body.dup.insert(index, badge_content)
|
@@ -35,10 +35,11 @@ module RailsMiniProfiler
|
|
35
35
|
|
36
36
|
attr_accessor :badge_enabled,
|
37
37
|
:badge_position,
|
38
|
-
:base_controller,
|
39
38
|
:page_size,
|
40
39
|
:webpacker_enabled
|
41
40
|
|
41
|
+
attr_writer :base_controller
|
42
|
+
|
42
43
|
def initialize(**kwargs)
|
43
44
|
defaults!
|
44
45
|
kwargs.each { |key, value| instance_variable_set("@#{key}", value) }
|
@@ -48,11 +49,18 @@ module RailsMiniProfiler
|
|
48
49
|
def defaults!
|
49
50
|
@badge_enabled = true
|
50
51
|
@badge_position = 'top-left'
|
51
|
-
|
52
|
+
# We must not set base controller during when the app loads, aka during autoload time, as we are loading
|
53
|
+
# constants. Rather, we only load the base controller constants when any engine controllers are first initialized
|
54
|
+
# and call #base_controller
|
55
|
+
@base_controller = nil
|
52
56
|
@page_size = 25
|
53
57
|
@webpacker_enabled = true
|
54
58
|
end
|
55
59
|
|
60
|
+
def base_controller
|
61
|
+
@base_controller ||= default_base_controller
|
62
|
+
end
|
63
|
+
|
56
64
|
def default_base_controller
|
57
65
|
app_controller_exists = class_exists?('::ApplicationController')
|
58
66
|
return ::ApplicationController if app_controller_exists && ::ApplicationController < ActionController::Base
|
@@ -18,6 +18,8 @@ module RailsMiniProfiler
|
|
18
18
|
# @return [Array<String>] a list of regex patterns for paths to skip
|
19
19
|
# @!attribute storage
|
20
20
|
# @return [Storage] the storage configuration
|
21
|
+
# @!attribute tracers
|
22
|
+
# @return [Array<Symbol>] the list of enabled tracers
|
21
23
|
# @!attribute ui
|
22
24
|
# @return [UserInterface] the ui configuration
|
23
25
|
# @!attribute user_provider
|
@@ -30,6 +32,7 @@ module RailsMiniProfiler
|
|
30
32
|
:flamegraph_sample_rate,
|
31
33
|
:skip_paths,
|
32
34
|
:storage,
|
35
|
+
:tracers,
|
33
36
|
:ui,
|
34
37
|
:user_provider
|
35
38
|
|
@@ -46,6 +49,7 @@ module RailsMiniProfiler
|
|
46
49
|
@logger = RailsMiniProfiler::Logger.new(Rails.logger)
|
47
50
|
@skip_paths = []
|
48
51
|
@storage = Storage.new
|
52
|
+
@tracers = %i[controller instantiation sequel view rmp]
|
49
53
|
@ui = UserInterface.new
|
50
54
|
@user_provider = proc { |env| Rack::Request.new(env).ip }
|
51
55
|
end
|
@@ -5,21 +5,23 @@ module RailsMiniProfiler
|
|
5
5
|
def initialize(app)
|
6
6
|
@app = app
|
7
7
|
@config = RailsMiniProfiler.configuration
|
8
|
-
|
8
|
+
@registry = Tracers::Registry.setup!(@config)
|
9
|
+
Tracers::Subscriptions.setup!(@registry.tracers.keys) { |trace| track_trace(trace) }
|
10
|
+
@trace_factory = Tracers::TraceFactory.new(@registry)
|
9
11
|
end
|
10
12
|
|
11
13
|
def call(env)
|
12
|
-
request = RequestWrapper.new(env
|
14
|
+
request = RequestWrapper.new(env)
|
13
15
|
request_context = RequestContext.new(request)
|
14
16
|
return @app.call(env) unless Guard.new(request_context).profile?
|
15
17
|
|
16
|
-
request_context.profiled_request = ProfiledRequest.new
|
17
18
|
result = with_tracing(request_context) { profile(request_context) }
|
18
19
|
return result unless request_context.authorized?
|
19
20
|
|
20
|
-
|
21
|
+
status, headers, body = result
|
22
|
+
request_context.response = ResponseWrapper.new(body, status, headers)
|
21
23
|
complete!(request_context)
|
22
|
-
request_context.saved? ? render_response(request_context) : result
|
24
|
+
request_context.saved? ? render_response(request_context).to_a : result
|
23
25
|
ensure
|
24
26
|
User.current_user = nil
|
25
27
|
end
|
@@ -35,14 +37,13 @@ module RailsMiniProfiler
|
|
35
37
|
def track_trace(event)
|
36
38
|
return if traces.nil?
|
37
39
|
|
38
|
-
trace =
|
39
|
-
traces.append(trace) unless trace.is_a?(RailsMiniProfiler::
|
40
|
+
trace = @trace_factory.create(event)
|
41
|
+
traces.append(trace) unless trace.is_a?(RailsMiniProfiler::Tracers::NullTrace)
|
40
42
|
end
|
41
43
|
|
42
44
|
private
|
43
45
|
|
44
46
|
def complete!(request_context)
|
45
|
-
request_context.complete_profiling!
|
46
47
|
request_context.save_results!
|
47
48
|
true
|
48
49
|
rescue ActiveRecord::ActiveRecordError => e
|
@@ -54,8 +55,7 @@ module RailsMiniProfiler
|
|
54
55
|
redirect = Redirect.new(request_context).render
|
55
56
|
return redirect if redirect
|
56
57
|
|
57
|
-
|
58
|
-
[modified_response.status, modified_response.headers, modified_response.response]
|
58
|
+
Badge.new(request_context).render
|
59
59
|
end
|
60
60
|
|
61
61
|
def profile(request_context)
|
@@ -10,7 +10,7 @@ module RailsMiniProfiler
|
|
10
10
|
# @return [RequestWrapper] the request as sent to the application
|
11
11
|
# @!attribute response
|
12
12
|
# @return [ResponseWrapper] the response as rendered by the application
|
13
|
-
# @!attribute profiled_request
|
13
|
+
# # @!attribute profiled_request
|
14
14
|
# @return [ProfiledRequest] the profiling data as gathered during profiling
|
15
15
|
# @!attribute traces
|
16
16
|
# @return [Array<Models::Trace>] trace wrappers gathered during profiling
|
@@ -19,8 +19,10 @@ module RailsMiniProfiler
|
|
19
19
|
class RequestContext
|
20
20
|
attr_reader :request
|
21
21
|
|
22
|
-
attr_accessor :response, :
|
22
|
+
attr_accessor :response, :traces, :flamegraph, :profiled_request
|
23
23
|
|
24
|
+
# Create a new request context
|
25
|
+
#
|
24
26
|
# @param request [RequestWrapper] the request as sent to the application
|
25
27
|
def initialize(request)
|
26
28
|
@request = request
|
@@ -36,39 +38,41 @@ module RailsMiniProfiler
|
|
36
38
|
@authorized ||= User.get(@env).present?
|
37
39
|
end
|
38
40
|
|
39
|
-
# Completes profiling, setting all data and preparing for saving it.
|
40
|
-
def complete_profiling!
|
41
|
-
profiled_request.user_id = User.current_user
|
42
|
-
profiled_request.request = @request
|
43
|
-
profiled_request.response = @response
|
44
|
-
total_time = traces.find { |trace| trace.name == 'rails_mini_profiler.total_time' }
|
45
|
-
profiled_request.total_time = total_time
|
46
|
-
@complete = true
|
47
|
-
end
|
48
|
-
|
49
41
|
# Save profiling data in the database.
|
50
42
|
#
|
51
43
|
# This will store the profiled request, as well as any attached traces and Flamgraph.
|
52
44
|
def save_results!
|
53
45
|
ActiveRecord::Base.transaction do
|
46
|
+
profiled_request = build_profiled_request
|
54
47
|
profiled_request.flamegraph = RailsMiniProfiler::Flamegraph.new(data: flamegraph) if flamegraph.present?
|
55
48
|
profiled_request.save
|
56
|
-
insert_traces unless traces.empty?
|
49
|
+
insert_traces(profiled_request) unless traces.empty?
|
50
|
+
@profiled_request = profiled_request
|
57
51
|
end
|
58
52
|
@saved = true
|
59
53
|
end
|
60
54
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
55
|
+
# Check if profiling results have been saved
|
56
|
+
#
|
57
|
+
# @return [Boolean] true if profiling results have been saved
|
65
58
|
def saved?
|
66
59
|
@saved
|
67
60
|
end
|
68
61
|
|
69
62
|
private
|
70
63
|
|
71
|
-
def
|
64
|
+
def build_profiled_request
|
65
|
+
new_profiled_request = ProfiledRequest.new
|
66
|
+
new_profiled_request.user_id = User.current_user
|
67
|
+
new_profiled_request.request = @request
|
68
|
+
new_profiled_request.response = @response
|
69
|
+
total_time = traces.find { |trace| trace.name == 'rails_mini_profiler.total_time' }
|
70
|
+
new_profiled_request.total_time = total_time
|
71
|
+
new_profiled_request
|
72
|
+
end
|
73
|
+
|
74
|
+
# We insert multiple at once for performance reasons.
|
75
|
+
def insert_traces(profiled_request)
|
72
76
|
return if traces.empty?
|
73
77
|
|
74
78
|
timestamp = Time.zone.now
|
@@ -1,69 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
# A convenience wrapper
|
5
|
-
#
|
6
|
-
# @!attribute body
|
7
|
-
# @return [String] the request body
|
8
|
-
# @!attribute method
|
9
|
-
# @return [String] the request method
|
10
|
-
# @!attribute path
|
11
|
-
# @return [String] the request path
|
12
|
-
# @!attribute query_string
|
13
|
-
# @return [String] the request query string
|
14
|
-
# @!attribute env
|
15
|
-
# @return [Rack::Env] the original env
|
4
|
+
# A convenience wrapper extending {Rack::Request}
|
16
5
|
#
|
17
6
|
# @api private
|
18
|
-
class RequestWrapper
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
7
|
+
class RequestWrapper < Rack::Request
|
8
|
+
# Convenience method to read the request body as String
|
9
|
+
#
|
10
|
+
# @return [String] the request body
|
11
|
+
def body
|
12
|
+
return '' unless super
|
24
13
|
|
25
|
-
|
26
|
-
|
27
|
-
|
14
|
+
body = super.read
|
15
|
+
super.rewind
|
16
|
+
body
|
28
17
|
end
|
29
18
|
|
30
19
|
# The request headers
|
31
20
|
#
|
32
|
-
# @return [Hash] the headers
|
21
|
+
# @return [Hash] the request headers
|
33
22
|
def headers
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def setup
|
40
|
-
@env = @attributes[:env] || {}
|
41
|
-
@method = setup_method
|
42
|
-
@query_string = setup_query_string
|
43
|
-
@path = setup_path
|
44
|
-
@body = setup_body
|
45
|
-
end
|
46
|
-
|
47
|
-
def setup_method
|
48
|
-
@attributes[:method] || @env['REQUEST_METHOD'] || 'GET'
|
49
|
-
end
|
50
|
-
|
51
|
-
def setup_query_string
|
52
|
-
@attributes[:query_string] || @env['QUERY_STRING'] || ''
|
53
|
-
end
|
54
|
-
|
55
|
-
def setup_path
|
56
|
-
@attributes[:path] || @env['PATH_INFO'] || '/'
|
57
|
-
end
|
58
|
-
|
59
|
-
def setup_body
|
60
|
-
return @attributes[:body] if @attributes[:body]
|
61
|
-
|
62
|
-
return '' unless @env['rack.input']
|
63
|
-
|
64
|
-
body = @env['rack.input'].read
|
65
|
-
@env['rack.input'].rewind
|
66
|
-
body
|
23
|
+
env.select { |k, _v| k.start_with? 'HTTP_' } || {}
|
67
24
|
end
|
68
25
|
end
|
69
26
|
end
|
@@ -1,24 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
# A convenience wrapper extending {Rack::Response}
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
class ResponseWrapper < Rack::Response
|
8
|
+
# Return the response body as String
|
9
|
+
#
|
10
|
+
# Depending on preceding middleware, response bodies may be Strings, Arrays or literally anything else. This method
|
11
|
+
# converts whatever it is to a string so we can store it later.
|
12
|
+
#
|
13
|
+
# @return [String] of the response body
|
14
14
|
def body
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
body = super
|
16
|
+
case body
|
17
|
+
when String
|
18
|
+
body
|
19
|
+
when Array
|
20
|
+
body.join
|
21
|
+
when ActionDispatch::Response::RackBody
|
22
|
+
body.body
|
23
|
+
else
|
24
|
+
''
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
def json?
|
@@ -1,8 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
module
|
4
|
+
module Tracers
|
5
5
|
class ControllerTracer < Tracer
|
6
|
+
class << self
|
7
|
+
def subscribes_to
|
8
|
+
'process_action.action_controller'
|
9
|
+
end
|
10
|
+
|
11
|
+
def build_from(event)
|
12
|
+
new(event).trace
|
13
|
+
end
|
14
|
+
|
15
|
+
def presents
|
16
|
+
ControllerTracePresenter
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
6
20
|
def trace
|
7
21
|
@event[:payload] = @event[:payload]
|
8
22
|
.slice(:view_runtime, :db_runtime)
|