scout_apm 2.3.5 → 2.4.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +0 -23
  3. data/lib/scout_apm.rb +21 -10
  4. data/lib/scout_apm/agent.rb +98 -336
  5. data/lib/scout_apm/agent/exit_handler.rb +64 -0
  6. data/lib/scout_apm/agent/preconditions.rb +69 -0
  7. data/lib/scout_apm/agent_context.rb +226 -0
  8. data/lib/scout_apm/app_server_load.rb +20 -18
  9. data/lib/scout_apm/background_job_integrations/resque.rb +7 -8
  10. data/lib/scout_apm/background_job_integrations/sidekiq.rb +2 -8
  11. data/lib/scout_apm/background_recorder.rb +8 -3
  12. data/lib/scout_apm/background_worker.rb +14 -7
  13. data/lib/scout_apm/config.rb +35 -29
  14. data/lib/scout_apm/context.rb +11 -4
  15. data/lib/scout_apm/db_query_metric_set.rb +17 -5
  16. data/lib/scout_apm/debug.rb +1 -1
  17. data/lib/scout_apm/environment.rb +10 -14
  18. data/lib/scout_apm/framework_integrations/sinatra.rb +1 -1
  19. data/lib/scout_apm/git_revision.rb +13 -8
  20. data/lib/scout_apm/histogram.rb +1 -1
  21. data/lib/scout_apm/instant/middleware.rb +7 -7
  22. data/lib/scout_apm/instant_reporting.rb +7 -7
  23. data/lib/scout_apm/instrument_manager.rb +87 -0
  24. data/lib/scout_apm/instruments/action_controller_rails_2.rb +12 -7
  25. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +16 -11
  26. data/lib/scout_apm/instruments/action_view.rb +11 -7
  27. data/lib/scout_apm/instruments/active_record.rb +28 -51
  28. data/lib/scout_apm/instruments/elasticsearch.rb +10 -6
  29. data/lib/scout_apm/instruments/grape.rb +12 -8
  30. data/lib/scout_apm/instruments/http_client.rb +11 -10
  31. data/lib/scout_apm/instruments/influxdb.rb +10 -6
  32. data/lib/scout_apm/instruments/middleware_detailed.rb +11 -5
  33. data/lib/scout_apm/instruments/middleware_summary.rb +11 -5
  34. data/lib/scout_apm/instruments/mongoid.rb +10 -5
  35. data/lib/scout_apm/instruments/moped.rb +11 -6
  36. data/lib/scout_apm/instruments/net_http.rb +11 -9
  37. data/lib/scout_apm/instruments/percentile_sampler.rb +8 -6
  38. data/lib/scout_apm/instruments/process/process_cpu.rb +8 -4
  39. data/lib/scout_apm/instruments/process/process_memory.rb +15 -10
  40. data/lib/scout_apm/instruments/rails_router.rb +12 -6
  41. data/lib/scout_apm/instruments/redis.rb +10 -6
  42. data/lib/scout_apm/instruments/samplers.rb +11 -0
  43. data/lib/scout_apm/instruments/sinatra.rb +5 -4
  44. data/lib/scout_apm/layaway.rb +26 -39
  45. data/lib/scout_apm/layaway_file.rb +8 -3
  46. data/lib/scout_apm/layer.rb +1 -1
  47. data/lib/scout_apm/layer_converters/converter_base.rb +4 -2
  48. data/lib/scout_apm/layer_converters/database_converter.rb +1 -1
  49. data/lib/scout_apm/layer_converters/histograms.rb +2 -2
  50. data/lib/scout_apm/layer_converters/slow_job_converter.rb +4 -3
  51. data/lib/scout_apm/layer_converters/slow_request_converter.rb +5 -4
  52. data/lib/scout_apm/logger.rb +143 -0
  53. data/lib/scout_apm/middleware.rb +7 -9
  54. data/lib/scout_apm/periodic_work.rb +28 -0
  55. data/lib/scout_apm/remote/server.rb +0 -2
  56. data/lib/scout_apm/reporter.rb +14 -8
  57. data/lib/scout_apm/reporting.rb +135 -0
  58. data/lib/scout_apm/request_manager.rb +4 -7
  59. data/lib/scout_apm/serializers/payload_serializer.rb +1 -1
  60. data/lib/scout_apm/slow_job_policy.rb +6 -2
  61. data/lib/scout_apm/slow_job_record.rb +5 -5
  62. data/lib/scout_apm/slow_request_policy.rb +6 -2
  63. data/lib/scout_apm/slow_transaction.rb +5 -5
  64. data/lib/scout_apm/store.rb +22 -16
  65. data/lib/scout_apm/synchronous_recorder.rb +7 -3
  66. data/lib/scout_apm/tasks/doctor.rb +75 -0
  67. data/lib/scout_apm/tasks/support.rb +22 -0
  68. data/lib/scout_apm/tracer.rb +5 -5
  69. data/lib/scout_apm/tracked_request.rb +23 -35
  70. data/lib/scout_apm/utils/backtrace_parser.rb +1 -1
  71. data/lib/scout_apm/utils/installed_gems.rb +7 -3
  72. data/lib/scout_apm/utils/klass_helper.rb +8 -2
  73. data/lib/scout_apm/utils/scm.rb +1 -1
  74. data/lib/scout_apm/utils/sql_sanitizer.rb +4 -6
  75. data/lib/scout_apm/version.rb +1 -1
  76. data/lib/tasks/doctor.rake +11 -0
  77. data/test/test_helper.rb +15 -2
  78. data/test/unit/agent_test.rb +1 -54
  79. data/test/unit/config_test.rb +9 -5
  80. data/test/unit/context_test.rb +4 -4
  81. data/test/unit/db_query_metric_set_test.rb +11 -4
  82. data/test/unit/fake_store_test.rb +1 -1
  83. data/test/unit/git_revision_test.rb +3 -3
  84. data/test/unit/instruments/net_http_test.rb +2 -1
  85. data/test/unit/instruments/percentile_sampler_test.rb +5 -9
  86. data/test/unit/layaway_test.rb +10 -5
  87. data/test/unit/layer_converters/metric_converter_test.rb +2 -2
  88. data/test/unit/slow_request_policy_test.rb +7 -3
  89. data/test/unit/sql_sanitizer_test.rb +0 -6
  90. data/test/unit/store_test.rb +11 -8
  91. metadata +15 -7
  92. data/lib/scout_apm/agent/logging.rb +0 -74
  93. data/lib/scout_apm/agent/reporting.rb +0 -129
  94. data/lib/scout_apm/utils/null_logger.rb +0 -13
