scout_apm 0.1.12 → 0.1.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c3c774cf96a6a211650f1fffabed007073ccb93
4
- data.tar.gz: bd321d8d0567c66caeb6a96ca3a65a72a48db39a
3
+ metadata.gz: 9959104d4317f9bb646443606363b67e7a33b4f9
4
+ data.tar.gz: 866026e27f92c5607fbf8bcf15f6f921bcbc7786
5
5
  SHA512:
6
- metadata.gz: e3071d8c222b7e3954aaa04a3eb25fe5ea89b780894be1763173ff5b061cf4cc565659267b3f353754dfeb16f9927db7108c22a6d60055f880d8561a74194e7e
7
- data.tar.gz: 84ab4cc77107f927537587f080b6b23950330da0075c9819f03c4038929006087256fce9449f54f39ae51a98ee91678307fe836abc66ccbf2e75c0e20c229118
6
+ metadata.gz: 05a3afbfa039ec01f844940000910689753579311313d386f8487b5e69413bce155ee11103b92fd808b93a0ba801cbf58fbfe195b9ecff7e62c012c9d5251f51
7
+ data.tar.gz: 7e6b9e8da470b075e6df0a7d4b9974939f11a1aaef323f3eff12f567561718627325ba6b64c76189557c8461f92f32ad966b8d85ce731fdea1ee3b4b934c98e7
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.1.13
2
+
3
+ * Fix support for ActiveRecord and ActionController instruments on Rails 2.3
4
+
1
5
  # 0.1.12
2
6
 
3
7
  * Fix Puma integration. Now detects both branches of preload_app! setting.
@@ -32,7 +32,7 @@ module ScoutApm
32
32
  def logger.format_message(severity, timestamp, progname, msg)
33
33
  # since STDOUT isn't exclusive like the scout_apm.log file, apply a prefix.
34
34
  prefix = @logdev.dev == STDOUT ? "[Scout] " : ''
35
- prefix + "[#{timestamp.strftime("%m/%d/%y %H:%M:%S %z")} #{ScoutApm::Agent.instance.environment.hostname} (#{$$})] #{severity} : #{msg}\n"
35
+ prefix + "[#{Utils::Time.to_s(timestamp)} #{ScoutApm::Agent.instance.environment.hostname} (#{$$})] #{severity} : #{msg}\n"
36
36
  end
37
37
  end
38
38
 
@@ -36,6 +36,7 @@ module ScoutApm
36
36
  @metric_lookup = Hash.new
37
37
 
38
38
  @capacity = ScoutApm::Capacity.new
39
+ @installed_instruments = []
39
40
  end
40
41
 
41
42
  def environment
@@ -176,19 +177,24 @@ module ScoutApm
176
177
  logger.debug "Installing instrumentation"
177
178
 
178
179
  case environment.framework
179
- when :rails
180
- require File.expand_path(File.join(File.dirname(__FILE__),'instruments/rails/action_controller_instruments.rb'))
181
- when :rails3_or_4
182
- require File.expand_path(File.join(File.dirname(__FILE__),'instruments/rails3_or_4/action_controller_instruments.rb'))
180
+ when :rails then install_instrument(ScoutApm::Instruments::ActionControllerRails2)
181
+ when :rails3_or_4 then install_instrument(ScoutApm::Instruments::ActionControllerRails3)
183
182
  end
184
- require File.expand_path(File.join(File.dirname(__FILE__),'instruments/active_record_instruments.rb'))
185
- require File.expand_path(File.join(File.dirname(__FILE__),'instruments/net_http.rb'))
186
- require File.expand_path(File.join(File.dirname(__FILE__),'instruments/moped_instruments.rb'))
187
- require File.expand_path(File.join(File.dirname(__FILE__),'instruments/mongoid_instruments.rb'))
183
+
184
+ install_instrument(ScoutApm::Instruments::ActiveRecord)
185
+ install_instrument(ScoutApm::Instruments::Moped)
186
+ install_instrument(ScoutApm::Instruments::Mongoid)
187
+ install_instrument(ScoutApm::Instruments::NetHttp)
188
188
  rescue
189
189
  logger.warn "Exception loading instruments:"
190
190
  logger.warn $!.message
191
191
  logger.warn $!.backtrace
