rack-mini-profiler 0.10.6 → 2.3.0
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 +5 -5
- data/CHANGELOG.md +129 -16
- data/README.md +116 -63
- data/lib/enable_rails_patches.rb +5 -0
- data/lib/generators/rack_profiler/install_generator.rb +2 -0
- data/lib/generators/rack_profiler/templates/rack_profiler.rb +2 -0
- data/lib/html/dot.1.1.2.min.js +2 -0
- data/lib/html/includes.css +141 -40
- data/lib/html/includes.js +1398 -970
- data/lib/html/includes.scss +547 -442
- data/lib/html/includes.tmpl +227 -142
- 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/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 +27 -16
- data/lib/mini_profiler/config.rb +73 -46
- data/lib/mini_profiler/context.rb +5 -3
- data/lib/mini_profiler/gc_profiler.rb +17 -16
- data/lib/mini_profiler/profiler.rb +332 -94
- data/lib/mini_profiler/profiling_methods.rb +20 -15
- data/lib/mini_profiler/snapshots_transporter.rb +109 -0
- data/lib/mini_profiler/storage/abstract_store.rb +80 -0
- data/lib/mini_profiler/storage/file_store.rb +18 -13
- data/lib/mini_profiler/storage/memcache_store.rb +10 -7
- data/lib/mini_profiler/storage/memory_store.rb +63 -13
- data/lib/mini_profiler/storage/redis_store.rb +143 -7
- data/lib/mini_profiler/timer_struct/base.rb +4 -2
- data/lib/mini_profiler/timer_struct/client.rb +9 -8
- data/lib/mini_profiler/timer_struct/custom.rb +8 -5
- data/lib/mini_profiler/timer_struct/page.rb +79 -24
- data/lib/mini_profiler/timer_struct/request.rb +83 -38
- data/lib/mini_profiler/timer_struct/sql.rb +25 -22
- data/lib/mini_profiler/version.rb +3 -1
- data/lib/mini_profiler_rails/railtie.rb +91 -8
- data/lib/mini_profiler_rails/railtie_methods.rb +61 -0
- data/lib/patches/db/activerecord.rb +5 -14
- data/lib/patches/db/mongo.rb +3 -1
- data/lib/patches/db/moped.rb +5 -3
- data/lib/patches/db/mysql2.rb +8 -6
- data/lib/patches/db/neo4j.rb +3 -1
- data/lib/patches/db/nobrainer.rb +4 -2
- data/lib/patches/db/oracle_enhanced.rb +4 -2
- data/lib/patches/db/pg.rb +41 -21
- data/lib/patches/db/plucky.rb +7 -5
- data/lib/patches/db/riak.rb +15 -13
- data/lib/patches/db/rsolr.rb +6 -4
- data/lib/patches/db/sequel.rb +2 -0
- data/lib/patches/net_patches.rb +20 -8
- data/lib/patches/sql_patches.rb +17 -7
- data/lib/prepend_net_http_patch.rb +5 -0
- data/lib/rack-mini-profiler.rb +3 -3
- data/rack-mini-profiler.gemspec +23 -9
- metadata +146 -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
@@ -1,28 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Rack
|
3
4
|
class MiniProfiler
|
4
5
|
|
5
6
|
# Timing system for a SQL query
|
6
7
|
module TimerStruct
|
7
8
|
class Sql < TimerStruct::Base
|
9
|
+
attr_accessor :parent
|
10
|
+
|
8
11
|
def initialize(query, duration_ms, page, parent, params = nil, skip_backtrace = false, full_backtrace = false)
|
9
12
|
|
10
13
|
stack_trace = nil
|
11
14
|
unless skip_backtrace || duration_ms < Rack::MiniProfiler.config.backtrace_threshold_ms
|
12
15
|
# Allow us to filter the stack trace
|
13
|
-
stack_trace =
|
14
|
-
|
16
|
+
stack_trace = "".dup
|
17
|
+
# Clean up the stack trace if there are options to do so
|
15
18
|
Kernel.caller.each do |ln|
|
16
|
-
ln.gsub!(Rack::MiniProfiler.config.backtrace_remove, '') if Rack::MiniProfiler.config.backtrace_remove
|
17
|
-
if full_backtrace
|
19
|
+
ln.gsub!(Rack::MiniProfiler.config.backtrace_remove, '') if Rack::MiniProfiler.config.backtrace_remove && !full_backtrace
|
20
|
+
if full_backtrace ||
|
18
21
|
(
|
19
22
|
(
|
20
|
-
Rack::MiniProfiler.config.backtrace_includes.nil?
|
21
|
-
Rack::MiniProfiler.config.backtrace_includes.any?{|regex| ln =~ regex}
|
22
|
-
)
|
23
|
+
Rack::MiniProfiler.config.backtrace_includes.nil? ||
|
24
|
+
Rack::MiniProfiler.config.backtrace_includes.any? { |regex| ln =~ regex }
|
25
|
+
) &&
|
23
26
|
(
|
24
|
-
Rack::MiniProfiler.config.backtrace_ignores.nil?
|
25
|
-
Rack::MiniProfiler.config.backtrace_ignores.none?{|regex| ln =~ regex}
|
27
|
+
Rack::MiniProfiler.config.backtrace_ignores.nil? ||
|
28
|
+
Rack::MiniProfiler.config.backtrace_ignores.none? { |regex| ln =~ regex }
|
26
29
|
)
|
27
30
|
)
|
28
31
|
stack_trace << ln << "\n"
|
@@ -32,17 +35,17 @@ module Rack
|
|
32
35
|
|
33
36
|
@parent = parent
|
34
37
|
@page = page
|
35
|
-
start_millis = ((
|
38
|
+
start_millis = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000).to_i - page[:started]) - duration_ms
|
36
39
|
super(
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
40
|
+
execute_type: 3, # TODO
|
41
|
+
formatted_command_string: query ? ERB::Util.html_escape(query) : nil,
|
42
|
+
stack_trace_snippet: stack_trace,
|
43
|
+
start_milliseconds: start_millis,
|
44
|
+
duration_milliseconds: duration_ms,
|
45
|
+
first_fetch_duration_milliseconds: duration_ms,
|
46
|
+
parameters: query ? trim_binds(params) : nil,
|
47
|
+
parent_timing_id: nil,
|
48
|
+
is_duplicate: false
|
46
49
|
)
|
47
50
|
end
|
48
51
|
|
@@ -57,18 +60,18 @@ module Rack
|
|
57
60
|
def trim_binds(binds)
|
58
61
|
max_len = Rack::MiniProfiler.config.max_sql_param_length
|
59
62
|
return if binds.nil? || max_len == 0
|
60
|
-
return binds.map{|(name, val)| [name, val]} if max_len.nil?
|
63
|
+
return binds.map { |(name, val)| [name, val] } if max_len.nil?
|
61
64
|
binds.map do |(name, val)|
|
62
65
|
val ||= name
|
63
66
|
if val.nil? || val == true || val == false || val.kind_of?(Numeric)
|
64
67
|
# keep these parameters as is
|
65
68
|
elsif val.kind_of?(String)
|
66
|
-
val = val[0...max_len]+(max_len < val.length ? '...' : '') if max_len
|
69
|
+
val = val[0...max_len] + (max_len < val.length ? '...' : '') if max_len
|
67
70
|
else
|
68
71
|
val = val.class.name
|
69
72
|
end
|
70
73
|
if name.kind_of?(String)
|
71
|
-
name = name[0...max_len]+(max_len < name.length ? '...' : '') if max_len
|
74
|
+
name = name[0...max_len] + (max_len < name.length ? '...' : '') if max_len
|
72
75
|
end
|
73
76
|
[name, val]
|
74
77
|
end
|
@@ -1,11 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fileutils'
|
4
|
+
require_relative './railtie_methods'
|
2
5
|
|
3
6
|
module Rack::MiniProfilerRails
|
7
|
+
extend Rack::MiniProfilerRailsMethods
|
4
8
|
|
5
9
|
# call direct if needed to do a defer init
|
6
10
|
def self.initialize!(app)
|
7
11
|
|
8
|
-
raise "MiniProfilerRails initialized twice. Set `require: false' for rack-mini-profiler in your Gemfile" if @already_initialized
|
12
|
+
raise "MiniProfilerRails initialized twice. Set `require: false' for rack-mini-profiler in your Gemfile" if defined?(@already_initialized) && @already_initialized
|
9
13
|
|
10
14
|
c = Rack::MiniProfiler.config
|
11
15
|
|
@@ -26,6 +30,8 @@ module Rack::MiniProfilerRails
|
|
26
30
|
|
27
31
|
if serves_static_assets?(app)
|
28
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
|
29
35
|
end
|
30
36
|
|
31
37
|
unless Rails.env.development? || Rails.env.test?
|
@@ -42,7 +48,7 @@ module Rack::MiniProfilerRails
|
|
42
48
|
base_path = Rails.application.config.paths['tmp'].first rescue "#{Rails.root}/tmp"
|
43
49
|
tmp = base_path + '/miniprofiler'
|
44
50
|
|
45
|
-
c.storage_options = {:
|
51
|
+
c.storage_options = { path: tmp }
|
46
52
|
c.storage = Rack::MiniProfiler::FileStore
|
47
53
|
end
|
48
54
|
|
@@ -53,16 +59,92 @@ module Rack::MiniProfilerRails
|
|
53
59
|
|
54
60
|
# Install the Middleware
|
55
61
|
app.middleware.insert(0, Rack::MiniProfiler)
|
62
|
+
c.enable_advanced_debugging_tools = Rails.env.development?
|
63
|
+
|
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
|
56
82
|
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
60
117
|
end
|
61
|
-
|
62
|
-
|
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'
|
63
128
|
end
|
129
|
+
Rack::MiniProfilerRails.const_set("Engine", klass)
|
130
|
+
end
|
64
131
|
|
65
|
-
|
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('/')
|
66
148
|
end
|
67
149
|
|
68
150
|
def self.serves_static_assets?(app)
|
@@ -93,6 +175,7 @@ module Rack::MiniProfilerRails
|
|
93
175
|
middlewares = app.middleware.middlewares
|
94
176
|
if Rack::MiniProfiler.config.suppress_encoding.nil? &&
|
95
177
|
middlewares.include?(Rack::Deflater) &&
|
178
|
+
middlewares.include?(Rack::MiniProfiler) &&
|
96
179
|
middlewares.index(Rack::Deflater) > middlewares.index(Rack::MiniProfiler)
|
97
180
|
Rack::MiniProfiler.config.suppress_encoding = true
|
98
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
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
## based off https://github.com/newrelic/rpm/blob/master/lib/new_relic/agent/instrumentation/active_record.rb
|
2
4
|
## fallback for alls sorts of weird dbs
|
3
5
|
module Rack
|
@@ -13,29 +15,18 @@ module Rack
|
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
def binds_to_params(binds)
|
17
|
-
return if binds.nil? || Rack::MiniProfiler.config.max_sql_param_length == 0
|
18
|
-
# map ActiveRecord::Relation::QueryAttribute to [name, value]
|
19
|
-
params = binds.map { |c| c.kind_of?(Array) ? [c.first, c.last] : [c.name, c.value] }
|
20
|
-
if (skip = Rack::MiniProfiler.config.skip_sql_param_names)
|
21
|
-
params.map { |(n,v)| n =~ skip ? [n, nil] : [n, v] }
|
22
|
-
else
|
23
|
-
params
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
18
|
def log_with_miniprofiler(*args, &block)
|
28
19
|
return log_without_miniprofiler(*args, &block) unless SqlPatches.should_measure?
|
29
20
|
|
30
21
|
sql, name, binds = args
|
31
|
-
start =
|
22
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
32
23
|
rval = log_without_miniprofiler(*args, &block)
|
33
24
|
|
34
25
|
# Don't log schema queries if the option is set
|
35
|
-
return rval if Rack::MiniProfiler.config.skip_schema_queries
|
26
|
+
return rval if Rack::MiniProfiler.config.skip_schema_queries && name =~ (/SCHEMA/)
|
36
27
|
|
37
28
|
elapsed_time = SqlPatches.elapsed_time(start)
|
38
|
-
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))
|
39
30
|
rval
|
40
31
|
end
|
41
32
|
end
|
data/lib/patches/db/mongo.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Mongo/Mongoid 5 patches
|
2
4
|
class Mongo::Server::Connection
|
3
5
|
def dispatch_with_timing(*args, &blk)
|
@@ -6,7 +8,7 @@ class Mongo::Server::Connection
|
|
6
8
|
result, _record = SqlPatches.record_sql(args[0][0].payload.inspect) do
|
7
9
|
dispatch_without_timing(*args, &blk)
|
8
10
|
end
|
9
|
-
|
11
|
+
result
|
10
12
|
end
|
11
13
|
|
12
14
|
# TODO: change to Module#prepend as soon as Ruby 1.9.3 support is dropped
|
data/lib/patches/db/moped.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Mongoid 3 patches
|
2
4
|
class Moped::Node
|
3
5
|
alias_method :process_without_profiling, :process
|
4
|
-
def process(*args
|
5
|
-
return process_without_profiling(*args
|
6
|
+
def process(*args, &blk)
|
7
|
+
return process_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
6
8
|
|
7
9
|
result, _record = SqlPatches.record_sql(args[0].log_inspect) do
|
8
10
|
process_without_profiling(*args, &blk)
|
9
11
|
end
|
10
|
-
|
12
|
+
result
|
11
13
|
end
|
12
14
|
end
|
data/lib/patches/db/mysql2.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# The best kind of instrumentation is in the actual db provider, however we don't want to double instrument
|
2
4
|
|
3
5
|
class Mysql2::Result
|
@@ -5,8 +7,8 @@ class Mysql2::Result
|
|
5
7
|
def each(*args, &blk)
|
6
8
|
return each_without_profiling(*args, &blk) unless defined?(@miniprofiler_sql_id)
|
7
9
|
|
8
|
-
start =
|
9
|
-
result = each_without_profiling(*args
|
10
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
11
|
+
result = each_without_profiling(*args, &blk)
|
10
12
|
elapsed_time = SqlPatches.elapsed_time(start)
|
11
13
|
|
12
14
|
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
@@ -16,11 +18,11 @@ end
|
|
16
18
|
|
17
19
|
class Mysql2::Client
|
18
20
|
alias_method :query_without_profiling, :query
|
19
|
-
def query(*args
|
20
|
-
return query_without_profiling(*args
|
21
|
+
def query(*args, &blk)
|
22
|
+
return query_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
21
23
|
|
22
|
-
result, record = SqlPatches.record_sql(
|
23
|
-
query_without_profiling(*args
|
24
|
+
result, record = SqlPatches.record_sql(args[0]) do
|
25
|
+
query_without_profiling(*args, &blk)
|
24
26
|
end
|
25
27
|
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
26
28
|
result
|
data/lib/patches/db/neo4j.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Neo4j::Core::Query
|
2
4
|
alias_method :response_without_miniprofiler, :response
|
3
5
|
|
4
6
|
def response
|
5
7
|
return @response if @response
|
6
|
-
start =
|
8
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
7
9
|
rval = response_without_miniprofiler
|
8
10
|
elapsed_time = SqlPatches.elapsed_time(start)
|
9
11
|
Rack::MiniProfiler.record_sql(to_cypher, elapsed_time)
|
data/lib/patches/db/nobrainer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Rack::MiniProfiler::NoBrainerProfiler
|
2
4
|
|
3
5
|
def on_query(env)
|
@@ -6,7 +8,7 @@ class Rack::MiniProfiler::NoBrainerProfiler
|
|
6
8
|
!env[:criteria].where_indexed? &&
|
7
9
|
!env[:criteria].model.try(:perf_warnings_disabled)
|
8
10
|
|
9
|
-
query = ""
|
11
|
+
query = "".dup
|
10
12
|
|
11
13
|
# per-model/query database overrides
|
12
14
|
query << "[#{env[:options][:db]}] " if env[:options][:db]
|
@@ -15,7 +17,7 @@ class Rack::MiniProfiler::NoBrainerProfiler
|
|
15
17
|
# query << "(#{NoBrainer::RQL.type_of(env[:query]).to_s}) "
|
16
18
|
|
17
19
|
query << "NOT USING INDEX: " if not_indexed
|
18
|
-
query << env[:query].inspect.
|
20
|
+
query << env[:query].inspect.delete("\n").gsub(/ +/, ' ') + " "
|
19
21
|
|
20
22
|
if env[:exception]
|
21
23
|
query << "exception: #{env[:exception].class} #{env[:exception].message.split("\n").first} "
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class ActiveRecord::Result
|
2
4
|
alias_method :each_without_profiling, :each
|
3
5
|
def each(&blk)
|
4
6
|
return each_without_profiling(&blk) unless defined?(@miniprofiler_sql_id)
|
5
7
|
|
6
|
-
start =
|
8
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
7
9
|
result = each_without_profiling(&blk)
|
8
10
|
elapsed_time = SqlPatches.elapsed_time(start)
|
9
11
|
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
@@ -45,7 +47,7 @@ class ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
|
45
47
|
def mp_profile_sql(sql, name, &blk)
|
46
48
|
return yield unless mp_should_measure?(name)
|
47
49
|
|
48
|
-
start =
|
50
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
49
51
|
result = yield
|
50
52
|
elapsed_time = SqlPatches.elapsed_time(start)
|
51
53
|
record = ::Rack::MiniProfiler.record_sql(sql, elapsed_time)
|
data/lib/patches/db/pg.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# PG patches, keep in mind exec and async_exec have a exec{|r| } semantics that is yet to be implemented
|
2
4
|
class PG::Result
|
3
5
|
alias_method :each_without_profiling, :each
|
@@ -6,7 +8,7 @@ class PG::Result
|
|
6
8
|
def values(*args, &blk)
|
7
9
|
return values_without_profiling(*args, &blk) unless defined?(@miniprofiler_sql_id)
|
8
10
|
mp_report_sql do
|
9
|
-
values_without_profiling(*args
|
11
|
+
values_without_profiling(*args , &blk)
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
@@ -18,7 +20,7 @@ class PG::Result
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def mp_report_sql(&block)
|
21
|
-
start =
|
23
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
22
24
|
result = yield
|
23
25
|
elapsed_time = SqlPatches.elapsed_time(start)
|
24
26
|
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
@@ -33,7 +35,11 @@ class PG::Connection
|
|
33
35
|
alias_method :send_query_prepared_without_profiling, :send_query_prepared
|
34
36
|
alias_method :prepare_without_profiling, :prepare
|
35
37
|
|
36
|
-
|
38
|
+
if Gem::Version.new(PG::VERSION) >= Gem::Version.new("1.1.0")
|
39
|
+
alias_method :exec_params_without_profiling, :exec_params
|
40
|
+
end
|
41
|
+
|
42
|
+
def prepare(*args, &blk)
|
37
43
|
# we have no choice but to do this here,
|
38
44
|
# if we do the check for profiling first, our cache may miss critical stuff
|
39
45
|
|
@@ -42,15 +48,15 @@ class PG::Connection
|
|
42
48
|
# dont leak more than 10k ever
|
43
49
|
@prepare_map = {} if @prepare_map.length > 1000
|
44
50
|
|
45
|
-
return prepare_without_profiling(*args
|
46
|
-
prepare_without_profiling(*args
|
51
|
+
return prepare_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
52
|
+
prepare_without_profiling(*args, &blk)
|
47
53
|
end
|
48
54
|
|
49
|
-
def exec(*args
|
50
|
-
return exec_without_profiling(*args
|
55
|
+
def exec(*args, &blk)
|
56
|
+
return exec_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
51
57
|
|
52
|
-
start =
|
53
|
-
result = exec_without_profiling(*args
|
58
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
59
|
+
result = exec_without_profiling(*args, &blk)
|
54
60
|
elapsed_time = SqlPatches.elapsed_time(start)
|
55
61
|
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
56
62
|
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
@@ -58,11 +64,25 @@ class PG::Connection
|
|
58
64
|
result
|
59
65
|
end
|
60
66
|
|
61
|
-
|
62
|
-
|
67
|
+
if Gem::Version.new(PG::VERSION) >= Gem::Version.new("1.1.0")
|
68
|
+
def exec_params(*args, &blk)
|
69
|
+
return exec_params_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
70
|
+
|
71
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
72
|
+
result = exec_params_without_profiling(*args, &blk)
|
73
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
74
|
+
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
75
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
76
|
+
|
77
|
+
result
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def exec_prepared(*args, &blk)
|
82
|
+
return exec_prepared_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
63
83
|
|
64
|
-
start =
|
65
|
-
result = exec_prepared_without_profiling(*args
|
84
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
85
|
+
result = exec_prepared_without_profiling(*args, &blk)
|
66
86
|
elapsed_time = SqlPatches.elapsed_time(start)
|
67
87
|
mapped = args[0]
|
68
88
|
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
@@ -72,11 +92,11 @@ class PG::Connection
|
|
72
92
|
result
|
73
93
|
end
|
74
94
|
|
75
|
-
def send_query_prepared(*args
|
76
|
-
return send_query_prepared_without_profiling(*args
|
95
|
+
def send_query_prepared(*args, &blk)
|
96
|
+
return send_query_prepared_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
77
97
|
|
78
|
-
start =
|
79
|
-
result = send_query_prepared_without_profiling(*args
|
98
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
99
|
+
result = send_query_prepared_without_profiling(*args, &blk)
|
80
100
|
elapsed_time = SqlPatches.elapsed_time(start)
|
81
101
|
mapped = args[0]
|
82
102
|
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
@@ -86,11 +106,11 @@ class PG::Connection
|
|
86
106
|
result
|
87
107
|
end
|
88
108
|
|
89
|
-
def async_exec(*args
|
90
|
-
return async_exec_without_profiling(*args
|
109
|
+
def async_exec(*args, &blk)
|
110
|
+
return async_exec_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
91
111
|
|
92
|
-
start =
|
93
|
-
result = exec_without_profiling(*args
|
112
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
113
|
+
result = exec_without_profiling(*args, &blk)
|
94
114
|
elapsed_time = SqlPatches.elapsed_time(start)
|
95
115
|
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
96
116
|
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
data/lib/patches/db/plucky.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# mongo_mapper patches
|
2
4
|
# TODO: Include overrides for distinct, update, cursor, and create
|
3
5
|
class Plucky::Query
|
@@ -7,19 +9,19 @@ class Plucky::Query
|
|
7
9
|
alias_method :remove_without_profiling, :remove
|
8
10
|
|
9
11
|
def find_each(*args, &blk)
|
10
|
-
|
12
|
+
profile_database_operation(__callee__, filtered_inspect(), *args, &blk)
|
11
13
|
end
|
12
14
|
|
13
15
|
def find_one(*args, &blk)
|
14
|
-
|
16
|
+
profile_database_operation(__callee__, filtered_inspect(args[0]), *args, &blk)
|
15
17
|
end
|
16
18
|
|
17
19
|
def count(*args, &blk)
|
18
|
-
|
20
|
+
profile_database_operation(__callee__, filtered_inspect(), *args, &blk)
|
19
21
|
end
|
20
22
|
|
21
23
|
def remove(*args, &blk)
|
22
|
-
|
24
|
+
profile_database_operation(__callee__, filtered_inspect(), *args, &blk)
|
23
25
|
end
|
24
26
|
|
25
27
|
private
|
@@ -27,7 +29,7 @@ class Plucky::Query
|
|
27
29
|
def profile_database_operation(method, message, *args, &blk)
|
28
30
|
return self.send("#{method.id2name}_without_profiling", *args, &blk) unless SqlPatches.should_measure?
|
29
31
|
|
30
|
-
start =
|
32
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
31
33
|
result = self.send("#{method.id2name}_without_profiling", *args, &blk)
|
32
34
|
elapsed_time = SqlPatches.elapsed_time(start)
|
33
35
|
|