@@ -171,7 +171,7 @@ module ScoutApm
171
171
  bins.slice!(minDeltaIndex - 1, 2)
172
172
  bins.insert(minDeltaIndex - 1, mergedBin)
173
173
  rescue => e
174
- ScoutApm::Agent.instance.logger.info("Error in NumericHistogram#trim_one. #{e.message}, #{e.backtrace}, #{self.inspect}")
174
+ ScoutApm::Agent.instance.context.logger.info("Error in NumericHistogram#trim_one. #{e.message}, #{e.backtrace}, #{self.inspect}")
175
175
  raise
176
176
  end
177
177
  end
@@ -55,7 +55,7 @@ module ScoutApm
55
55
  DevTraceResponseManipulator.new(env, rack_response).call
56
56
  rescue Exception => e
57
57
  # If anything went wrong at all, just bail out and return the unmodified response.
58
- ScoutApm::Agent.instance.logger.debug("DevTrace: Raised an exception: #{e.message}, #{e.backtrace}")
58
+ ScoutApm::Agent.instance.context.logger.debug("DevTrace: Raised an exception: #{e.message}, #{e.backtrace}")
59
59
  rack_response
60
60
  end
61
61
  end
@@ -79,7 +79,7 @@ module ScoutApm
79
79
  return rack_response unless preconditions_met?
80
80
 
81
81
  if ajax_request?
82
- ScoutApm::Agent.instance.logger.debug("DevTrace: in middleware, dev_trace is active, and response has a body. This is either AJAX or JSON. Path=#{path}; ContentType=#{content_type}")
82
+ ScoutApm::Agent.instance.context.logger.debug("DevTrace: in middleware, dev_trace is active, and response has a body. This is either AJAX or JSON. Path=#{path}; ContentType=#{content_type}")
83
83
  adjust_ajax_header
84
84
  else
85
85
  adjust_html_response