192
192
  end
193
+
194
+ def install_instrument(instrument_klass)
195
+ instance = instrument_klass.new
196
+ @installed_instruments << instance
197
+ instance.install
198
+ end
193
199
  end
194
200
  end
@@ -1,43 +1,48 @@
1
1
  # Used to run a given task every 60 seconds.
2
- class ScoutApm::BackgroundWorker
3
- # in seconds, time between when the worker thread wakes up and runs.
4
- PERIOD = 60
2
+ module ScoutApm
3
+ class BackgroundWorker
4
+ # in seconds, time between when the worker thread wakes up and runs.
5
+ DEFAULT_PERIOD = 60
5
6
 
6
- def initialize
7
- @keep_running = true
8
- end
7
+ attr_reader :period
9
8
 
10
- def stop
11
- @keep_running = false
12
- end
9
+ def initialize(period=DEFAULT_PERIOD)
10
+ @period = period
11
+ @keep_running = true
12
+ end
13
13
 
14
- # Runs the task passed to +start+ once.
15
- def run_once
16
- @task.call if @task
17
- end
14
+ def stop
15
+ @keep_running = false
16
+ end
17
+
18
+ # Runs the task passed to +start+ once.
19
+ def run_once
20
+ @task.call if @task
21
+ end
18
22
 
19
- # Starts running the passed block every 60 seconds (starting now).
20
- def start(&block)
21
- @task = block
22
- begin
23
- ScoutApm::Agent.instance.logger.debug "Starting Background Worker, running every #{PERIOD} seconds"
24
- next_time = Time.now
25
- while @keep_running do
26
- now = Time.now
27
- while now < next_time
28
- sleep_time = next_time - now
29
- sleep(sleep_time) if sleep_time > 0
23
+ # Starts running the passed block every 60 seconds (starting now).
24
+ def start(&block)
25
+ @task = block
26
+ begin
27
+ ScoutApm::Agent.instance.logger.debug "Starting Background Worker, running every #{period} seconds"
28
+ next_time = Time.now
29
+ while @keep_running do
30
30
  now = Time.now
31
+ while now < next_time
32
+ sleep_time = next_time - now
33
+ sleep(sleep_time) if sleep_time > 0
34
+ now = Time.now
35
+ end
36
+ @task.call
37
+ while next_time <= now
38
+ next_time += period
39
+ end
31
40
  end
32
- @task.call
33
- while next_time <= now
34
- next_time += PERIOD
35
- end
41
+ rescue
42
+ ScoutApm::Agent.instance.logger.debug "Background Worker Exception!!!!!!!"
43
+ ScoutApm::Agent.instance.logger.debug $!.message
44
+ ScoutApm::Agent.instance.logger.debug $!.backtrace
36
45
  end
37
- rescue
38
- ScoutApm::Agent.instance.logger.debug "Background Worker Exception!!!!!!!"
39
- ScoutApm::Agent.instance.logger.debug $!.message
40
- ScoutApm::Agent.instance.logger.debug $!.backtrace
41
46
  end
42
47
  end
43
48
  end
@@ -1,54 +1,56 @@
1
1
  # Encapsulates logic for determining capacity utilization of the Ruby processes.
2
- class ScoutApm::Capacity
3
- attr_reader :processing_start_time, :accumulated_time, :transaction_entry_time
2
+ module ScoutApm
3
+ class Capacity
4
+ attr_reader :processing_start_time, :accumulated_time, :transaction_entry_time
4
5
 
5
- def initialize
6
- @processing_start_time = Time.now
7
- @lock ||= Mutex.new # the transaction_entry_time could be modified while processing a request or when #process is called.
8
- @accumulated_time = 0.0
9
- end
10
-
11
- # Called when a transaction is traced.
12
- def start_transaction!
13
- @lock.synchronize do
14
- @transaction_entry_time = Time.now
6
+ def initialize
7
+ @processing_start_time = Time.now
8
+ @lock ||= Mutex.new # the transaction_entry_time could be modified while processing a request or when #process is called.
9
+ @accumulated_time = 0.0
15
10
  end
16
- end
17
11
 
