rack-mini-profiler 0.9.2 → 0.9.3
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.
Potentially problematic release.
This version of rack-mini-profiler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +17 -3
- data/lib/html/includes.css +15 -4
- data/lib/html/includes.js +93 -58
- data/lib/html/includes.less +21 -5
- data/lib/html/includes.tmpl +49 -49
- data/lib/html/list.tmpl +8 -8
- data/lib/mini_profiler/asset_version.rb +5 -0
- data/lib/mini_profiler/client_settings.rb +3 -3
- data/lib/mini_profiler/config.rb +11 -11
- data/lib/mini_profiler/gc_profiler.rb +10 -10
- data/lib/mini_profiler/profiler.rb +49 -71
- data/lib/mini_profiler/profiling_methods.rb +15 -17
- data/lib/mini_profiler/storage/file_store.rb +4 -4
- data/lib/mini_profiler/storage/memcache_store.rb +5 -7
- data/lib/mini_profiler/storage/memory_store.rb +56 -27
- data/lib/mini_profiler/storage/redis_store.rb +19 -11
- data/lib/mini_profiler/timer_struct/base.rb +33 -0
- data/lib/mini_profiler/timer_struct/client.rb +89 -0
- data/lib/mini_profiler/timer_struct/custom.rb +22 -0
- data/lib/mini_profiler/timer_struct/page.rb +62 -0
- data/lib/mini_profiler/timer_struct/request.rb +126 -0
- data/lib/mini_profiler/timer_struct/sql.rb +59 -0
- data/lib/mini_profiler/version.rb +2 -2
- data/lib/patches/db/activerecord.rb +42 -0
- data/lib/patches/db/moped.rb +12 -0
- data/lib/patches/db/mysql2.rb +30 -0
- data/lib/patches/db/pg.rb +104 -0
- data/lib/patches/db/plucky.rb +47 -0
- data/lib/patches/db/rsolr.rb +24 -0
- data/lib/patches/db/sequel.rb +10 -0
- data/lib/patches/sql_patches.rb +17 -255
- data/lib/rack-mini-profiler.rb +28 -0
- data/rack-mini-profiler.gemspec +6 -2
- metadata +16 -8
- data/lib/mini_profiler/client_timer_struct.rb +0 -78
- data/lib/mini_profiler/custom_timer_struct.rb +0 -22
- data/lib/mini_profiler/page_timer_struct.rb +0 -58
- data/lib/mini_profiler/request_timer_struct.rb +0 -115
- data/lib/mini_profiler/sql_timer_struct.rb +0 -58
- data/lib/mini_profiler/timer_struct.rb +0 -33
@@ -0,0 +1,59 @@
|
|
1
|
+
module Rack
|
2
|
+
class MiniProfiler
|
3
|
+
|
4
|
+
# Timing system for a SQL query
|
5
|
+
module TimerStruct
|
6
|
+
class Sql < TimerStruct::Base
|
7
|
+
def initialize(query, duration_ms, page, parent, skip_backtrace = false, full_backtrace = false)
|
8
|
+
|
9
|
+
stack_trace = nil
|
10
|
+
unless skip_backtrace || duration_ms < Rack::MiniProfiler.config.backtrace_threshold_ms
|
11
|
+
# Allow us to filter the stack trace
|
12
|
+
stack_trace = ""
|
13
|
+
# Clean up the stack trace if there are options to do so
|
14
|
+
Kernel.caller.each do |ln|
|
15
|
+
ln.gsub!(Rack::MiniProfiler.config.backtrace_remove, '') if Rack::MiniProfiler.config.backtrace_remove and !full_backtrace
|
16
|
+
if full_backtrace or
|
17
|
+
(
|
18
|
+
(
|
19
|
+
Rack::MiniProfiler.config.backtrace_includes.nil? or
|
20
|
+
Rack::MiniProfiler.config.backtrace_includes.all?{|regex| ln =~ regex}
|
21
|
+
) and
|
22
|
+
(
|
23
|
+
Rack::MiniProfiler.config.backtrace_ignores.nil? or
|
24
|
+
Rack::MiniProfiler.config.backtrace_ignores.all?{|regex| !(ln =~ regex)}
|
25
|
+
)
|
26
|
+
)
|
27
|
+
stack_trace << ln << "\n"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
@parent = parent
|
33
|
+
@page = page
|
34
|
+
start_millis = ((Time.now.to_f * 1000).to_i - page[:started]) - duration_ms
|
35
|
+
super(
|
36
|
+
:execute_type => 3, # TODO
|
37
|
+
:formatted_command_string => query,
|
38
|
+
:stack_trace_snippet => stack_trace,
|
39
|
+
:start_milliseconds => start_millis,
|
40
|
+
:duration_milliseconds => duration_ms,
|
41
|
+
:first_fetch_duration_milliseconds => duration_ms,
|
42
|
+
:parameters => nil,
|
43
|
+
:parent_timing_id => nil,
|
44
|
+
:is_duplicate => false
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
def report_reader_duration(elapsed_ms)
|
49
|
+
return if @reported
|
50
|
+
@reported = true
|
51
|
+
self[:duration_milliseconds] += elapsed_ms
|
52
|
+
@parent[:sql_timings_duration_milliseconds] += elapsed_ms
|
53
|
+
@page[:duration_milliseconds_in_sql] += elapsed_ms
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
## based off https://github.com/newrelic/rpm/blob/master/lib/new_relic/agent/instrumentation/active_record.rb
|
2
|
+
## fallback for alls sorts of weird dbs
|
3
|
+
module Rack
|
4
|
+
class MiniProfiler
|
5
|
+
module ActiveRecordInstrumentation
|
6
|
+
def self.included(instrumented_class)
|
7
|
+
instrumented_class.class_eval do
|
8
|
+
unless instrumented_class.method_defined?(:log_without_miniprofiler)
|
9
|
+
alias_method :log_without_miniprofiler, :log
|
10
|
+
alias_method :log, :log_with_miniprofiler
|
11
|
+
protected :log
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_with_miniprofiler(*args, &block)
|
17
|
+
return log_without_miniprofiler(*args, &block) unless SqlPatches.should_measure?
|
18
|
+
|
19
|
+
sql, name, _binds = args
|
20
|
+
start = Time.now
|
21
|
+
rval = log_without_miniprofiler(*args, &block)
|
22
|
+
|
23
|
+
# Don't log schema queries if the option is set
|
24
|
+
return rval if Rack::MiniProfiler.config.skip_schema_queries and name =~ /SCHEMA/
|
25
|
+
|
26
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
27
|
+
Rack::MiniProfiler.record_sql(sql, elapsed_time)
|
28
|
+
rval
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.insert_instrumentation
|
34
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
|
35
|
+
include ::Rack::MiniProfiler::ActiveRecordInstrumentation
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if defined?(::Rails) && !SqlPatches.patched?
|
40
|
+
insert_instrumentation
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Mongoid 3 patches
|
2
|
+
class Moped::Node
|
3
|
+
alias_method :process_without_profiling, :process
|
4
|
+
def process(*args,&blk)
|
5
|
+
return process_without_profiling(*args,&blk) unless SqlPatches.should_measure?
|
6
|
+
|
7
|
+
result, _record = SqlPatches.record_sql(args[0].log_inspect) do
|
8
|
+
process_without_profiling(*args, &blk)
|
9
|
+
end
|
10
|
+
return result
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# The best kind of instrumentation is in the actual db provider, however we don't want to double instrument
|
2
|
+
|
3
|
+
class Mysql2::Result
|
4
|
+
alias_method :each_without_profiling, :each
|
5
|
+
def each(*args, &blk)
|
6
|
+
return each_without_profiling(*args, &blk) unless @miniprofiler_sql_id
|
7
|
+
|
8
|
+
start = Time.now
|
9
|
+
result = each_without_profiling(*args,&blk)
|
10
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
11
|
+
|
12
|
+
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
13
|
+
result
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Mysql2::Client
|
18
|
+
alias_method :query_without_profiling, :query
|
19
|
+
def query(*args,&blk)
|
20
|
+
return query_without_profiling(*args,&blk) unless SqlPatches.should_measure?
|
21
|
+
|
22
|
+
result, record = SqlPatches.record_sql( args[0] ) do
|
23
|
+
query_without_profiling(*args,&blk)
|
24
|
+
end
|
25
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
SqlPatches.patched = true
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# PG patches, keep in mind exec and async_exec have a exec{|r| } semantics that is yet to be implemented
|
2
|
+
class PG::Result
|
3
|
+
alias_method :each_without_profiling, :each
|
4
|
+
alias_method :values_without_profiling, :values
|
5
|
+
|
6
|
+
def values(*args, &blk)
|
7
|
+
return values_without_profiling(*args, &blk) unless @miniprofiler_sql_id
|
8
|
+
mp_report_sql do
|
9
|
+
values_without_profiling(*args ,&blk)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def each(*args, &blk)
|
14
|
+
return each_without_profiling(*args, &blk) unless @miniprofiler_sql_id
|
15
|
+
mp_report_sql do
|
16
|
+
each_without_profiling(*args, &blk)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def mp_report_sql(&block)
|
21
|
+
start = Time.now
|
22
|
+
result = yield
|
23
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
24
|
+
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
25
|
+
result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class PG::Connection
|
30
|
+
alias_method :exec_without_profiling, :exec
|
31
|
+
alias_method :async_exec_without_profiling, :async_exec
|
32
|
+
alias_method :exec_prepared_without_profiling, :exec_prepared
|
33
|
+
alias_method :send_query_prepared_without_profiling, :send_query_prepared
|
34
|
+
alias_method :prepare_without_profiling, :prepare
|
35
|
+
|
36
|
+
def prepare(*args,&blk)
|
37
|
+
# we have no choice but to do this here,
|
38
|
+
# if we do the check for profiling first, our cache may miss critical stuff
|
39
|
+
|
40
|
+
@prepare_map ||= {}
|
41
|
+
@prepare_map[args[0]] = args[1]
|
42
|
+
# dont leak more than 10k ever
|
43
|
+
@prepare_map = {} if @prepare_map.length > 1000
|
44
|
+
|
45
|
+
return prepare_without_profiling(*args,&blk) unless SqlPatches.should_measure?
|
46
|
+
prepare_without_profiling(*args,&blk)
|
47
|
+
end
|
48
|
+
|
49
|
+
def exec(*args,&blk)
|
50
|
+
return exec_without_profiling(*args,&blk) unless SqlPatches.should_measure?
|
51
|
+
|
52
|
+
start = Time.now
|
53
|
+
result = exec_without_profiling(*args,&blk)
|
54
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
55
|
+
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
56
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
57
|
+
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
def exec_prepared(*args,&blk)
|
62
|
+
return exec_prepared_without_profiling(*args,&blk) unless SqlPatches.should_measure?
|
63
|
+
|
64
|
+
start = Time.now
|
65
|
+
result = exec_prepared_without_profiling(*args,&blk)
|
66
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
67
|
+
mapped = args[0]
|
68
|
+
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
69
|
+
record = ::Rack::MiniProfiler.record_sql(mapped, elapsed_time)
|
70
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
71
|
+
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
def send_query_prepared(*args,&blk)
|
76
|
+
return send_query_prepared_without_profiling(*args,&blk) unless SqlPatches.should_measure?
|
77
|
+
|
78
|
+
start = Time.now
|
79
|
+
result = send_query_prepared_without_profiling(*args,&blk)
|
80
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
81
|
+
mapped = args[0]
|
82
|
+
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
83
|
+
record = ::Rack::MiniProfiler.record_sql(mapped, elapsed_time)
|
84
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
85
|
+
|
86
|
+
result
|
87
|
+
end
|
88
|
+
|
89
|
+
def async_exec(*args,&blk)
|
90
|
+
return exec_without_profiling(*args,&blk) unless SqlPatches.should_measure?
|
91
|
+
|
92
|
+
start = Time.now
|
93
|
+
result = exec_without_profiling(*args,&blk)
|
94
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
95
|
+
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
96
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
97
|
+
|
98
|
+
result
|
99
|
+
end
|
100
|
+
|
101
|
+
alias_method :query, :exec
|
102
|
+
end
|
103
|
+
|
104
|
+
SqlPatches.patched = true
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# mongo_mapper patches
|
2
|
+
# TODO: Include overrides for distinct, update, cursor, and create
|
3
|
+
class Plucky::Query
|
4
|
+
alias_method :find_each_without_profiling, :find_each
|
5
|
+
alias_method :find_one_without_profiling, :find_one
|
6
|
+
alias_method :count_without_profiling, :count
|
7
|
+
alias_method :remove_without_profiling, :remove
|
8
|
+
|
9
|
+
def find_each(*args, &blk)
|
10
|
+
return profile_database_operation(__callee__, filtered_inspect(), *args, &blk)
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_one(*args, &blk)
|
14
|
+
return profile_database_operation(__callee__, filtered_inspect(args[0]), *args, &blk)
|
15
|
+
end
|
16
|
+
|
17
|
+
def count(*args, &blk)
|
18
|
+
return profile_database_operation(__callee__, filtered_inspect(), *args, &blk)
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove(*args, &blk)
|
22
|
+
return profile_database_operation(__callee__, filtered_inspect(), *args, &blk)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def profile_database_operation(method, message, *args, &blk)
|
28
|
+
return self.send("#{method.id2name}_without_profiling", *args, &blk) unless SqlPatches.should_measure?
|
29
|
+
|
30
|
+
start = Time.now
|
31
|
+
result = self.send("#{method.id2name}_without_profiling", *args, &blk)
|
32
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
33
|
+
|
34
|
+
query_message = "#{@collection.name}.#{method.id2name} => #{message}"
|
35
|
+
::Rack::MiniProfiler.record_sql(query_message, elapsed_time)
|
36
|
+
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
def filtered_inspect(hash = to_hash())
|
41
|
+
hash_string = hash.reject { |key| key == :transformer }.collect do |key, value|
|
42
|
+
" #{key}: #{value.inspect}"
|
43
|
+
end.join(",\n")
|
44
|
+
|
45
|
+
"{\n#{hash_string}\n}"
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class RSolr::Connection
|
2
|
+
alias_method :execute_without_profiling, :execute
|
3
|
+
def execute_with_profiling(client, request_context)
|
4
|
+
return execute_without_profiling(client, request_context) unless SqlPatches.should_measure?
|
5
|
+
|
6
|
+
start = Time.now
|
7
|
+
result = execute_without_profiling(client, request_context)
|
8
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
9
|
+
|
10
|
+
data = "#{request_context[:method].upcase} #{request_context[:uri]}"
|
11
|
+
if request_context[:method] == :post and request_context[:data]
|
12
|
+
if request_context[:headers].include?("Content-Type") and request_context[:headers]["Content-Type"] == "text/xml"
|
13
|
+
# it's xml, unescaping isn't needed
|
14
|
+
data << "\n#{request_context[:data]}"
|
15
|
+
else
|
16
|
+
data << "\n#{Rack::Utils.unescape(request_context[:data])}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
::Rack::MiniProfiler.record_sql(data, elapsed_time)
|
20
|
+
|
21
|
+
result
|
22
|
+
end
|
23
|
+
alias_method :execute, :execute_with_profiling
|
24
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Sequel
|
2
|
+
class Database
|
3
|
+
alias_method :log_duration_original, :log_duration
|
4
|
+
def log_duration(duration, message)
|
5
|
+
# `duration` will be in seconds, but we need it in milliseconds for internal consistency.
|
6
|
+
::Rack::MiniProfiler.record_sql(message, duration * 1000)
|
7
|
+
log_duration_original(duration, message)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/lib/patches/sql_patches.rb
CHANGED
@@ -19,266 +19,28 @@ class SqlPatches
|
|
19
19
|
rescue NameError
|
20
20
|
false
|
21
21
|
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# The best kind of instrumentation is in the actual db provider, however we don't want to double instrument
|
25
|
-
if SqlPatches.class_exists? "Mysql2::Client"
|
26
|
-
|
27
|
-
class Mysql2::Result
|
28
|
-
alias_method :each_without_profiling, :each
|
29
|
-
def each(*args, &blk)
|
30
|
-
return each_without_profiling(*args, &blk) unless @miniprofiler_sql_id
|
31
|
-
|
32
|
-
start = Time.now
|
33
|
-
result = each_without_profiling(*args,&blk)
|
34
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
35
22
|
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
def self.record_sql(statement, &block)
|
24
|
+
start = Time.now
|
25
|
+
result = yield
|
26
|
+
record = ::Rack::MiniProfiler.record_sql( statement, elapsed_time(start) )
|
27
|
+
return result, record
|
39
28
|
end
|
40
29
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
current = ::Rack::MiniProfiler.current
|
45
|
-
return query_without_profiling(*args,&blk) unless current && current.measure
|
46
|
-
|
47
|
-
start = Time.now
|
48
|
-
result = query_without_profiling(*args,&blk)
|
49
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
50
|
-
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
51
|
-
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
52
|
-
|
53
|
-
result
|
54
|
-
|
55
|
-
end
|
30
|
+
def self.should_measure?
|
31
|
+
current = ::Rack::MiniProfiler.current
|
32
|
+
(current && current.measure)
|
56
33
|
end
|
57
34
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
# PG patches, keep in mind exec and async_exec have a exec{|r| } semantics that is yet to be implemented
|
63
|
-
if SqlPatches.class_exists? "PG::Result"
|
64
|
-
|
65
|
-
class PG::Result
|
66
|
-
alias_method :each_without_profiling, :each
|
67
|
-
alias_method :values_without_profiling, :values
|
68
|
-
|
69
|
-
def values(*args, &blk)
|
70
|
-
return values_without_profiling(*args, &blk) unless @miniprofiler_sql_id
|
71
|
-
|
72
|
-
start = Time.now
|
73
|
-
result = values_without_profiling(*args,&blk)
|
74
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
75
|
-
|
76
|
-
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
77
|
-
result
|
78
|
-
end
|
79
|
-
|
80
|
-
def each(*args, &blk)
|
81
|
-
return each_without_profiling(*args, &blk) unless @miniprofiler_sql_id
|
82
|
-
|
83
|
-
start = Time.now
|
84
|
-
result = each_without_profiling(*args,&blk)
|
85
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
86
|
-
|
87
|
-
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
88
|
-
result
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class PG::Connection
|
93
|
-
alias_method :exec_without_profiling, :exec
|
94
|
-
alias_method :async_exec_without_profiling, :async_exec
|
95
|
-
alias_method :exec_prepared_without_profiling, :exec_prepared
|
96
|
-
alias_method :send_query_prepared_without_profiling, :send_query_prepared
|
97
|
-
alias_method :prepare_without_profiling, :prepare
|
98
|
-
|
99
|
-
def prepare(*args,&blk)
|
100
|
-
# we have no choice but to do this here,
|
101
|
-
# if we do the check for profiling first, our cache may miss critical stuff
|
102
|
-
|
103
|
-
@prepare_map ||= {}
|
104
|
-
@prepare_map[args[0]] = args[1]
|
105
|
-
# dont leak more than 10k ever
|
106
|
-
@prepare_map = {} if @prepare_map.length > 1000
|
107
|
-
|
108
|
-
current = ::Rack::MiniProfiler.current
|
109
|
-
return prepare_without_profiling(*args,&blk) unless current && current.measure
|
110
|
-
|
111
|
-
prepare_without_profiling(*args,&blk)
|
112
|
-
end
|
113
|
-
|
114
|
-
def exec(*args,&blk)
|
115
|
-
current = ::Rack::MiniProfiler.current
|
116
|
-
return exec_without_profiling(*args,&blk) unless current && current.measure
|
117
|
-
|
118
|
-
start = Time.now
|
119
|
-
result = exec_without_profiling(*args,&blk)
|
120
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
121
|
-
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
122
|
-
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
123
|
-
|
124
|
-
result
|
125
|
-
end
|
126
|
-
|
127
|
-
def exec_prepared(*args,&blk)
|
128
|
-
current = ::Rack::MiniProfiler.current
|
129
|
-
return exec_prepared_without_profiling(*args,&blk) unless current && current.measure
|
130
|
-
|
131
|
-
start = Time.now
|
132
|
-
result = exec_prepared_without_profiling(*args,&blk)
|
133
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
134
|
-
mapped = args[0]
|
135
|
-
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
136
|
-
record = ::Rack::MiniProfiler.record_sql(mapped, elapsed_time)
|
137
|
-
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
138
|
-
|
139
|
-
result
|
140
|
-
end
|
141
|
-
|
142
|
-
def send_query_prepared(*args,&blk)
|
143
|
-
current = ::Rack::MiniProfiler.current
|
144
|
-
return send_query_prepared_without_profiling(*args,&blk) unless current && current.measure
|
145
|
-
|
146
|
-
start = Time.now
|
147
|
-
result = send_query_prepared_without_profiling(*args,&blk)
|
148
|
-
|
149
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
150
|
-
mapped = args[0]
|
151
|
-
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
152
|
-
record = ::Rack::MiniProfiler.record_sql(mapped, elapsed_time)
|
153
|
-
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
154
|
-
|
155
|
-
result
|
156
|
-
end
|
157
|
-
|
158
|
-
def async_exec(*args,&blk)
|
159
|
-
current = ::Rack::MiniProfiler.current
|
160
|
-
return exec_without_profiling(*args,&blk) unless current && current.measure
|
161
|
-
|
162
|
-
start = Time.now
|
163
|
-
result = exec_without_profiling(*args,&blk)
|
164
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
165
|
-
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
166
|
-
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
167
|
-
|
168
|
-
result
|
169
|
-
end
|
170
|
-
|
171
|
-
alias_method :query, :exec
|
172
|
-
end
|
173
|
-
|
174
|
-
SqlPatches.patched = true
|
175
|
-
end
|
176
|
-
|
177
|
-
|
178
|
-
# Mongoid 3 patches
|
179
|
-
if SqlPatches.class_exists?("Moped::Node")
|
180
|
-
class Moped::Node
|
181
|
-
alias_method :process_without_profiling, :process
|
182
|
-
def process(*args,&blk)
|
183
|
-
current = ::Rack::MiniProfiler.current
|
184
|
-
return process_without_profiling(*args,&blk) unless current && current.measure
|
185
|
-
|
186
|
-
start = Time.now
|
187
|
-
result = process_without_profiling(*args,&blk)
|
188
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
189
|
-
::Rack::MiniProfiler.record_sql(args[0].log_inspect, elapsed_time)
|
190
|
-
|
191
|
-
result
|
192
|
-
end
|
35
|
+
def self.elapsed_time(start_time)
|
36
|
+
((Time.now - start_time).to_f * 1000).round(1)
|
193
37
|
end
|
194
38
|
end
|
195
39
|
|
196
|
-
if SqlPatches.class_exists?
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
start = Time.now
|
204
|
-
result = execute_without_profiling(client, request_context)
|
205
|
-
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
206
|
-
|
207
|
-
data = "#{request_context[:method].upcase} #{request_context[:uri]}"
|
208
|
-
if request_context[:method] == :post and request_context[:data]
|
209
|
-
if request_context[:headers].include?("Content-Type") and request_context[:headers]["Content-Type"] == "text/xml"
|
210
|
-
# it's xml, unescaping isn't needed
|
211
|
-
data << "\n#{request_context[:data]}"
|
212
|
-
else
|
213
|
-
data << "\n#{Rack::Utils.unescape(request_context[:data])}"
|
214
|
-
end
|
215
|
-
end
|
216
|
-
::Rack::MiniProfiler.record_sql(data, elapsed_time)
|
217
|
-
|
218
|
-
result
|
219
|
-
end
|
220
|
-
alias_method :execute, :execute_with_profiling
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
|
225
|
-
# Fallback for sequel
|
226
|
-
if SqlPatches.class_exists?("Sequel::Database") && !SqlPatches.patched?
|
227
|
-
module Sequel
|
228
|
-
class Database
|
229
|
-
alias_method :log_duration_original, :log_duration
|
230
|
-
def log_duration(duration, message)
|
231
|
-
# `duration` will be in seconds, but we need it in milliseconds for internal consistency.
|
232
|
-
::Rack::MiniProfiler.record_sql(message, duration * 1000)
|
233
|
-
log_duration_original(duration, message)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
|
240
|
-
## based off https://github.com/newrelic/rpm/blob/master/lib/new_relic/agent/instrumentation/active_record.rb
|
241
|
-
## fallback for alls sorts of weird dbs
|
242
|
-
if SqlPatches.module_exists?('ActiveRecord') && !SqlPatches.patched?
|
243
|
-
module Rack
|
244
|
-
class MiniProfiler
|
245
|
-
module ActiveRecordInstrumentation
|
246
|
-
def self.included(instrumented_class)
|
247
|
-
instrumented_class.class_eval do
|
248
|
-
unless instrumented_class.method_defined?(:log_without_miniprofiler)
|
249
|
-
alias_method :log_without_miniprofiler, :log
|
250
|
-
alias_method :log, :log_with_miniprofiler
|
251
|
-
protected :log
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
def log_with_miniprofiler(*args, &block)
|
257
|
-
current = ::Rack::MiniProfiler.current
|
258
|
-
return log_without_miniprofiler(*args, &block) unless current && current.measure
|
259
|
-
|
260
|
-
sql, name, binds = args
|
261
|
-
t0 = Time.now
|
262
|
-
rval = log_without_miniprofiler(*args, &block)
|
263
|
-
|
264
|
-
# Don't log schema queries if the option is set
|
265
|
-
return rval if Rack::MiniProfiler.config.skip_schema_queries and name =~ /SCHEMA/
|
266
|
-
|
267
|
-
elapsed_time = ((Time.now - t0).to_f * 1000).round(1)
|
268
|
-
Rack::MiniProfiler.record_sql(sql, elapsed_time)
|
269
|
-
rval
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
def self.insert_instrumentation
|
275
|
-
ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
|
276
|
-
include ::Rack::MiniProfiler::ActiveRecordInstrumentation
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
if defined?(::Rails) && !SqlPatches.patched?
|
281
|
-
insert_instrumentation
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
40
|
+
require 'patches/db/mysql2' if SqlPatches.class_exists? "Mysql2::Client"
|
41
|
+
require 'patches/db/pg' if SqlPatches.class_exists? "PG::Result"
|
42
|
+
require 'patches/db/moped' if SqlPatches.class_exists?("Moped::Node")
|
43
|
+
require 'patches/db/plucky' if SqlPatches.class_exists?("Plucky::Query")
|
44
|
+
require 'patches/db/rsolr' if SqlPatches.class_exists?("RSolr::Connection") && RSolr::VERSION[0] != "0"
|
45
|
+
require 'patches/db/sequel' if !SqlPatches.patched? && SqlPatches.class_exists?("Sequel::Database")
|
46
|
+
require 'patches/db/activerecord' if !SqlPatches.patched? && SqlPatches.module_exists?("ActiveRecord")
|