rack-mini-profiler 0.1.22 → 0.1.27

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack-mini-profiler might be problematic. Click here for more details.

Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/Ruby/CHANGELOG +69 -35
  3. data/Ruby/README.md +47 -9
  4. data/Ruby/lib/html/flamegraph.html +351 -0
  5. data/Ruby/lib/html/includes.css +451 -75
  6. data/Ruby/lib/html/includes.js +134 -23
  7. data/Ruby/lib/html/includes.less +38 -35
  8. data/Ruby/lib/html/includes.tmpl +40 -15
  9. data/Ruby/lib/html/jquery.1.7.1.js +1 -1
  10. data/Ruby/lib/html/jquery.tmpl.js +1 -1
  11. data/Ruby/lib/html/list.js +7 -6
  12. data/Ruby/lib/html/profile_handler.js +1 -62
  13. data/Ruby/lib/mini_profiler/client_timer_struct.rb +1 -1
  14. data/Ruby/lib/mini_profiler/config.rb +58 -52
  15. data/Ruby/lib/mini_profiler/context.rb +11 -10
  16. data/Ruby/lib/mini_profiler/custom_timer_struct.rb +22 -0
  17. data/Ruby/lib/mini_profiler/flame_graph.rb +54 -0
  18. data/Ruby/lib/mini_profiler/gc_profiler.rb +8 -4
  19. data/Ruby/lib/mini_profiler/page_timer_struct.rb +7 -2
  20. data/Ruby/lib/mini_profiler/profiler.rb +207 -157
  21. data/Ruby/lib/mini_profiler/profiling_methods.rb +131 -108
  22. data/Ruby/lib/mini_profiler/request_timer_struct.rb +20 -1
  23. data/Ruby/lib/mini_profiler/sql_timer_struct.rb +1 -1
  24. data/Ruby/lib/mini_profiler/storage/abstract_store.rb +31 -27
  25. data/Ruby/lib/mini_profiler/storage/file_store.rb +111 -109
  26. data/Ruby/lib/mini_profiler/storage/memcache_store.rb +11 -9
  27. data/Ruby/lib/mini_profiler/storage/memory_store.rb +65 -63
  28. data/Ruby/lib/mini_profiler/storage/redis_store.rb +54 -44
  29. data/Ruby/lib/mini_profiler/version.rb +5 -0
  30. data/Ruby/lib/mini_profiler_rails/railtie.rb +44 -40
  31. data/Ruby/lib/patches/net_patches.rb +14 -0
  32. data/Ruby/lib/patches/sql_patches.rb +89 -48
  33. data/Ruby/lib/rack-mini-profiler.rb +1 -0
  34. data/rack-mini-profiler.gemspec +1 -1
  35. metadata +41 -52
@@ -2,17 +2,19 @@ module Rack
2
2
  class MiniProfiler
3
3
  class MemcacheStore < AbstractStore
4
4
 
5
- EXPIRE_SECONDS = 60*60*24
5
+ EXPIRES_IN_SECONDS = 60 * 60 * 24
6
6
  MAX_RETRIES = 10
7
7
 
8
- def initialize(client = nil, prefix = "MPMemcacheStore")
8
+ def initialize(args = nil)
9
9
  require 'dalli' unless defined? Dalli
10
- @prefix = prefix
11
- @client = client || Dalli::Client.new(['localhost:11211'])
10
+ args ||= {}
11
+ @prefix = args[:prefix] || "MPMemcacheStore"
12
+ @client = args[:client] || Dalli::Client.new
13
+ @expires_in_seconds = args[:expires_in] || EXPIRES_IN_SECONDS
12
14
  end
13
15
 
14
16
  def save(page_struct)
15
- @client.set("#{@prefix}#{page_struct['Id']}", Marshal::dump(page_struct), EXPIRE_SECONDS)
17
+ @client.set("#{@prefix}#{page_struct['Id']}", Marshal::dump(page_struct), @expires_in_seconds)
16
18
  end