18
- # Called when a transaction completes to record its time used.
19
- def finish_transaction!
20
- @lock.synchronize do
21
- if transaction_entry_time
22
- @accumulated_time += (Time.now - transaction_entry_time).to_f
23
- else
24
- ScoutApm::Agent.instance.logger.warn "No transaction entry time. Not recording capacity metrics for transaction."
12
+ # Called when a transaction is traced.
13
+ def start_transaction!
14
+ @lock.synchronize do
15
+ @transaction_entry_time = Time.now
25
16
  end
26
- @transaction_entry_time = nil
27
17
  end
28
- end
29
18
 
30
- # Ran when sending metrics to server. Reports capacity usage metrics.
31
- def process
32
- process_time = Time.now
33
- ScoutApm::Agent.instance.logger.debug "Processing capacity usage for [#{@processing_start_time}] to [#{process_time}]. Time Spent: #{@accumulated_time}."
34
- @lock.synchronize do
35
- time_spent = @accumulated_time
36
- @accumulated_time = 0.0
37
- # If a transaction is still running, capture its running time up to now and
38
- # reset the +transaction_entry_time+ to now.
39
- if @transaction_entry_time
40
- time_spent += (process_time - @transaction_entry_time).to_f
41
- ScoutApm::Agent.instance.logger.debug "A transaction is running while calculating capacity. Start time: [#{transaction_entry_time}]. Will update the entry time to [#{process_time}]."
42
- @transaction_entry_time = process_time # prevent from over-counting capacity usage. update the transaction start time to now.
19
+ # Called when a transaction completes to record its time used.
20
+ def finish_transaction!
21
+ @lock.synchronize do
22
+ if transaction_entry_time
23
+ @accumulated_time += (Time.now - transaction_entry_time).to_f
24
+ else
25
+ ScoutApm::Agent.instance.logger.warn "No transaction entry time. Not recording capacity metrics for transaction."
26
+ end
27
+ @transaction_entry_time = nil
43
28
  end
44
- time_spent = 0.0 if time_spent < 0.0
29
+ end
45
30
 
46
- window = (process_time - processing_start_time).to_f # time period we are evaulating capacity usage.
47
- window = 1.0 if window <= 0.0 # prevent divide-by-zero if clock adjusted.
48
- capacity = time_spent / window
49
- ScoutApm::Agent.instance.logger.debug "Instance/Capacity: #{capacity}"
50
- ScoutApm::Agent.instance.store.track!("Instance/Capacity",capacity,:scope => nil)
51
- @processing_start_time = process_time
31
+ # Ran when sending metrics to server. Reports capacity usage metrics.
32
+ def process
33
+ process_time = Time.now
34
+ ScoutApm::Agent.instance.logger.debug "Processing capacity usage for [#{@processing_start_time}] to [#{process_time}]. Time Spent: #{@accumulated_time}."
35
+ @lock.synchronize do
36
+ time_spent = @accumulated_time
37
+ @accumulated_time = 0.0
38
+ # If a transaction is still running, capture its running time up to now and
39
+ # reset the +transaction_entry_time+ to now.
40
+ if @transaction_entry_time
41
+ time_spent += (process_time - @transaction_entry_time).to_f
42
+ ScoutApm::Agent.instance.logger.debug "A transaction is running while calculating capacity. Start time: [#{transaction_entry_time}]. Will update the entry time to [#{process_time}]."
43
+ @transaction_entry_time = process_time # prevent from over-counting capacity usage. update the transaction start time to now.
44
+ end
45
+ time_spent = 0.0 if time_spent < 0.0
46
+
47
+ window = (process_time - processing_start_time).to_f # time period we are evaulating capacity usage.
48
+ window = 1.0 if window <= 0.0 # prevent divide-by-zero if clock adjusted.
49
+ capacity = time_spent / window
50
+ ScoutApm::Agent.instance.logger.debug "Instance/Capacity: #{capacity}"
51
+ ScoutApm::Agent.instance.store.track!("Instance/Capacity",capacity,:scope => nil)
52
+ @processing_start_time = process_time
53
+ end
52
54
  end
53
55
  end
54
56
  end
@@ -41,25 +41,7 @@ module ScoutApm
41
41
  end
42
42
 
43
43
  def database_engine
