rack-mini-profiler 1.0.1 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +115 -20
- data/README.md +126 -45
- data/lib/enable_rails_patches.rb +5 -0
- data/lib/html/dot.1.1.2.min.js +2 -0
- data/lib/html/includes.css +136 -35
- data/lib/html/includes.js +1400 -1009
- data/lib/html/includes.scss +546 -441
- data/lib/html/includes.tmpl +231 -148
- data/lib/html/pretty-print.js +810 -0
- data/lib/html/profile_handler.js +1 -1
- data/lib/html/rack-mini-profiler.css +3 -0
- data/lib/html/rack-mini-profiler.js +2 -0
- data/lib/html/share.html +0 -1
- data/lib/html/speedscope/LICENSE +21 -0
- data/lib/html/speedscope/README.md +3 -0
- data/lib/html/speedscope/demangle-cpp.1768f4cc.js +4 -0
- data/lib/html/speedscope/favicon-16x16.f74b3187.png +0 -0
- data/lib/html/speedscope/favicon-32x32.bc503437.png +0 -0
- data/lib/html/speedscope/file-format-schema.json +324 -0
- data/lib/html/speedscope/fonts/source-code-pro-regular.css +8 -0
- data/lib/html/speedscope/fonts/source-code-pro-v13-regular.woff +0 -0
- data/lib/html/speedscope/fonts/source-code-pro-v13-regular.woff2 +0 -0
- data/lib/html/speedscope/import.cf0fa83f.js +115 -0
- data/lib/html/speedscope/index.html +2 -0
- data/lib/html/speedscope/release.txt +3 -0
- data/lib/html/speedscope/reset.8c46b7a1.css +2 -0
- data/lib/html/speedscope/source-map.438fa06b.js +24 -0
- data/lib/html/speedscope/speedscope.44364064.js +200 -0
- data/lib/html/vendor.js +848 -0
- data/lib/mini_profiler/asset_version.rb +3 -2
- data/lib/mini_profiler/client_settings.rb +13 -5
- data/lib/mini_profiler/config.rb +43 -5
- data/lib/mini_profiler/gc_profiler.rb +1 -1
- data/lib/mini_profiler/profiler.rb +310 -42
- data/lib/mini_profiler/profiling_methods.rb +13 -8
- data/lib/mini_profiler/snapshots_transporter.rb +109 -0
- data/lib/mini_profiler/storage/abstract_store.rb +79 -1
- data/lib/mini_profiler/storage/file_store.rb +3 -3
- data/lib/mini_profiler/storage/memcache_store.rb +2 -0
- data/lib/mini_profiler/storage/memory_store.rb +54 -5
- data/lib/mini_profiler/storage/redis_store.rb +136 -2
- data/lib/mini_profiler/timer_struct/custom.rb +1 -0
- data/lib/mini_profiler/timer_struct/page.rb +60 -4
- data/lib/mini_profiler/timer_struct/request.rb +53 -11
- data/lib/mini_profiler/timer_struct/sql.rb +4 -2
- data/lib/mini_profiler/version.rb +1 -1
- data/lib/mini_profiler_rails/railtie.rb +88 -7
- data/lib/mini_profiler_rails/railtie_methods.rb +61 -0
- data/lib/patches/db/activerecord.rb +1 -12
- data/lib/patches/db/mongo.rb +1 -1
- data/lib/patches/db/moped.rb +1 -1
- data/lib/patches/db/mysql2.rb +4 -27
- data/lib/patches/db/mysql2/alias_method.rb +30 -0
- data/lib/patches/db/mysql2/prepend.rb +34 -0
- data/lib/patches/db/plucky.rb +4 -4
- data/lib/patches/net_patches.rb +18 -8
- data/lib/patches/sql_patches.rb +13 -5
- data/lib/prepend_mysql2_patch.rb +5 -0
- data/lib/prepend_net_http_patch.rb +5 -0
- data/lib/rack-mini-profiler.rb +1 -1
- data/rack-mini-profiler.gemspec +15 -6
- metadata +150 -31
- data/lib/html/jquery.1.7.1.js +0 -4
- data/lib/html/jquery.tmpl.js +0 -486
- data/lib/html/list.css +0 -9
- data/lib/html/list.js +0 -38
- data/lib/html/list.tmpl +0 -34
@@ -10,6 +10,53 @@ module Rack
|
|
10
10
|
# :has_many TimerStruct::Sql children
|
11
11
|
# :has_many TimerStruct::Custom children
|
12
12
|
class Page < TimerStruct::Base
|
13
|
+
class << self
|
14
|
+
def from_hash(hash)
|
15
|
+
hash = symbolize_hash(hash)
|
16
|
+
if hash.key?(:custom_timing_names)
|
17
|
+
hash[:custom_timing_names] = []
|
18
|
+
end
|
19
|
+
hash.delete(:started_formatted)
|
20
|
+
if hash.key?(:duration_milliseconds)
|
21
|
+
hash[:duration_milliseconds] = 0
|
22
|
+
end
|
23
|
+
page = self.allocate
|
24
|
+
page.instance_variable_set(:@attributes, hash)
|
25
|
+
page
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def symbolize_hash(hash)
|
31
|
+
new_hash = {}
|
32
|
+
hash.each do |k, v|
|
33
|
+
sym_k = String === k ? k.to_sym : k
|
34
|
+
if Hash === v
|
35
|
+
new_hash[sym_k] = symbolize_hash(v)
|
36
|
+
elsif Array === v
|
37
|
+
new_hash[sym_k] = symbolize_array(v)
|
38
|
+
else
|
39
|
+
new_hash[sym_k] = v
|
40
|
+
end
|
41
|
+
end
|
42
|
+
new_hash
|
43
|
+
end
|
44
|
+
|
45
|
+
def symbolize_array(array)
|
46
|
+
array.map do |item|
|
47
|
+
if Array === item
|
48
|
+
symbolize_array(item)
|
49
|
+
elsif Hash === item
|
50
|
+
symbolize_hash(item)
|
51
|
+
else
|
52
|
+
item
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
attr_reader :attributes
|
59
|
+
|
13
60
|
def initialize(env)
|
14
61
|
timer_id = MiniProfiler.generate_id
|
15
62
|
page_name = env['PATH_INFO']
|
@@ -39,8 +86,13 @@ module Rack
|
|
39
86
|
executed_scalars: 0,
|
40
87
|
executed_non_queries: 0,
|
41
88
|
custom_timing_names: [],
|
42
|
-
custom_timing_stats: {}
|
89
|
+
custom_timing_stats: {},
|
90
|
+
custom_fields: {},
|
91
|
+
has_flamegraph: false,
|
92
|
+
flamegraph: nil
|
43
93
|
)
|
94
|
+
self[:request_method] = env['REQUEST_METHOD']
|
95
|
+
self[:request_path] = env['PATH_INFO']
|
44
96
|
name = "#{env['REQUEST_METHOD']} http://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{env['SCRIPT_NAME']}#{env['PATH_INFO']}"
|
45
97
|
self[:root] = TimerStruct::Request.createRoot(name, self)
|
46
98
|
end
|
@@ -61,17 +113,21 @@ module Rack
|
|
61
113
|
@attributes[:root]
|
62
114
|
end
|
63
115
|
|
116
|
+
def attributes_to_serialize
|
117
|
+
@attributes.keys - [:flamegraph]
|
118
|
+
end
|
119
|
+
|
64
120
|
def to_json(*a)
|
65
|
-
::JSON.generate(@attributes.merge(
|
121
|
+
::JSON.generate(@attributes.slice(*attributes_to_serialize).merge(extra_json))
|
66
122
|
end
|
67
123
|
|
68
124
|
def as_json(options = nil)
|
69
|
-
super(options).merge!(extra_json)
|
125
|
+
super(options).slice(*attributes_to_serialize.map(&:to_s)).merge!(extra_json)
|
70
126
|
end
|
71
127
|
|
72
128
|
def extra_json
|
73
129
|
{
|
74
|
-
|
130
|
+
started_formatted: '/Date(%d)/' % @attributes[:started_at],
|
75
131
|
duration_milliseconds: @attributes[:root][:duration_milliseconds],
|
76
132
|
custom_timing_names: @attributes[:custom_timing_stats].keys.sort
|
77
133
|
}
|
@@ -11,7 +11,7 @@ module Rack
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
attr_accessor :children_duration
|
14
|
+
attr_accessor :children_duration, :start, :parent
|
15
15
|
|
16
16
|
def initialize(name, page, parent)
|
17
17
|
start_millis = (Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000).to_i - page[:started]
|
@@ -62,10 +62,6 @@ module Rack
|
|
62
62
|
self[:start_milliseconds]
|
63
63
|
end
|
64
64
|
|
65
|
-
def start
|
66
|
-
@start
|
67
|
-
end
|
68
|
-
|
69
65
|
def depth
|
70
66
|
self[:depth]
|
71
67
|
end
|
@@ -91,6 +87,20 @@ module Rack
|
|
91
87
|
end
|
92
88
|
end
|
93
89
|
|
90
|
+
def move_child(child, destination)
|
91
|
+
if index = self[:children].index(child)
|
92
|
+
self[:children].slice!(index)
|
93
|
+
self[:has_children] = self[:children].size > 0
|
94
|
+
|
95
|
+
destination[:children].push(child)
|
96
|
+
destination[:has_children] = true
|
97
|
+
|
98
|
+
child[:parent_timing_id] = destination[:id]
|
99
|
+
child.parent = destination
|
100
|
+
child.adjust_depth
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
94
104
|
def add_sql(query, elapsed_ms, page, params = nil, skip_backtrace = false, full_backtrace = false)
|
95
105
|
TimerStruct::Sql.new(query, elapsed_ms, page, self, params, skip_backtrace, full_backtrace).tap do |timer|
|
96
106
|
self[:sql_timings].push(timer)
|
@@ -102,6 +112,19 @@ module Rack
|
|
102
112
|
end
|
103
113
|
end
|
104
114
|
|
115
|
+
def move_sql(sql, destination)
|
116
|
+
if index = self[:sql_timings].index(sql)
|
117
|
+
self[:sql_timings].slice!(index)
|
118
|
+
self[:has_sql_timings] = self[:sql_timings].size > 0
|
119
|
+
self[:sql_timings_duration_milliseconds] -= sql[:duration_milliseconds]
|
120
|
+
destination[:sql_timings].push(sql)
|
121
|
+
destination[:has_sql_timings] = true
|
122
|
+
destination[:sql_timings_duration_milliseconds] += sql[:duration_milliseconds]
|
123
|
+
sql[:parent_timing_id] = destination[:id]
|
124
|
+
sql.parent = destination
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
105
128
|
def add_custom(type, elapsed_ms, page)
|
106
129
|
TimerStruct::Custom.new(type, elapsed_ms, page, self).tap do |timer|
|
107
130
|
timer[:parent_timing_id] = self[:id]
|
@@ -119,18 +142,37 @@ module Rack
|
|
119
142
|
end
|
120
143
|
end
|
121
144
|
|
145
|
+
def move_custom(type, custom, destination)
|
146
|
+
if index = self[:custom_timings][type]&.index(custom)
|
147
|
+
custom[:parent_timing_id] = destination[:id]
|
148
|
+
custom.parent = destination
|
149
|
+
self[:custom_timings][type].slice!(index)
|
150
|
+
if self[:custom_timings][type].size == 0
|
151
|
+
self[:custom_timings].delete(type)
|
152
|
+
self[:custom_timing_stats].delete(type)
|
153
|
+
else
|
154
|
+
self[:custom_timing_stats][type][:count] -= 1
|
155
|
+
self[:custom_timing_stats][type][:duration] -= custom[:duration_milliseconds]
|
156
|
+
end
|
157
|
+
destination[:custom_timings][type] ||= []
|
158
|
+
destination[:custom_timings][type].push(custom)
|
159
|
+
destination[:custom_timing_stats][type] ||= { count: 0, duration: 0.0 }
|
160
|
+
destination[:custom_timing_stats][type][:count] += 1
|
161
|
+
destination[:custom_timing_stats][type][:duration] += custom[:duration_milliseconds]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
122
165
|
def record_time(milliseconds = nil)
|
123
166
|
milliseconds ||= (Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start) * 1000
|
124
167
|
self[:duration_milliseconds] = milliseconds
|
125
168
|
self[:is_trivial] = true if milliseconds < self[:trivial_duration_threshold_milliseconds]
|
126
|
-
self[:duration_without_children_milliseconds] = milliseconds -
|
127
|
-
|
128
|
-
if @parent
|
129
|
-
@parent.children_duration += milliseconds
|
130
|
-
end
|
131
|
-
|
169
|
+
self[:duration_without_children_milliseconds] = milliseconds - self[:children].sum(&:duration_ms)
|
132
170
|
end
|
133
171
|
|
172
|
+
def adjust_depth
|
173
|
+
self[:depth] = self.parent ? self.parent[:depth] + 1 : 0
|
174
|
+
self[:children].each(&:adjust_depth)
|
175
|
+
end
|
134
176
|
end
|
135
177
|
end
|
136
178
|
end
|
@@ -6,6 +6,8 @@ module Rack
|
|
6
6
|
# Timing system for a SQL query
|
7
7
|
module TimerStruct
|
8
8
|
class Sql < TimerStruct::Base
|
9
|
+
attr_accessor :parent
|
10
|
+
|
9
11
|
def initialize(query, duration_ms, page, parent, params = nil, skip_backtrace = false, full_backtrace = false)
|
10
12
|
|
11
13
|
stack_trace = nil
|
@@ -36,12 +38,12 @@ module Rack
|
|
36
38
|
start_millis = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000).to_i - page[:started]) - duration_ms
|
37
39
|
super(
|
38
40
|
execute_type: 3, # TODO
|
39
|
-
formatted_command_string: query,
|
41
|
+
formatted_command_string: query ? ERB::Util.html_escape(query) : nil,
|
40
42
|
stack_trace_snippet: stack_trace,
|
41
43
|
start_milliseconds: start_millis,
|
42
44
|
duration_milliseconds: duration_ms,
|
43
45
|
first_fetch_duration_milliseconds: duration_ms,
|
44
|
-
parameters: trim_binds(params),
|
46
|
+
parameters: query ? trim_binds(params) : nil,
|
45
47
|
parent_timing_id: nil,
|
46
48
|
is_duplicate: false
|
47
49
|
)
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require_relative './railtie_methods'
|
4
5
|
|
5
6
|
module Rack::MiniProfilerRails
|
7
|
+
extend Rack::MiniProfilerRailsMethods
|
6
8
|
|
7
9
|
# call direct if needed to do a defer init
|
8
10
|
def self.initialize!(app)
|
@@ -28,10 +30,12 @@ module Rack::MiniProfilerRails
|
|
28
30
|
|
29
31
|
if serves_static_assets?(app)
|
30
32
|
c.skip_paths << app.config.assets.prefix
|
33
|
+
wp_assets_path = get_webpacker_assets_path()
|
34
|
+
c.skip_paths << wp_assets_path if wp_assets_path
|
31
35
|
end
|
32
36
|
|
33
37
|
unless Rails.env.development? || Rails.env.test?
|
34
|
-
c.authorization_mode = :
|
38
|
+
c.authorization_mode = :allow_authorized
|
35
39
|
end
|
36
40
|
|
37
41
|
if Rails.logger
|
@@ -55,16 +59,92 @@ module Rack::MiniProfilerRails
|
|
55
59
|
|
56
60
|
# Install the Middleware
|
57
61
|
app.middleware.insert(0, Rack::MiniProfiler)
|
62
|
+
c.enable_advanced_debugging_tools = Rails.env.development?
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
if ::Rack::MiniProfiler.patch_rails?
|
65
|
+
# Attach to various Rails methods
|
66
|
+
ActiveSupport.on_load(:action_controller) do
|
67
|
+
::Rack::MiniProfiler.profile_method(ActionController::Base, :process) { |action| "Executing action: #{action}" }
|
68
|
+
end
|
69
|
+
|
70
|
+
ActiveSupport.on_load(:action_view) do
|
71
|
+
::Rack::MiniProfiler.profile_method(ActionView::Template, :render) { |x, y| "Rendering: #{@virtual_path}" }
|
72
|
+
end
|
73
|
+
else
|
74
|
+
subscribe("start_processing.action_controller") do |name, start, finish, id, payload|
|
75
|
+
next if !should_measure?
|
76
|
+
|
77
|
+
current = Rack::MiniProfiler.current
|
78
|
+
description = "Executing action: #{payload[:action]}"
|
79
|
+
Thread.current[get_key(payload)] = current.current_timer
|
80
|
+
Rack::MiniProfiler.current.current_timer = current.current_timer.add_child(description)
|
81
|
+
end
|
82
|
+
|
83
|
+
subscribe("process_action.action_controller") do |name, start, finish, id, payload|
|
84
|
+
next if !should_measure?
|
85
|
+
|
86
|
+
key = get_key(payload)
|
87
|
+
parent_timer = Thread.current[key]
|
88
|
+
next if !parent_timer
|
89
|
+
|
90
|
+
Thread.current[key] = nil
|
91
|
+
Rack::MiniProfiler.current.current_timer.record_time
|
92
|
+
Rack::MiniProfiler.current.current_timer = parent_timer
|
93
|
+
end
|
94
|
+
|
95
|
+
subscribe("render_partial.action_view") do |name, start, finish, id, payload|
|
96
|
+
render_notification_handler(shorten_identifier(payload[:identifier]), finish, start)
|
97
|
+
end
|
98
|
+
|
99
|
+
subscribe("render_template.action_view") do |name, start, finish, id, payload|
|
100
|
+
render_notification_handler(shorten_identifier(payload[:identifier]), finish, start)
|
101
|
+
end
|
102
|
+
|
103
|
+
if Rack::MiniProfiler.subscribe_sql_active_record
|
104
|
+
# we don't want to subscribe if we've already patched a DB driver
|
105
|
+
# otherwise we would end up with 2 records for every query
|
106
|
+
subscribe("sql.active_record") do |name, start, finish, id, payload|
|
107
|
+
next if !should_measure?
|
108
|
+
next if payload[:name] =~ /SCHEMA/ && Rack::MiniProfiler.config.skip_schema_queries
|
109
|
+
|
110
|
+
Rack::MiniProfiler.record_sql(
|
111
|
+
payload[:sql],
|
112
|
+
(finish - start) * 1000,
|
113
|
+
Rack::MiniProfiler.binds_to_params(payload[:binds])
|
114
|
+
)
|
115
|
+
end
|
116
|
+
end
|
62
117
|
end
|
63
|
-
|
64
|
-
|
118
|
+
@already_initialized = true
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.create_engine
|
122
|
+
return if defined?(Rack::MiniProfilerRails::Engine)
|
123
|
+
klass = Class.new(::Rails::Engine) do
|
124
|
+
engine_name 'rack-mini-profiler'
|
125
|
+
config.assets.paths << File.expand_path('../../html', __FILE__)
|
126
|
+
config.assets.precompile << 'rack-mini-profiler.js'
|
127
|
+
config.assets.precompile << 'rack-mini-profiler.css'
|
65
128
|
end
|
129
|
+
Rack::MiniProfilerRails.const_set("Engine", klass)
|
130
|
+
end
|
66
131
|
|
67
|
-
|
132
|
+
def self.subscribe(event, &blk)
|
133
|
+
if ActiveSupport::Notifications.respond_to?(:monotonic_subscribe)
|
134
|
+
ActiveSupport::Notifications.monotonic_subscribe(event) { |*args| blk.call(*args) }
|
135
|
+
else
|
136
|
+
ActiveSupport::Notifications.subscribe(event) do |name, start, finish, id, payload|
|
137
|
+
blk.call(name, start.to_f, finish.to_f, id, payload)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.get_key(payload)
|
143
|
+
"mini_profiler_parent_timer_#{payload[:controller]}_#{payload[:action]}".to_sym
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.shorten_identifier(identifier)
|
147
|
+
identifier.split('/').last(2).join('/')
|
68
148
|
end
|
69
149
|
|
70
150
|
def self.serves_static_assets?(app)
|
@@ -95,6 +175,7 @@ module Rack::MiniProfilerRails
|
|
95
175
|
middlewares = app.middleware.middlewares
|
96
176
|
if Rack::MiniProfiler.config.suppress_encoding.nil? &&
|
97
177
|
middlewares.include?(Rack::Deflater) &&
|
178
|
+
middlewares.include?(Rack::MiniProfiler) &&
|
98
179
|
middlewares.index(Rack::Deflater) > middlewares.index(Rack::MiniProfiler)
|
99
180
|
Rack::MiniProfiler.config.suppress_encoding = true
|
100
181
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rack::MiniProfilerRailsMethods
|
4
|
+
def render_notification_handler(name, finish, start, name_as_description: false)
|
5
|
+
return if !should_measure?
|
6
|
+
|
7
|
+
description = name_as_description ? name : "Rendering: #{name}"
|
8
|
+
current = Rack::MiniProfiler.current.current_timer
|
9
|
+
node = current.add_child(description)
|
10
|
+
duration = finish - start
|
11
|
+
duration_ms = duration * 1000
|
12
|
+
node.start -= duration
|
13
|
+
node[:start_milliseconds] -= duration_ms
|
14
|
+
node.record_time(duration_ms)
|
15
|
+
|
16
|
+
children_duration = 0
|
17
|
+
to_be_moved = { requests: [], sql: [], custom: {} }
|
18
|
+
current.children.each do |child|
|
19
|
+
next if child == node
|
20
|
+
if should_move?(child, node)
|
21
|
+
to_be_moved[:requests] << child
|
22
|
+
children_duration += child[:duration_milliseconds]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
node[:duration_without_children_milliseconds] = duration_ms - children_duration
|
26
|
+
to_be_moved[:requests].each { |req| current.move_child(req, node) }
|
27
|
+
|
28
|
+
current.sql_timings.each do |sql|
|
29
|
+
to_be_moved[:sql] << sql if should_move?(sql, node)
|
30
|
+
end
|
31
|
+
to_be_moved[:sql].each { |sql| current.move_sql(sql, node) }
|
32
|
+
|
33
|
+
current.custom_timings.each do |type, timings|
|
34
|
+
to_be_moved[:custom] = []
|
35
|
+
timings.each do |custom|
|
36
|
+
to_be_moved[:custom] << custom if should_move?(custom, node)
|
37
|
+
end
|
38
|
+
to_be_moved[:custom].each { |custom| current.move_custom(type, custom, node) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def should_measure?
|
43
|
+
current = Rack::MiniProfiler.current
|
44
|
+
current && current.measure
|
45
|
+
end
|
46
|
+
|
47
|
+
def should_move?(child, node)
|
48
|
+
start = :start_milliseconds
|
49
|
+
duration = :duration_milliseconds
|
50
|
+
child[start] >= node[start] &&
|
51
|
+
child[start] + child[duration] <= node[start] + node[duration]
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_webpacker_assets_path
|
55
|
+
if defined?(Webpacker) && Webpacker.config.config_path.exist?
|
56
|
+
Webpacker.config.public_output_path.to_s.gsub(Webpacker.config.public_path.to_s, "")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
extend self
|
61
|
+
end
|
@@ -15,17 +15,6 @@ module Rack
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def binds_to_params(binds)
|
19
|
-
return if binds.nil? || Rack::MiniProfiler.config.max_sql_param_length == 0
|
20
|
-
# map ActiveRecord::Relation::QueryAttribute to [name, value]
|
21
|
-
params = binds.map { |c| c.kind_of?(Array) ? [c.first, c.last] : [c.name, c.value] }
|
22
|
-
if (skip = Rack::MiniProfiler.config.skip_sql_param_names)
|
23
|
-
params.map { |(n, v)| n =~ skip ? [n, nil] : [n, v] }
|
24
|
-
else
|
25
|
-
params
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
18
|
def log_with_miniprofiler(*args, &block)
|
30
19
|
return log_without_miniprofiler(*args, &block) unless SqlPatches.should_measure?
|
31
20
|
|
@@ -37,7 +26,7 @@ module Rack
|
|
37
26
|
return rval if Rack::MiniProfiler.config.skip_schema_queries && name =~ (/SCHEMA/)
|
38
27
|
|
39
28
|
elapsed_time = SqlPatches.elapsed_time(start)
|
40
|
-
Rack::MiniProfiler.record_sql(sql, elapsed_time, binds_to_params(binds))
|
29
|
+
Rack::MiniProfiler.record_sql(sql, elapsed_time, Rack::MiniProfiler.binds_to_params(binds))
|
41
30
|
rval
|
42
31
|
end
|
43
32
|
end
|