17
19
 
18
20
  def load(id)
@@ -23,9 +25,9 @@ module Rack
23
25
  end
24
26
 
25
27
  def set_unviewed(user, id)
26
- @client.add("#{@prefix}-#{user}-v", [], EXPIRE_SECONDS)
28
+ @client.add("#{@prefix}-#{user}-v", [], @expires_in_seconds)
27
29
  MAX_RETRIES.times do
28
- break if @client.cas("#{@prefix}-#{user}-v", EXPIRE_SECONDS) do |ids|
30
+ break if @client.cas("#{@prefix}-#{user}-v", @expires_in_seconds) do |ids|
29
31
  ids << id unless ids.include?(id)
30
32
  ids
31
33
  end
@@ -33,9 +35,9 @@ module Rack
33
35
  end
34
36
 
35
37
  def set_viewed(user, id)
36
- @client.add("#{@prefix}-#{user}-v", [], EXPIRE_SECONDS)
38
+ @client.add("#{@prefix}-#{user}-v", [], @expires_in_seconds)
37
39
  MAX_RETRIES.times do
38
- break if @client.cas("#{@prefix}-#{user}-v", EXPIRE_SECONDS) do |ids|
40
+ break if @client.cas("#{@prefix}-#{user}-v", @expires_in_seconds) do |ids|
39
41
  ids.delete id
40
42
  ids
41
43
  end