44
- default = :mysql
45
-
46
- if defined?(ActiveRecord::Base)
47
- config = ActiveRecord::Base.connection_config
48
- if config && config[:adapter]
49
- case config[:adapter]
50
- when "postgres" then :postgres
51
- when "postgresql" then :postgres
52
- when "sqlite3" then :sqlite
53
- when "mysql" then :mysql
54
- else default
55
- end
56
- else
57
- default
58
- end
59
- else
60
- # TODO: Figure out how to detect outside of Rails context. (sequel, ROM, etc)
61
- default
62
- end
44
+ framework_integration.database_engine
63
45
  end
64
46
 
65
47
  def processors
@@ -31,6 +31,30 @@ module ScoutApm
31
31
  def env
32
32
  RAILS_ENV.dup
33
33
  end
34
+
35
+ # Attempts to determine the database engine being used
36
+ def database_engine
37
+ default = :mysql
38
+
39
+ if defined?(ActiveRecord::Base)
40
+ config = ActiveRecord::Base.configurations[env]
41
+ if config && config["adapter"]
42
+ case config["adapter"].to_s
43
+ when "postgres" then :postgres
44
+ when "postgresql" then :postgres
45
+ when "sqlite3" then :sqlite
46
+ when "mysql" then :mysql
47
+ else default
48
+ end
49
+ else
50
+ default
51
+ end
52
+ else
53
+ default
54
+ end
55
+ rescue
56
+ default
57
+ end
34
58
  end
35
59
  end
36
60
  end
@@ -32,6 +32,27 @@ module ScoutApm
32
32
  ::Rails.env
33
33
  end
34
34
 
35
+ def database_engine
36
+ default = :mysql
37
+
38
+ if defined?(ActiveRecord::Base)
39
+ config = ActiveRecord::Base.connection_config
40
+ if config && config[:adapter]
41
+ case config[:adapter]
42
+ when "postgres" then :postgres
43
+ when "postgresql" then :postgres
44
+ when "sqlite3" then :sqlite
45
+ when "mysql" then :mysql
46
+ else default
47
+ end
48
+ else
49
+ default
50
+ end
51
+ else
52
+ # TODO: Figure out how to detect outside of Rails context. (sequel, ROM, etc)
53
+ default
54
+ end
55
+ end
35
56
  end
36
57
  end
37
58
  end
@@ -25,6 +25,11 @@ module ScoutApm
25
25
  def env
26
26
  ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
27
27
  end
28
+
29
+ # TODO: Figure out how to accomodate odd environments
30
+ def database_engine
31
+ :mysql
32
+ end
28
33
  end
29
34
  end
30
35
  end
@@ -26,6 +26,11 @@ module ScoutApm
26
26
  def env
27
27
  ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
28
28
  end
29
+
30
+ # TODO: Figure out how to detect this smarter
31
+ def database_engine
32
+ :mysql
33
+ end
29
34
  end
30
35
  end
31
36
  end