@@ -116,7 +116,7 @@ module ScoutApm
116
116
  end
117
117
 
118
118
  def dev_trace_disabled?
119
- ! ScoutApm::Agent.instance.config.value('dev_trace')
119
+ ! ScoutApm::Agent.instance.context.config.value('dev_trace')
120
120
  end
121
121
 
122
122
  ########################
@@ -212,7 +212,7 @@ module ScoutApm
212
212
  ##############################
213
213
 
214
214
  def logger
215
- ScoutApm::Agent.instance.logger
215
+ ScoutApm::Agent.instance.context.logger
216
216
  end
217
217
 
218
218
  def tracked_request
@@ -220,14 +220,14 @@ module ScoutApm
220
220
  end
221
221
 
222
222
  def apm_host
223
- ScoutApm::Agent.instance.config.value("direct_host")
223
+ ScoutApm::Agent.instance.context.config.value("direct_host")
224
224
  end
225
225
 
226
226
  def trace
227
227
  @trace ||=
228
228
  begin
229
229
  layer_finder = LayerConverters::FindLayerByType.new(tracked_request)
230
- converter = LayerConverters::SlowRequestConverter.new(tracked_request, layer_finder, ScoutApm::FakeStore.new)
230
+ converter = LayerConverters::SlowRequestConverter.new(ScoutApm::Agent.instance.context, tracked_request, layer_finder, ScoutApm::FakeStore.new)
231
231
  converter.call
232
232
  end
233
233
  end
@@ -236,7 +236,7 @@ module ScoutApm
236
236
  @payload ||=
237
237
  begin
