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 +4 -4
- data/CHANGELOG.markdown +4 -0
- data/lib/scout_apm/agent/logging.rb +1 -1
- data/lib/scout_apm/agent.rb +14 -8
- data/lib/scout_apm/background_worker.rb +37 -32
- data/lib/scout_apm/capacity.rb +44 -42
- data/lib/scout_apm/environment.rb +1 -19
- data/lib/scout_apm/framework_integrations/rails_2.rb +24 -0
- data/lib/scout_apm/framework_integrations/rails_3_or_4.rb +21 -0
- data/lib/scout_apm/framework_integrations/ruby.rb +5 -0
- data/lib/scout_apm/framework_integrations/sinatra.rb +5 -0
- data/lib/scout_apm/instruments/action_controller_rails_2.rb +68 -0
- data/lib/scout_apm/instruments/action_controller_rails_3.rb +64 -0
- data/lib/scout_apm/instruments/{active_record_instruments.rb → active_record.rb} +43 -22
- data/lib/scout_apm/instruments/mongoid.rb +34 -0
- data/lib/scout_apm/instruments/moped.rb +49 -0
- data/lib/scout_apm/instruments/net_http.rb +33 -10
- data/lib/scout_apm/layaway.rb +82 -78
- data/lib/scout_apm/layaway_file.rb +59 -57
- data/lib/scout_apm/server_integrations/unicorn.rb +9 -1
- data/lib/scout_apm/store.rb +193 -184
- data/lib/scout_apm/utils/time.rb +12 -0
- data/lib/scout_apm/version.rb +1 -1
- data/lib/scout_apm.rb +11 -3
- metadata +8 -7
- data/lib/scout_apm/instruments/mongoid_instruments.rb +0 -10
- data/lib/scout_apm/instruments/moped_instruments.rb +0 -24
- data/lib/scout_apm/instruments/rails/action_controller_instruments.rb +0 -48
- data/lib/scout_apm/instruments/rails3_or_4/action_controller_instruments.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9959104d4317f9bb646443606363b67e7a33b4f9
|
4
|
+
data.tar.gz: 866026e27f92c5607fbf8bcf15f6f921bcbc7786
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05a3afbfa039ec01f844940000910689753579311313d386f8487b5e69413bce155ee11103b92fd808b93a0ba801cbf58fbfe195b9ecff7e62c012c9d5251f51
|
7
|
+
data.tar.gz: 7e6b9e8da470b075e6df0a7d4b9974939f11a1aaef323f3eff12f567561718627325ba6b64c76189557c8461f92f32ad966b8d85ce731fdea1ee3b4b934c98e7
|
data/CHANGELOG.markdown
CHANGED
@@ -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 + "[#{
|
35
|
+
prefix + "[#{Utils::Time.to_s(timestamp)} #{ScoutApm::Agent.instance.environment.hostname} (#{$$})] #{severity} : #{msg}\n"
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
data/lib/scout_apm/agent.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
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
|
-
|
3
|
-
|
4
|
-
|
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
|
-
|
7
|
-
@keep_running = true
|
8
|
-
end
|
7
|
+
attr_reader :period
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def initialize(period=DEFAULT_PERIOD)
|
10
|
+
@period = period
|
11
|
+
@keep_running = true
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
data/lib/scout_apm/capacity.rb
CHANGED
@@ -1,54 +1,56 @@
|
|
1
1
|
# Encapsulates logic for determining capacity utilization of the Ruby processes.
|
2
|
-
|
3
|
-
|
2
|
+
module ScoutApm
|
3
|
+
class Capacity
|
4
|
+
attr_reader :processing_start_time, :accumulated_time, :transaction_entry_time
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
29
|
+
end
|
45
30
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
ScoutApm::Agent.instance.logger.debug "
|
50
|
-
|
51
|
-
|
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
|
-
|
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
|
@@ -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
|
-
|
68
|
-
|
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
|
+
|