@@ -0,0 +1,68 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ class ActionControllerRails2
4
+ attr_reader :logger
5
+
6
+ def initalize(logger=ScoutApm::Agent.instance.logger)
7
+ @logger = logger
8
+ @installed = false
9
+ end
10
+
11
+ def installed?
12
+ @installed
13
+ end
14
+
15
+ def install
16
+ @installed = true
17
+
18
+ if defined?(::ActionController) && defined?(::ActionController::Base)
19
+ ::ActionController::Base.class_eval do
20
+ include ScoutApm::Tracer
21
+ include ::ScoutApm::Instruments::ActionControllerRails2Instruments
22
+
23
+ def rescue_action_with_scout(exception)
24
+ ScoutApm::Agent.instance.store.track!("Errors/Request",1, :scope => nil)
25
+ ScoutApm::Agent.instance.store.ignore_transaction!
26
+ rescue_action_without_scout exception
27
+ end
28
+
29
+ alias_method :rescue_action_without_scout, :rescue_action
30
+ alias_method :rescue_action, :rescue_action_with_scout
31
+ protected :rescue_action
32
+ end
33
+
34
+ ScoutApm::Agent.instance.logger.debug "Instrumenting ActionView::Template"
35
+ ::ActionView::Template.class_eval do
36
+ include ::ScoutApm::Tracer
37
+ instrument_method :render, :metric_name => 'View/#{path[%r{^(/.*/)?(.*)$},2]}/Rendering', :scope => true
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+
44
+ module ActionControllerRails2Instruments
45
+ def self.included(instrumented_class)
46
+ ScoutApm::Agent.instance.logger.debug "Instrumenting #{instrumented_class.inspect}"
47
+ instrumented_class.class_eval do
48
+ unless instrumented_class.method_defined?(:perform_action_without_scout_instruments)
49
+ alias_method :perform_action_without_scout_instruments, :perform_action
50
+ alias_method :perform_action, :perform_action_with_scout_instruments
51
+ private :perform_action
52
+ end
53
+ end
54
+ end
55
+
56
+ # In addition to instrumenting actions, this also sets the scope to the controller action name. The scope is later
57
+ # applied to metrics recorded during this transaction. This lets us associate ActiveRecord calls with
58
+ # specific controller actions.
59
+ def perform_action_with_scout_instruments(*args, &block)
60
+ scout_controller_action = "Controller/#{controller_path}/#{action_name}"
61
+ self.class.scout_apm_trace(scout_controller_action, :uri => request.request_uri, :ip => request.remote_ip) do
62
+ perform_action_without_scout_instruments(*args, &block)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,64 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ class ActionControllerRails3
4
+ attr_reader :logger
5
+
6
+ def initalize(logger=ScoutApm::Agent.instance.logger)
7
+ @logger = logger
8
+ @installed = false
9
+ end
10
+
11
+ def installed?
12
+ @installed
13
+ end
14
+
15
+ def install
16
+ @installed = true
17
+
18
+ # ActionController::Base is a subclass of ActionController::Metal, so this instruments both
19
+ # standard Rails requests + Metal.
20
+ if defined?(::ActionController) && defined?(::ActionController::Metal)
21
+ ScoutApm::Agent.instance.logger.debug "Instrumenting ActionController::Metal"
22
+ ::ActionController::Metal.class_eval do
23
+ include ScoutApm::Tracer
24
+ include ScoutApm::Instruments::ActionControllerRails3Instruments
25
+ end
26
+ end
27
+
28
+ if defined?(::ActionView) && defined?(::ActionView::PartialRenderer)
29
+ ScoutApm::Agent.instance.logger.debug "Instrumenting ActionView::PartialRenderer"
30
+ ActionView::PartialRenderer.class_eval do
31
+ include ScoutApm::Tracer
32
+ instrument_method :render_partial, :metric_name => 'View/#{@template.virtual_path}/Rendering', :scope => true
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+
39
+ module ActionControllerRails3Instruments
40
+ # Instruments the action and tracks errors.
41
+ def process_action(*args)
42
+ scout_controller_action = "Controller/#{controller_path}/#{action_name}"
43
+
44
+ self.class.scout_apm_trace(scout_controller_action, :uri => request.fullpath, :ip => request.remote_ip) do
45
+ begin
46
+ super
47
+ rescue Exception
48
+ ScoutApm::Agent.instance.store.track!("Errors/Request",1, :scope => nil)
49
+ raise
50
+ ensure
51
+ Thread::current[:scout_apm_scope_name] = nil
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+
60
+ # Rails 3/4
61
+ module ScoutApm
62
+ module Instruments
63
+ end
64
+ end
@@ -2,6 +2,47 @@ require 'scout_apm/utils/sql_sanitizer'
2
2
 
3
3
  module ScoutApm
4
4
  module Instruments
5
+ class ActiveRecord
6
+ attr_reader :logger
7
+
8
+ def initalize(logger=ScoutApm::Agent.instance.logger)
9
+ @logger = logger
10
+ @installed = false
11
+ end
12
+
13
+ def installed?
14
+ @installed
15
+ end
16
+
17
+ def install
18
+ @installed = true
19
+
20
+ if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3 && ::Rails.respond_to?(:configuration)
21
+ Rails.configuration.after_initialize do
22
+ ScoutApm::Agent.instance.logger.debug "Adding ActiveRecord instrumentation to a Rails 3 app"
23
+ add_instruments
24
+ end
25
+ else
26
+ add_instruments
27
+ end
28
+ end
29
+
30
+ def add_instruments
31
+ if defined?(::ActiveRecord) && defined?(::ActiveRecord::Base)
32
+ ::ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
33
+ include ::ScoutApm::Instruments::ActiveRecordInstruments
34
+ include ::ScoutApm::Tracer
35
+ end
36
+
37
+ ::ActiveRecord::Base.class_eval do
38
+ include ::ScoutApm::Tracer
39
+ end
40
+ end
41
+ rescue
42
+ ScoutApm::Agent.instance.logger.warn "ActiveRecord instrumentation exception: #{$!.message}"
43
+ end
44
+ end
45
+
5
46
  # Contains ActiveRecord instrument, aliasing +ActiveRecord::ConnectionAdapters::AbstractAdapter#log+ calls