238
238
  metadata = {
239
- :app_root => ScoutApm::Environment.instance.root.to_s,
239
+ :app_root => ScoutApm::Agent.instance.context.environment.root.to_s,
240
240
  :unique_id => env['action_dispatch.request_id'], # note, this is a different unique_id than what "normal" payloads use
241
241
  :agent_version => ScoutApm::VERSION,
242
242
  :platform => "ruby",
@@ -15,12 +15,12 @@ module ScoutApm
15
15
  # Serialize that trace. We reuse the PayloadSerializer, but only provide the metadata and traces.
16
16
  # In this case, the traces array will always have just one element.
17
17
  metadata = {
18
- :app_root => ScoutApm::Environment.instance.root.to_s,
19
- :unique_id => ScoutApm::Utils::UniqueId.simple,
20
- :agent_version => ScoutApm::VERSION,
21
- :agent_time => Time.now.iso8601,
22
- :agent_pid => Process.pid,
23
- :platform => "ruby",
18
+ :app_root => ScoutApm::Agent.instance.context.environment.root.to_s,
19
+ :unique_id => ScoutApm::Utils::UniqueId.simple,
20
+ :agent_version => ScoutApm::VERSION,
21
+ :agent_time => Time.now.iso8601,
22
+ :agent_pid => Process.pid,
23
+ :platform => "ruby",
24
24
  }
25
25
 
26
26
  metrics = []
@@ -31,7 +31,7 @@ module ScoutApm
31
31
  payload = ScoutApm::Serializers::PayloadSerializer.serialize(metadata, metrics, traces, jobs, slow_jobs)
32
32
 
33
33
  # Hand it off to the reporter for POST to our servers
34
- reporter = Reporter.new(:instant_trace, Agent.instance.config, Agent.instance.logger, @instant_key)
34
+ reporter = Reporter.new(context, :instant_trace, @instant_key)
35
35
  reporter.report(payload, {'Content-Type' => 'application/json'} )
36
36
  end
37
37
  end
@@ -0,0 +1,87 @@
1
+ module ScoutApm
2
+ class InstrumentManager
3
+ attr_reader :context
4
+
5
+ attr_reader :installed_instruments
6
+
7
+ def initialize(context)
8
+ @context = context
9
+ @installed_instruments = []
10
+ end
11
+
12
+ # Loads the instrumention logic.
13
+ def install!
14
+ case framework
15
+ when :rails then
16
+ install_instrument(ScoutApm::Instruments::ActionControllerRails2)
17
+ when :rails3_or_4 then
18
+ install_instrument(ScoutApm::Instruments::ActionControllerRails3Rails4)
19
+ install_instrument(ScoutApm::Instruments::RailsRouter)
20
+
21
+ if config.value("detailed_middleware")
22
+ install_instrument(ScoutApm::Instruments::MiddlewareDetailed)
23
+ else
24
+ install_instrument(ScoutApm::Instruments::MiddlewareSummary)
25
+ end
26
+ end
27
+
28
+ install_instrument(ScoutApm::Instruments::ActionView)
29
+ install_instrument(ScoutApm::Instruments::ActiveRecord)
30
+ install_instrument(ScoutApm::Instruments::Moped)
31
+ install_instrument(ScoutApm::Instruments::Mongoid)
32
+ install_instrument(ScoutApm::Instruments::NetHttp)
33
+ install_instrument(ScoutApm::Instruments::HttpClient)
34
+ install_instrument(ScoutApm::Instruments::Redis)
35
+ install_instrument(ScoutApm::Instruments::InfluxDB)
36
+ install_instrument(ScoutApm::Instruments::Elasticsearch)
37
+ install_instrument(ScoutApm::Instruments::Grape)
38
+ rescue
39
+ logger.warn "Exception loading instruments:"
40
+ logger.warn $!.message
41
+ logger.warn $!.backtrace
42
+ end
43
+
44
+ private
45
+
46
+ def install_instrument(instrument_klass)
47
+ return if already_installed?(instrument_klass)
48
+
49
+ if skip_instrument?(instrument_klass)
50
+ logger.info "Skipping Disabled Instrument: #{instrument_short_name} - To re-enable, change `disabled_instruments` key in scout_apm.yml"
51
+ return
52
+ end
53
+
54
+ instance = instrument_klass.new(context)
55
+ @installed_instruments << instance
56
+ instance.install
57
+ end
58
+
59
+ # Allows users to skip individual instruments via the config file
60
+ def skip_instrument?(instrument_klass)
61
+ instrument_short_name = instrument_klass.name.split("::").last
62
+ (config.value("disabled_instruments") || []).include?(instrument_short_name)
63
+ end
64
+
65
+ def already_installed?(instrument_klass)
66
+ @installed_instruments.any? do |already_installed_instrument|
67
+ instrument_klass === already_installed_instrument
68
+ end
69
+ end
70
+
71
+ ###################
72
+ # Lookup Helpers #
73
+ ###################
74
+
75
+ def logger
76
+ context.logger
77
+ end
78
+
79
+ def config
80
+ context.config
81
+ end
82
+
83
+ def framework
84
+ context.environment.framework
85
+ end
86
+ end
87
+ end
@@ -1,27 +1,31 @@
1
1
  module ScoutApm
2
2
  module Instruments
3
3
  class ActionControllerRails2
4
- attr_reader :logger
4
+ attr_reader :context
5
5
 
6
- def initalize(logger=ScoutApm::Agent.instance.logger)
7
- @logger = logger
6
+ def initialize(context)
7
+ @context = context
8
8
  @installed = false
9
9
  end
10
10
 
11
+ def logger
12
+ context.logger
13
+ end
14
+
11
15
  def installed?
12
16
  @installed
13
17
  end
14
18
 
15
19
  def install
16
- @installed = true
17
-
18
20
  if defined?(::ActionController) && defined?(::ActionController::Base)
21
+ @installed = true
22
+
19
23
  ::ActionController::Base.class_eval do
20
24
  include ScoutApm::Tracer
21
25
  include ::ScoutApm::Instruments::ActionControllerRails2Instruments
22
26
  end
23
27
 
24
- ScoutApm::Agent.instance.logger.info "Instrumenting ActionView::Template"
28
+ logger.info "Instrumenting ActionView::Template"
25
29
  ::ActionView::Template.class_eval do
26
30
  include ::ScoutApm::Tracer
27
31
  instrument_method :render, :type => "View", :name => '#{path[%r{^(/.*/)?(.*)$},2]}/Rendering', :scope => true
@@ -33,7 +37,8 @@ module ScoutApm
33
37
 
34
38
  module ActionControllerRails2Instruments
35
39
  def self.included(instrumented_class)
36
- ScoutApm::Agent.instance.logger.info "Instrumenting #{instrumented_class.inspect}"
40
+ # XXX: Don't lookup context by global
41
+ ScoutApm::Agent.instance.context.logger.info "Instrumenting #{instrumented_class.inspect}"
37
42
  instrumented_class.class_eval do
38
43
  unless instrumented_class.method_defined?(:perform_action_without_scout_instruments)
39
44
  alias_method :perform_action_without_scout_instruments, :perform_action
@@ -2,27 +2,31 @@ module ScoutApm
2
2
  module Instruments
3
3
  # instrumentation for Rails 3 and Rails 4 is the same.
4
4
  class ActionControllerRails3Rails4
5
- attr_reader :logger
5
+ attr_reader :context
6
6
 
7
- def initalize(logger=ScoutApm::Agent.instance.logger)
8
- @logger = logger
7
+ def initialize(context)
8
+ @context = context
9
9
  @installed = false
10
10
  end
11
11
 
12
+ def logger
13
+ context.logger
14
+ end
15
+
12
16
  def installed?
13
17
  @installed
14
18
  end
15
19
 
16
20
  def install
17
- @installed = true
18
-
19
21
  # We previously instrumented ActionController::Metal, which missed
20
22
  # before and after filter timing. Instrumenting Base includes those
21
23
  # filters, at the expense of missing out on controllers that don't use
22
24
  # the full Rails stack.
23
25
  if defined?(::ActionController)
26
+ @installed = true
27
+
24
28
  if defined?(::ActionController::Base)
25
- ScoutApm::Agent.instance.logger.info "Instrumenting ActionController::Base"
29
+ logger.info "Instrumenting ActionController::Base"
26
30
  ::ActionController::Base.class_eval do
27
31
  # include ScoutApm::Tracer
28
32
  include ScoutApm::Instruments::ActionControllerBaseInstruments
@@ -30,14 +34,14 @@ module ScoutApm
30
34
  end
31
35
 
32
36
  if defined?(::ActionController::Metal)
33
- ScoutApm::Agent.instance.logger.info "Instrumenting ActionController::Metal"
37
+ logger.info "Instrumenting ActionController::Metal"
34
38
  ::ActionController::Metal.class_eval do
35
39
  include ScoutApm::Instruments::ActionControllerMetalInstruments
36
40
  end
37
41
  end
38
42
 
39
43
  if defined?(::ActionController::API)
40
- ScoutApm::Agent.instance.logger.info "Instrumenting ActionController::Api"
44
+ logger.info "Instrumenting ActionController::Api"
41
45
  ::ActionController::API.class_eval do
42
46
  include ScoutApm::Instruments::ActionControllerAPIInstruments
43
47
  end
@@ -59,7 +63,7 @@ module ScoutApm
59
63
 
60
64
  # Check if this this request is to be reported instantly
61
65
  if instant_key = request.cookies['scoutapminstant']
62
- Agent.instance.logger.info "Instant trace request with key=#{instant_key} for path=#{path}"
66
+ ScoutApm::Agent.instance.context.logger.info "Instant trace request with key=#{instant_key} for path=#{path}"
63
67
  req.instant_key = instant_key
64
68
  end
65
69
 
@@ -91,8 +95,9 @@ module ScoutApm
91
95
  end
92
96
 
93
97
  # Given an +ActionDispatch::Request+, formats the uri based on config settings.
94
- def self.scout_transaction_uri(request)
95
- case ScoutApm::Agent.instance.config.value("uri_reporting")
98
+ # XXX: Don't lookup context like this - find a way to pass it through
99
+ def self.scout_transaction_uri(request, config=ScoutApm::Agent.instance.context.config)
100
+ case config.value("uri_reporting")
96
101
  when 'path'
97
102
  request.path # strips off the query string for more security
98
103
  else # default handles filtered params
@@ -2,22 +2,26 @@ module ScoutApm
2
2
  module Instruments
3
3
  # instrumentation for Rails 3 and Rails 4 is the same.
4
4
  class ActionView
5
- attr_reader :logger
5
+ attr_reader :context
6
6
 
7
- def initalize(logger=ScoutApm::Agent.instance.logger)
8
- @logger = logger
7
+ def initialize(context)
8
+ @context = context
9
9
  @installed = false
10
10
  end
11
11
 
12
+ def logger
13
+ context.logger
14
+ end
15
+
12
16
  def installed?
13
17
  @installed
14
18
  end
15
19
 
16
20
  def install
17
- @installed = true
18
-
19
21
  if defined?(::ActionView) && defined?(::ActionView::PartialRenderer)
20
- ScoutApm::Agent.instance.logger.info "Instrumenting ActionView::PartialRenderer"
22
+ @installed = true
23
+
24
+ logger.info "Instrumenting ActionView::PartialRenderer"
21
25
  ::ActionView::PartialRenderer.class_eval do
22
26
  include ScoutApm::Tracer
23
27
 
@@ -32,7 +36,7 @@ module ScoutApm
32
36
  :scope => true
33
37
  end
34
38
 
35
- ScoutApm::Agent.instance.logger.info "Instrumenting ActionView::TemplateRenderer"
39
+ logger.info "Instrumenting ActionView::TemplateRenderer"
36
40
  ::ActionView::TemplateRenderer.class_eval do
37
41
  include ScoutApm::Tracer
38
42
  instrument_method :render_template,
@@ -1,55 +1,25 @@
1
1
  require 'scout_apm/utils/sql_sanitizer'
2
2
 
3
3
  module ScoutApm
4
- class SqlList
5
- attr_reader :sqls
6
-
7
- def initialize(sql=nil)
8
- @sqls = []
9
-
10
- if !sql.nil?
11
- push(sql)
12
- end
13
- end
14
-
15
- def <<(sql)
16
- push(sql)
17
- end
18
-
19
- def push(sql)
20
- if !(Utils::SqlSanitizer === sql)
21
- sql = Utils::SqlSanitizer.new(sql)
22
- end
23
- @sqls << sql
24
- end
25
-
26
- # All of this one, then all of the other.
27
- def merge(other)
28
- @sqls += other.sqls
29
- end
30
-
31
- def to_s
32
- @sqls.map{|s| s.to_s }.join(";\n")
33
- end
34
- end
35
-
36
4
  module Instruments
37
5
  class ActiveRecord
38
- attr_reader :logger
6
+ attr_reader :context
39
7
 
40
- def initalize(logger=ScoutApm::Agent.instance.logger)
41
- @logger = logger
8
+ def initialize(context)
9
+ @context = context
42
10
  @installed = false
43
11
  end
44
12
 
13
+ def logger
14
+ context.logger
15
+ end
16
+
45
17
  def installed?
46
18
  @installed
47
19
  end
48
20
 
49
21
  def install
50
- @installed = true
51
-
52
- if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3 && ::Rails.respond_to?(:configuration)
22
+ if install_via_after_initialize?
53
23
  Rails.configuration.after_initialize do
54
24
  add_instruments
55
25
  end
@@ -58,9 +28,21 @@ module ScoutApm
58
28
  end
59
29
  end
60
30
 
31
+ # If we have the right version of rails, we should use the hooks provided
32
+ # to install these instruments
33
+ def install_via_after_initialize?
34
+ defined?(::Rails) &&
35
+ defined?(::Rails::VERSION) &&
36
+ defined?(::Rails::VERSION::MAJOR) &&
37
+ ::Rails::VERSION::MAJOR.to_i == 3 &&
38
+ ::Rails.respond_to?(:configuration)
39
+ end
40
+
61
41
  def add_instruments
62
42
  # Setup Tracer on AR::Base
63
43
  if Utils::KlassHelper.defined?("ActiveRecord::Base")
44
+ @installed = true
45
+
64
46
  ::ActiveRecord::Base.class_eval do
65
47
  include ::ScoutApm::Tracer
66
48
  end
@@ -112,14 +94,14 @@ module ScoutApm
112
94
  if layer && layer.type == "ActiveRecord"
113
95
  layer.annotate_layer(payload)
114
96
  elsif layer
115
- ScoutApm::Agent.instance.logger.debug("Expected layer type: ActiveRecord, got #{layer && layer.type}")
97
+ logger.debug("Expected layer type: ActiveRecord, got #{layer && layer.type}")
116
98
  else
117
99
  # noop, no layer at all. We're probably ignoring this req.
118
100
  end
119
101
  end
120
102
  end
121
103
  rescue
122
- ScoutApm::Agent.instance.logger.warn "ActiveRecord instrumentation exception: #{$!.message}"
104
+ logger.warn "ActiveRecord instrumentation exception: #{$!.message}"
123
105
  end
124
106
  end
125
107
 
@@ -134,7 +116,7 @@ module ScoutApm
134
116
  ################################################################################
135
117
  module ActiveRecordInstruments
136
118
  def self.included(instrumented_class)
137
- ScoutApm::Agent.instance.logger.info "Instrumenting #{instrumented_class.inspect}"
119
+ ScoutApm::Agent.instance.context.logger.info "Instrumenting #{instrumented_class.inspect}"
138
120
  instrumented_class.class_eval do
139
121
  unless instrumented_class.method_defined?(:log_without_scout_instruments)
140
122
  alias_method :log_without_scout_instruments, :log
@@ -147,12 +129,13 @@ module ScoutApm
147
129
  # Extract data from the arguments
148
130
  sql, name = args
149
131
  metric_name = Utils::ActiveRecordMetricName.new(sql, name)
150
- desc = SqlList.new(sql)
132
+ desc = Utils::SqlSanitizer.new(sql)
151
133
 
152
134
  # Get current ScoutApm context
153
135
  req = ScoutApm::RequestManager.lookup
154
136
  current_layer = req.current_layer
155
137
 
138
+
156
139
  # If we call #log, we have a real query to run, and we've already
157
140
  # gotten through the cache gatekeeper. Since we want to only trace real
158
141
  # queries, and not repeated identical queries that just hit cache, we
@@ -167,13 +150,9 @@ module ScoutApm
167
150
  # TODO: Get rid of call .to_s, need to find this without forcing a previous run of the name logic
168
151
  if current_layer.name.to_s == Utils::ActiveRecordMetricName::DEFAULT_METRIC
169
152
  current_layer.name = metric_name
153
+ current_layer.desc = desc
170
154
  end
171
155
 
172
- if current_layer.desc.nil?
173
- current_layer.desc = SqlList.new
174
- end
175
- current_layer.desc.merge(desc)
176
-
177
156
  log_without_scout_instruments(*args, &block)
178
157
 
179
158
  # OR: Start a new layer, we didn't pick up instrumentation earlier in the stack.
@@ -211,7 +190,7 @@ module ScoutApm
211
190
 
212
191
  module ActiveRecordQueryingInstruments
213
192
  def self.included(instrumented_class)
214
- ScoutApm::Agent.instance.logger.info "Instrumenting ActiveRecord::Querying - #{instrumented_class.inspect}"
193
+ ScoutApm::Agent.instance.context.logger.info "Instrumenting ActiveRecord::Querying - #{instrumented_class.inspect}"
215
194
  instrumented_class.class_eval do
216
195
  unless instrumented_class.method_defined?(:find_by_sql_without_scout_instruments)
217
196
  alias_method :find_by_sql_without_scout_instruments, :find_by_sql
@@ -237,7 +216,7 @@ module ScoutApm
237
216
 
238
217
  module ActiveRecordFinderMethodsInstruments
239
218
  def self.included(instrumented_class)
240
- ScoutApm::Agent.instance.logger.info "Instrumenting ActiveRecord::FinderMethods - #{instrumented_class.inspect}"
219
+ ScoutApm::Agent.instance.context.logger.info "Instrumenting ActiveRecord::FinderMethods - #{instrumented_class.inspect}"
241
220
  instrumented_class.class_eval do
242
221
  unless instrumented_class.method_defined?(:find_with_associations_without_scout_instruments)
243
222
  alias_method :find_with_associations_without_scout_instruments, :find_with_associations
@@ -250,7 +229,6 @@ module ScoutApm
250
229
  req = ScoutApm::RequestManager.lookup
251
230
  layer = ScoutApm::Layer.new("ActiveRecord", Utils::ActiveRecordMetricName::DEFAULT_METRIC)
252
231
  layer.annotate_layer(:ignorable => true)
253
- layer.desc = SqlList.new
254
232
  req.start_layer(layer)
255
233
  req.ignore_children!
256
234
  begin
@@ -269,7 +247,6 @@ module ScoutApm
269
247
 
270
248
  req = ScoutApm::RequestManager.lookup
271
249
  layer = ScoutApm::Layer.new("ActiveRecord", Utils::ActiveRecordMetricName.new("", "#{model} #{operation}"))
272
- layer.desc = SqlList.new
273
250
  req.start_layer(layer)
274
251
  req.ignore_children!
275
252
  begin