@@ -1,63 +1,65 @@
1
- module Rack
2
- class MiniProfiler
3
- class MemoryStore < AbstractStore
4
-
5
- EXPIRE_TIMER_CACHE = 3600 * 24
6
-
7
- def initialize(args)
8
- @timer_struct_lock = Mutex.new
9
- @timer_struct_cache = {}
10
- @user_view_lock = Mutex.new
11
- @user_view_cache = {}
12
-
13
- # TODO: fix it to use weak ref, trouble is may be broken in 1.9 so need to use the 'ref' gem
14
- me = self
15
- Thread.new do
16
- while true do
17
- me.cleanup_cache
18
- sleep(3600)
19
- end
20
- end
21
- end
22
-
23
- def save(page_struct)
24
- @timer_struct_lock.synchronize {
25
- @timer_struct_cache[page_struct['Id']] = page_struct
26
- }
27
- end
28
-
29
- def load(id)
30
- @timer_struct_lock.synchronize {
31
- @timer_struct_cache[id]
32
- }
33
- end
34
-
35
- def set_unviewed(user, id)
36
- @user_view_lock.synchronize {
37
- @user_view_cache[user] ||= []
38
- @user_view_cache[user] << id
39
- }
40
- end
41
-
42
- def set_viewed(user, id)
43
- @user_view_lock.synchronize {
44
- @user_view_cache[user] ||= []
45
- @user_view_cache[user].delete(id)
46
- }
47
- end
48
-
49
- def get_unviewed_ids(user)
50
- @user_view_lock.synchronize {
51
- @user_view_cache[user]
52
- }
53
- end
54
-
55
- def cleanup_cache
56
- expire_older_than = ((Time.now.to_f - MiniProfiler::MemoryStore::EXPIRE_TIMER_CACHE) * 1000).to_i
57
- @timer_struct_lock.synchronize {
58
- @timer_struct_cache.delete_if { |k, v| v['Started'] < expire_older_than }
59
- }
60
- end
61
- end
62
- end
63
- end
1
+ module Rack
2
+ class MiniProfiler
3
+ class MemoryStore < AbstractStore
4
+
5
+ EXPIRES_IN_SECONDS = 60 * 60 * 24
6
+
7
+ def initialize(args = nil)
8
+ args ||= {}
9
+ @expires_in_seconds = args[:expires_in] || EXPIRES_IN_SECONDS
10
+ @timer_struct_lock = Mutex.new
11
+ @timer_struct_cache = {}
12
+ @user_view_lock = Mutex.new
13
+ @user_view_cache = {}
14
+
15
+ # TODO: fix it to use weak ref, trouble is may be broken in 1.9 so need to use the 'ref' gem
16
+ me = self
17
+ Thread.new do
18
+ while true do
19
+ me.cleanup_cache
20
+ sleep(3600)
21
+ end
22
+ end
23
+ end
24
+
25
+ def save(page_struct)
26
+ @timer_struct_lock.synchronize {
27
+ @timer_struct_cache[page_struct['Id']] = page_struct
28
+ }
29
+ end
30
+
31
+ def load(id)
32
+ @timer_struct_lock.synchronize {
33
+ @timer_struct_cache[id]
34
+ }
35
+ end
36
+
37
+ def set_unviewed(user, id)
38
+ @user_view_lock.synchronize {
39
+ @user_view_cache[user] ||= []
40
+ @user_view_cache[user] << id
41
+ }
42
+ end
43
+
44
+ def set_viewed(user, id)
45
+ @user_view_lock.synchronize {
46
+ @user_view_cache[user] ||= []
47
+ @user_view_cache[user].delete(id)
48
+ }
49
+ end
50
+
51
+ def get_unviewed_ids(user)
52
+ @user_view_lock.synchronize {
53
+ @user_view_cache[user]
54
+ }
55
+ end
56
+
57
+ def cleanup_cache
58
+ expire_older_than = ((Time.now.to_f - @expires_in_seconds) * 1000).to_i
59
+ @timer_struct_lock.synchronize {
60
+ @timer_struct_cache.delete_if { |k, v| v['Started'] < expire_older_than }
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,44 +1,54 @@
1
- module Rack
2
- class MiniProfiler
3
- class RedisStore < AbstractStore
4
-
5
- EXPIRE_SECONDS = 60 * 60 * 24
6
-
7
- def initialize(args)
8
- args ||= {}
9
- @prefix = args[:prefix] || 'MPRedisStore'
10
- end
11
-
12
- def save(page_struct)
13
- redis.setex "#{@prefix}#{page_struct['Id']}", EXPIRE_SECONDS, Marshal::dump(page_struct)
14
- end
15
-
16
- def load(id)
17
- raw = redis.get "#{@prefix}#{id}"
18
- if raw
19
- Marshal::load raw
20
- end
21
- end
22
-
23
- def set_unviewed(user, id)
24
- redis.sadd "#{@prefix}-#{user}-v", id
25
- end
26
-
27
- def set_viewed(user, id)
28
- redis.srem "#{@prefix}-#{user}-v", id
29
- end
30
-
31
- def get_unviewed_ids(user)
32
- redis.smembers "#{@prefix}-#{user}-v"
33
- end
34
-
35
- private
36
-
37
- def redis
38
- require 'redis' unless defined? Redis
39
- Redis.new
40
- end
41
-
42
- end
43
- end
44
- end
1
+ module Rack
2
+ class MiniProfiler
3
+ class RedisStore < AbstractStore
4
+
5
+ EXPIRES_IN_SECONDS = 60 * 60 * 24
6
+
7
+ def initialize(args = nil)
8
+ @args = args || {}
9
+ @prefix = @args.delete(:prefix) || 'MPRedisStore'
10
+ @redis_connection = @args.delete(:connection)
11
+ @expires_in_seconds = @args.delete(:expires_in) || EXPIRES_IN_SECONDS
12
+ end
13
+
14
+ def save(page_struct)
15
+ redis.setex "#{@prefix}#{page_struct['Id']}", @expires_in_seconds, Marshal::dump(page_struct)
16
+ end
17
+
18
+ def load(id)
19
+ raw = redis.get "#{@prefix}#{id}"
20
+ if raw
21
+ Marshal::load raw
22
+ end
23
+ end
24
+
25
+ def set_unviewed(user, id)
26
+ redis.sadd "#{@prefix}-#{user}-v", id
27
+ end
28
+
29
+ def set_viewed(user, id)
30
+ redis.srem "#{@prefix}-#{user}-v", id
31
+ end
32
+
33
+ def get_unviewed_ids(user)
34
+ redis.smembers "#{@prefix}-#{user}-v"
35
+ end
36
+
37
+ def diagnostics(user)
38
+ "Redis prefix: #{@prefix}
39
+ Redis location: #{redis.client.host}:#{redis.client.port} db: #{redis.client.db}
40
+ unviewed_ids: #{get_unviewed_ids(user)}
41
+ "
42
+ end
43
+
44
+ private
45
+
46
+ def redis
47
+ return @redis_connection if @redis_connection
48
+ require 'redis' unless defined? Redis
49
+ @redis_connection ||= Redis.new @args
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class MiniProfiler
3
+ VERSION = 'cc5e38497a61f98499f27184d21dbcd1'.freeze
4
+ end
5
+ end
@@ -1,61 +1,65 @@
1
1
  require 'fileutils'
2
2
 
3
- module MiniProfilerRails
3
+ module Rack::MiniProfilerRails
4
4
 
5
- class Railtie < ::Rails::Railtie
5
+ # call direct if needed to do a defer init
6
+ def self.initialize!(app)
7
+ c = Rack::MiniProfiler.config
6
8
 
7
- initializer "rack_mini_profiler.configure_rails_initialization" do |app|
8
- c = Rack::MiniProfiler.config
9
+ # By default, only show the MiniProfiler in development mode, in production allow profiling if post_authorize_cb is set
10
+ c.pre_authorize_cb = lambda { |env|
11
+ !Rails.env.test?
12
+ }
9
13
 
10
- # By default, only show the MiniProfiler in development mode, in production allow profiling if post_authorize_cb is set
11
- c.pre_authorize_cb = lambda { |env|
12
- Rails.env.development? || Rails.env.production?
13
- }
14
+ c.skip_paths ||= []
14
15
 
15
- c.skip_paths ||= []
16
+ if Rails.env.development?
17
+ c.skip_paths << "/assets/"
18
+ c.skip_schema_queries = true
19
+ end
16
20
 
17
- if Rails.env.development?
18
- c.skip_paths << "/assets/"
19
- c.skip_schema_queries = true
20
- end
21
+ if Rails.env.production?
22
+ c.authorization_mode = :whitelist
23
+ end
21
24
 
22
- if Rails.env.production?
23
- c.authorization_mode = :whitelist
24
- end
25
+ # The file store is just so much less flaky
26
+ tmp = Rails.root.to_s + "/tmp/miniprofiler"
27
+ FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
25
28
 
26
- # The file store is just so much less flaky
27
- tmp = Rails.root.to_s + "/tmp/miniprofiler"
28
- FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
29
+ c.storage_options = {:path => tmp}
30
+ c.storage = Rack::MiniProfiler::FileStore
29
31
 
30
- c.storage_options = {:path => tmp}
31
- c.storage = Rack::MiniProfiler::FileStore
32
+ # Quiet the SQL stack traces
33
+ c.backtrace_remove = Rails.root.to_s + "/"
34
+ c.backtrace_includes = [/^\/?(app|config|lib|test)/]
35
+ c.skip_schema_queries = Rails.env != 'production'
32
36
 
33
- # Quiet the SQL stack traces
34
- c.backtrace_remove = Rails.root.to_s + "/"
35
- c.backtrace_includes = [/^\/?(app|config|lib|test)/]
36
- c.skip_schema_queries = Rails.env != 'production'
37
+ # Install the Middleware
38
+ app.middleware.insert(0, Rack::MiniProfiler)
37
39
 
38
- # Install the Middleware
39
- app.middleware.insert(0, Rack::MiniProfiler)
40
+ # Attach to various Rails methods
41
+ ::Rack::MiniProfiler.profile_method(ActionController::Base, :process) {|action| "Executing action: #{action}"}
42
+ ::Rack::MiniProfiler.profile_method(ActionView::Template, :render) {|x,y| "Rendering: #{@virtual_path}"}
43
+ end
40
44
 
41
- # Attach to various Rails methods
42
- ::Rack::MiniProfiler.profile_method(ActionController::Base, :process) {|action| "Executing action: #{action}"}
43
- ::Rack::MiniProfiler.profile_method(ActionView::Template, :render) {|x,y| "Rendering: #{@virtual_path}"}
45
+ class Railtie < ::Rails::Railtie
44
46
 
47
+ initializer "rack_mini_profiler.configure_rails_initialization" do |app|
48
+ Rack::MiniProfilerRails.initialize!(app)
45
49
  end
46
50
 
47
51
  # TODO: Implement something better here
48
- # config.after_initialize do
49
- #
50
- # class ::ActionView::Helpers::AssetTagHelper::JavascriptIncludeTag
52
+ # config.after_initialize do
53
+ #
54
+ # class ::ActionView::Helpers::AssetTagHelper::JavascriptIncludeTag
51
55
  # alias_method :asset_tag_orig, :asset_tag
52
56
  # def asset_tag(source,options)
53
- # current = Rack::MiniProfiler.current
54
- # return asset_tag_orig(source,options) unless current
57
+ # current = Rack::MiniProfiler.current
58
+ # return asset_tag_orig(source,options) unless current
55
59
  # wrapped = ""
56
60
  # unless current.mpt_init
57
61
  # current.mpt_init = true
58
- # wrapped << Rack::MiniProfiler::ClientTimerStruct.init_instrumentation
62
+ # wrapped << Rack::MiniProfiler::ClientTimerStruct.init_instrumentation
59
63
  # end
60
64
  # name = source.split('/')[-1]
61
65
  # wrapped << Rack::MiniProfiler::ClientTimerStruct.instrument(name, asset_tag_orig(source,options)).html_safe
@@ -63,15 +67,15 @@ module MiniProfilerRails
63
67
  # end
64
68
  # end
65
69
 
66
- # class ::ActionView::Helpers::AssetTagHelper::StylesheetIncludeTag
70
+ # class ::ActionView::Helpers::AssetTagHelper::StylesheetIncludeTag
67
71
  # alias_method :asset_tag_orig, :asset_tag
68
72
  # def asset_tag(source,options)
69
- # current = Rack::MiniProfiler.current
70
- # return asset_tag_orig(source,options) unless current
73
+ # current = Rack::MiniProfiler.current
74
+ # return asset_tag_orig(source,options) unless current
71
75
  # wrapped = ""
72
76
  # unless current.mpt_init
73
77
  # current.mpt_init = true
74
- # wrapped << Rack::MiniProfiler::ClientTimerStruct.init_instrumentation
78
+ # wrapped << Rack::MiniProfiler::ClientTimerStruct.init_instrumentation
75
79
  # end
76
80
  # name = source.split('/')[-1]
77
81
  # wrapped << Rack::MiniProfiler::ClientTimerStruct.instrument(name, asset_tag_orig(source,options)).html_safe
@@ -0,0 +1,14 @@
1
+ if (defined?(Net) && defined?(Net::HTTP))
2
+
3
+ Net::HTTP.class_eval do
4
+ def request_with_mini_profiler(*args, &block)
5
+ request = args[0]
6
+ Rack::MiniProfiler.step("Net::HTTP #{request.method} #{request.path}") do
7
+ request_without_mini_profiler(*args, &block)
8
+ end
9
+ end
10
+ alias request_without_mini_profiler request
11
+ alias request request_with_mini_profiler
12
+ end
13
+
14
+ end
@@ -8,32 +8,32 @@ class SqlPatches
8
8
  @patched = val
9
9
  end
10
10
 
11
- def self.class_exists?(name)
12
- eval(name + ".class").to_s.eql?('Class')
13
- rescue NameError
14
- false
15
- end
16
-
11
+ def self.class_exists?(name)
12
+ eval(name + ".class").to_s.eql?('Class')
13
+ rescue NameError
14
+ false
15
+ end
16
+
17
17
  def self.module_exists?(name)
18
- eval(name + ".class").to_s.eql?('Module')
19
- rescue NameError
20
- false
21
- end
18
+ eval(name + ".class").to_s.eql?('Module')
19
+ rescue NameError
20
+ false
21
+ end
22
22
  end
23
23
 
24
24
  # The best kind of instrumentation is in the actual db provider, however we don't want to double instrument
25
25
  if SqlPatches.class_exists? "Mysql2::Client"
26
-
26
+
27
27
  class Mysql2::Result
28
28
  alias_method :each_without_profiling, :each
29
29
  def each(*args, &blk)
30
30
  return each_without_profiling(*args, &blk) unless @miniprofiler_sql_id
31
31
 
32
32
  start = Time.now
33
- result = each_without_profiling(*args,&blk)
33
+ result = each_without_profiling(*args,&blk)
34
34
  elapsed_time = ((Time.now - start).to_f * 1000).round(1)
35
35
 
36
- @miniprofiler_sql_id.report_reader_duration(elapsed_time)
36
+ @miniprofiler_sql_id.report_reader_duration(elapsed_time)
37
37
  result
38
38
  end
39
39
  end
@@ -42,7 +42,7 @@ if SqlPatches.class_exists? "Mysql2::Client"
42
42
  alias_method :query_without_profiling, :query
43
43
  def query(*args,&blk)
44
44
  current = ::Rack::MiniProfiler.current
45
- return query_without_profiling(*args,&blk) unless current
45
+ return query_without_profiling(*args,&blk) unless current && current.measure
46
46
 
47
47
  start = Time.now
48
48
  result = query_without_profiling(*args,&blk)
@@ -53,14 +53,14 @@ if SqlPatches.class_exists? "Mysql2::Client"
53
53
 
54
54
  end
55
55
  end
56
-
56
+
57
57
  SqlPatches.patched = true
58
58
  end
59
59
 
60
60
 
61
- # PG patches, keep in mind exec and async_exec have a exec{|r| } semantics that is yet to be implemented
61
+ # PG patches, keep in mind exec and async_exec have a exec{|r| } semantics that is yet to be implemented
62
62
  if SqlPatches.class_exists? "PG::Result"
63
-
63
+
64
64
  class PG::Result
65
65
  alias_method :each_without_profiling, :each
66
66
  alias_method :values_without_profiling, :values
@@ -69,10 +69,10 @@ if SqlPatches.class_exists? "PG::Result"
69
69
  return values_without_profiling(*args, &blk) unless @miniprofiler_sql_id
70
70
 
71
71
  start = Time.now
72
- result = values_without_profiling(*args,&blk)
72
+ result = values_without_profiling(*args,&blk)
73
73
  elapsed_time = ((Time.now - start).to_f * 1000).round(1)
74
74
 
75
- @miniprofiler_sql_id.report_reader_duration(elapsed_time)
75
+ @miniprofiler_sql_id.report_reader_duration(elapsed_time)
76
76
  result
77
77
  end
78
78
 
@@ -80,10 +80,10 @@ if SqlPatches.class_exists? "PG::Result"
80
80
  return each_without_profiling(*args, &blk) unless @miniprofiler_sql_id
81
81
 
82
82
  start = Time.now
83
- result = each_without_profiling(*args,&blk)
83
+ result = each_without_profiling(*args,&blk)
84
84
  elapsed_time = ((Time.now - start).to_f * 1000).round(1)
85
85
 
86
- @miniprofiler_sql_id.report_reader_duration(elapsed_time)
86
+ @miniprofiler_sql_id.report_reader_duration(elapsed_time)
87
87
  result
88
88
  end
89
89
  end
@@ -96,23 +96,23 @@ if SqlPatches.class_exists? "PG::Result"
96
96
  alias_method :prepare_without_profiling, :prepare
97
97
 
98
98
  def prepare(*args,&blk)
99
- # we have no choice but to do this here,
100
- # if we do the check for profiling first, our cache may miss critical stuff
101
-
99
+ # we have no choice but to do this here,
100
+ # if we do the check for profiling first, our cache may miss critical stuff
101
+
102
102
  @prepare_map ||= {}
103
103
  @prepare_map[args[0]] = args[1]
104
104
  # dont leak more than 10k ever
105
105
  @prepare_map = {} if @prepare_map.length > 1000
106
106
 
107
107
  current = ::Rack::MiniProfiler.current
108
- return prepare_without_profiling(*args,&blk) unless current
108
+ return prepare_without_profiling(*args,&blk) unless current && current.measure
109
109
 
110
- prepare_without_profiling(*args,&blk)
110
+ prepare_without_profiling(*args,&blk)
111
111
  end
112
112
 
113
113
  def exec(*args,&blk)
114
114
  current = ::Rack::MiniProfiler.current
115
- return exec_without_profiling(*args,&blk) unless current
115
+ return exec_without_profiling(*args,&blk) unless current && current.measure
116
116
 
117
117
  start = Time.now
118
118
  result = exec_without_profiling(*args,&blk)
@@ -124,7 +124,7 @@ if SqlPatches.class_exists? "PG::Result"
124
124
 
125
125
  def exec_prepared(*args,&blk)
126
126
  current = ::Rack::MiniProfiler.current
127
- return exec_prepared_without_profiling(*args,&blk) unless current
127
+ return exec_prepared_without_profiling(*args,&blk) unless current && current.measure
128
128
 
129
129
  start = Time.now
130
130
  result = exec_prepared_without_profiling(*args,&blk)
@@ -135,10 +135,10 @@ if SqlPatches.class_exists? "PG::Result"
135
135
 
136
136
  result
137
137
  end
138
-
138
+
139
139
  def send_query_prepared(*args,&blk)
140
140
  current = ::Rack::MiniProfiler.current
141
- return send_query_prepared_without_profiling(*args,&blk) unless current
141
+ return send_query_prepared_without_profiling(*args,&blk) unless current && current.measure
142
142
 
143
143
  start = Time.now
144
144
  result = send_query_prepared_without_profiling(*args,&blk)
@@ -149,10 +149,10 @@ if SqlPatches.class_exists? "PG::Result"
149
149
 
150
150
  result
151
151
  end
152
-
152
+
153
153
  def async_exec(*args,&blk)
154
154
  current = ::Rack::MiniProfiler.current
155
- return exec_without_profiling(*args,&blk) unless current
155
+ return exec_without_profiling(*args,&blk) unless current && current.measure
156
156
 
157
157
  start = Time.now
158
158
  result = exec_without_profiling(*args,&blk)
@@ -161,34 +161,75 @@ if SqlPatches.class_exists? "PG::Result"
161
161
 
162
162
  result
163
163
  end
164
-
164
+
165
165
  alias_method :query, :exec
166
166
  end
167
-
167
+
168
168
  SqlPatches.patched = true
169
169
  end
170
170
 
171
171
 
172
+ # Mongoid 3 patches
173
+ if SqlPatches.class_exists?("Moped::Node")
174
+ class Moped::Node
175
+ alias_method :process_without_profiling, :process
176
+ def process(*args,&blk)
177
+ current = ::Rack::MiniProfiler.current
178
+ return process_without_profiling(*args,&blk) unless current && current.measure
179
+
180
+ start = Time.now
181
+ result = process_without_profiling(*args,&blk)
182
+ elapsed_time = ((Time.now - start).to_f * 1000).round(1)
183
+ result.instance_variable_set("@miniprofiler_sql_id", ::Rack::MiniProfiler.record_sql(args[0].log_inspect, elapsed_time))
184
+
185
+ result
186
+ end
187
+ end
188
+ end
189
+
190
+ if SqlPatches.class_exists?("RSolr::Connection") && RSolr::VERSION[0] != "0" # requires at least v1.0.0
191
+ class RSolr::Connection
192
+ alias_method :execute_without_profiling, :execute
193
+ def execute_with_profiling(client, request_context)
194
+ current = ::Rack::MiniProfiler.current
195
+ return execute_without_profiling(client, request_context) unless current && current.measure
196
+
197
+ start = Time.now
198
+ result = execute_without_profiling(client, request_context)
199
+ elapsed_time = ((Time.now - start).to_f * 1000).round(1)
200
+
201
+ data = "#{request_context[:method].upcase} #{request_context[:uri]}"
202
+ if request_context[:method] == :post and request_context[:data]
203
+ data << "\n#{Rack::Utils.unescape(request_context[:data])}"
204
+ end
205
+ result.instance_variable_set("@miniprofiler_sql_id", ::Rack::MiniProfiler.record_sql(data, elapsed_time))
206
+
207
+ result
208
+ end
209
+ alias_method :execute, :execute_with_profiling
210
+ end
211
+ end
212
+
172
213
 
173
214
  # Fallback for sequel
174
215
  if SqlPatches.class_exists?("Sequel::Database") && !SqlPatches.patched?
175
- module Sequel
176
- class Database
177
- alias_method :log_duration_original, :log_duration
178
- def log_duration(duration, message)
179
- ::Rack::MiniProfiler.record_sql(message, duration)
180
- log_duration_original(duration, message)
181
- end
182
- end
183
- end
216
+ module Sequel
217
+ class Database
218
+ alias_method :log_duration_original, :log_duration
219
+ def log_duration(duration, message)
220
+ ::Rack::MiniProfiler.record_sql(message, duration)
221
+ log_duration_original(duration, message)
222
+ end
223
+ end
224
+ end
184
225
  end
185
226
 
186
227
 
187
228
  ## based off https://github.com/newrelic/rpm/blob/master/lib/new_relic/agent/instrumentation/active_record.rb
188
229
  ## fallback for alls sorts of weird dbs
189
- if SqlPatches.module_exists?('ActiveRecord')
230
+ if SqlPatches.module_exists?('ActiveRecord') && !SqlPatches.patched?
190
231
  module Rack
191
- class MiniProfiler
232
+ class MiniProfiler
192
233
  module ActiveRecordInstrumentation
193
234
  def self.included(instrumented_class)
194
235
  instrumented_class.class_eval do
@@ -202,12 +243,12 @@ if SqlPatches.module_exists?('ActiveRecord')
202
243
 
203
244
  def log_with_miniprofiler(*args, &block)
204
245
  current = ::Rack::MiniProfiler.current
205
- return log_without_miniprofiler(*args, &block) unless current
246
+ return log_without_miniprofiler(*args, &block) unless current && current.measure
206
247
 
207
248
  sql, name, binds = args
208
249
  t0 = Time.now
209
250
  rval = log_without_miniprofiler(*args, &block)
210
-
251
+
211
252
  # Don't log schema queries if the option is set
212
253
  return rval if Rack::MiniProfiler.config.skip_schema_queries and name =~ /SCHEMA/
213
254
 
@@ -218,7 +259,7 @@ if SqlPatches.module_exists?('ActiveRecord')
218
259
  end
219
260
  end
220
261
 
221
- def self.insert_instrumentation
262
+ def self.insert_instrumentation
222
263
  ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
223
264
  include ::Rack::MiniProfiler::ActiveRecordInstrumentation
224
265
  end