6
47
  # to trace calls to the database.
7
48
  module ActiveRecordInstruments
@@ -47,28 +88,8 @@ module ScoutApm
47
88
  metric
48
89
  end
49
90
  end # module ActiveRecordInstruments
50
- end # module Instruments
51
- end
52
-
53
- def add_instruments
54
- if defined?(ActiveRecord) && defined?(ActiveRecord::Base)
55
- ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
56
- include ::ScoutApm::Instruments::ActiveRecordInstruments
57
- include ::ScoutApm::Tracer
58
- end
59
- ActiveRecord::Base.class_eval do
60
- include ::ScoutApm::Tracer
61
- end
62
91
  end
63
- rescue
64
- ScoutApm::Agent.instance.logger.warn "ActiveRecord instrumentation exception: #{$!.message}"
65
92
  end
66
93
 
67
- if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3 && ::Rails.respond_to?(:configuration)
68
- Rails.configuration.after_initialize do
69
- ScoutApm::Agent.instance.logger.debug "Adding ActiveRecord instrumentation to a Rails 3 app"
70
- add_instruments
71
- end
72
- else
73
- add_instruments
74
- end
94
+
95
+
@@ -0,0 +1,34 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ class Mongoid
4
+ attr_reader :logger
5
+
6
+ def initalize(logger=ScoutApm::Agent.instance.logger)
7
+ @logger = logger
8
+ @installed = false
9
+ end
10
+
11
+ def installed?
12
+ @installed
13
+ end
14
+
15
+ def install
16
+ @installed = true
17
+
18
+ # Mongoid versions that use Moped should instrument Moped.
19
+ if defined?(::Mongoid) and !defined?(::Moped)
20
+ ScoutApm::Agent.instance.logger.debug "Instrumenting Mongoid"
21
+
22
+ ::Mongoid::Collection.class_eval do
23
+ include ScoutApm::Tracer
24
+ (::Mongoid::Collections::Operations::ALL - [:<<, :[]]).each do |method|
25
+ instrument_method method, :metric_name => "MongoDB/\#{@klass}/#{method}"
26
+ end
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,49 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ class Moped
4
+ attr_reader :logger
5
+
6
+ def initalize(logger=ScoutApm::Agent.instance.logger)
7
+ @logger = logger
8
+ @installed = false
9
+ end
10
+
11
+ def installed?
12
+ @installed
13
+ end
14
+
15
+ def install
16
+ @installed = true
17
+
18
+ if defined?(::Moped)
19
+ ScoutApm::Agent.instance.logger.debug "Instrumenting Moped"
20
+ ::Moped::Node.class_eval do
21
+ include ScoutApm::Tracer
22
+
23
+ def process_with_scout_instruments(operation, &callback)
24
+ if operation.respond_to?(:collection)
25
+ collection = operation.collection
26
+ self.class.instrument("MongoDB/Process/#{collection}/#{operation.class.to_s.split('::').last}",
27
+ :desc => scout_sanitize_log(operation.log_inspect)) do
28
+ process_without_scout_instruments(operation, &callback)
29
+ end
30
+ end
31
+ end
32
+ alias_method :process_without_scout_instruments, :process
33
+ alias_method :process, :process_with_scout_instruments
34
+
35
+ # replaces values w/ ?
36
+ def scout_sanitize_log(log)
37
+ return nil if log.length > 1000 # safeguard - don't sanitize large SQL statements
38
+ log.gsub(/(=>")((?:[^"]|"")*)"/) do
39
+ $1 + '?' + '"'
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+