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.

Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -3
  3. data/lib/html/includes.css +15 -4
  4. data/lib/html/includes.js +93 -58
  5. data/lib/html/includes.less +21 -5
  6. data/lib/html/includes.tmpl +49 -49
  7. data/lib/html/list.tmpl +8 -8
  8. data/lib/mini_profiler/asset_version.rb +5 -0
  9. data/lib/mini_profiler/client_settings.rb +3 -3
  10. data/lib/mini_profiler/config.rb +11 -11
  11. data/lib/mini_profiler/gc_profiler.rb +10 -10
  12. data/lib/mini_profiler/profiler.rb +49 -71
  13. data/lib/mini_profiler/profiling_methods.rb +15 -17
  14. data/lib/mini_profiler/storage/file_store.rb +4 -4
  15. data/lib/mini_profiler/storage/memcache_store.rb +5 -7
  16. data/lib/mini_profiler/storage/memory_store.rb +56 -27
  17. data/lib/mini_profiler/storage/redis_store.rb +19 -11
  18. data/lib/mini_profiler/timer_struct/base.rb +33 -0
  19. data/lib/mini_profiler/timer_struct/client.rb +89 -0
  20. data/lib/mini_profiler/timer_struct/custom.rb +22 -0
  21. data/lib/mini_profiler/timer_struct/page.rb +62 -0
  22. data/lib/mini_profiler/timer_struct/request.rb +126 -0
  23. data/lib/mini_profiler/timer_struct/sql.rb +59 -0
  24. data/lib/mini_profiler/version.rb +2 -2
  25. data/lib/patches/db/activerecord.rb +42 -0
  26. data/lib/patches/db/moped.rb +12 -0
  27. data/lib/patches/db/mysql2.rb +30 -0
  28. data/lib/patches/db/pg.rb +104 -0
  29. data/lib/patches/db/plucky.rb +47 -0
  30. data/lib/patches/db/rsolr.rb +24 -0
  31. data/lib/patches/db/sequel.rb +10 -0
  32. data/lib/patches/sql_patches.rb +17 -255
  33. data/lib/rack-mini-profiler.rb +28 -0
  34. data/rack-mini-profiler.gemspec +6 -2
  35. metadata +16 -8
  36. data/lib/mini_profiler/client_timer_struct.rb +0 -78
  37. data/lib/mini_profiler/custom_timer_struct.rb +0 -22
  38. data/lib/mini_profiler/page_timer_struct.rb +0 -58
  39. data/lib/mini_profiler/request_timer_struct.rb +0 -115
  40. data/lib/mini_profiler/sql_timer_struct.rb +0 -58
  41. 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
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class MiniProfiler
3
- VERSION = '898a13ca6797c6bc1fee313e17d388b0'.freeze
3
+ VERSION = '0.9.3'
4
4
  end
5
- end
5
+ 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
@@ -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
- @miniprofiler_sql_id.report_reader_duration(elapsed_time)
37
- result
38
- end
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
- class Mysql2::Client
42
- alias_method :query_without_profiling, :query
43
- def query(*args,&blk)
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
- SqlPatches.patched = true
59
- end
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?("RSolr::Connection") && RSolr::VERSION[0] != "0" # requires at least v1.0.0
197
- class RSolr::Connection
198
- alias_method :execute_without_profiling, :execute
199
- def execute_with_profiling(client, request_context)
200
- current = ::Rack::MiniProfiler.current
201
- return execute_without_profiling(client, request_context) unless current && current.measure
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")