scout_apm 5.1.1 → 5.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +22 -5
  3. data/CHANGELOG.markdown +32 -0
  4. data/gems/instruments.gemfile +6 -0
  5. data/gems/sidekiq.gemfile +4 -0
  6. data/lib/scout_apm/background_job_integrations/sidekiq.rb +2 -8
  7. data/lib/scout_apm/config.rb +16 -1
  8. data/lib/scout_apm/instrument_manager.rb +19 -1
  9. data/lib/scout_apm/instruments/action_controller_rails_2.rb +1 -1
  10. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +1 -1
  11. data/lib/scout_apm/instruments/action_view.rb +1 -1
  12. data/lib/scout_apm/instruments/active_record.rb +2 -2
  13. data/lib/scout_apm/instruments/elasticsearch.rb +91 -42
  14. data/lib/scout_apm/instruments/grape.rb +1 -1
  15. data/lib/scout_apm/instruments/http.rb +36 -16
  16. data/lib/scout_apm/instruments/http_client.rb +33 -14
  17. data/lib/scout_apm/instruments/influxdb.rb +2 -2
  18. data/lib/scout_apm/instruments/memcached.rb +26 -11
  19. data/lib/scout_apm/instruments/middleware_detailed.rb +1 -1
  20. data/lib/scout_apm/instruments/middleware_summary.rb +1 -1
  21. data/lib/scout_apm/instruments/mongoid.rb +1 -1
  22. data/lib/scout_apm/instruments/moped.rb +44 -19
  23. data/lib/scout_apm/instruments/net_http.rb +49 -21
  24. data/lib/scout_apm/instruments/rails_router.rb +1 -1
  25. data/lib/scout_apm/instruments/redis.rb +27 -12
  26. data/lib/scout_apm/instruments/redis5.rb +59 -0
  27. data/lib/scout_apm/instruments/sinatra.rb +1 -1
  28. data/lib/scout_apm/instruments/typhoeus.rb +1 -1
  29. data/lib/scout_apm/layer_converters/external_service_converter.rb +1 -1
  30. data/lib/scout_apm/server_integrations/puma.rb +29 -1
  31. data/lib/scout_apm/slow_request_policy.rb +1 -1
  32. data/lib/scout_apm/store.rb +6 -0
  33. data/lib/scout_apm/version.rb +1 -1
  34. data/lib/scout_apm.rb +1 -0
  35. data/test/test_helper.rb +26 -0
  36. data/test/unit/background_job_integrations/sidekiq_test.rb +17 -0
  37. data/test/unit/environment_test.rb +0 -28
  38. data/test/unit/instruments/active_record_test.rb +31 -1
  39. data/test/unit/instruments/http_client_test.rb +24 -0
  40. data/test/unit/instruments/http_test.rb +24 -0
  41. data/test/unit/instruments/moped_test.rb +24 -0
  42. data/test/unit/instruments/net_http_test.rb +11 -1
  43. data/test/unit/instruments/redis_test.rb +24 -0
  44. data/test/unit/instruments/typhoeus_test.rb +1 -1
  45. metadata +78 -7
@@ -16,7 +16,7 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  @installed = true
21
21
 
22
22
  # Mongoid versions that use Moped should instrument Moped.
@@ -16,32 +16,37 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  if defined?(::Moped)
21
21
  @installed = true
22
22
 
23
- logger.info "Instrumenting Moped"
23
+ logger.info "Instrumenting Moped. Prepend: #{prepend}"
24
24
 
25
- ::Moped::Node.class_eval do
26
- include ScoutApm::Tracer
25
+ if prepend
26
+ ::Moped::Node.send(:include, ScoutApm::Tracer)
27
+ ::Moped::Node.send(:prepend, MopedInstrumentationPrepend)
28
+ else
29
+ ::Moped::Node.class_eval do
30
+ include ScoutApm::Tracer
27
31
 
28
- def process_with_scout_instruments(operation, &callback)
29
- if operation.respond_to?(:collection)
30
- collection = operation.collection
31
- name = "Process/#{collection}/#{operation.class.to_s.split('::').last}"
32
- self.class.instrument("MongoDB", name, :annotate_layer => { :query => scout_sanitize_log(operation.log_inspect) }) do
33
- process_without_scout_instruments(operation, &callback)
32
+ def process_with_scout_instruments(operation, &callback)
33
+ if operation.respond_to?(:collection)
34
+ collection = operation.collection
35
+ name = "Process/#{collection}/#{operation.class.to_s.split('::').last}"
36
+ self.class.instrument("MongoDB", name, :annotate_layer => { :query => scout_sanitize_log(operation.log_inspect) }) do
37
+ process_without_scout_instruments(operation, &callback)
38
+ end
34
39
  end
35
40
  end
36
- end
37
- alias_method :process_without_scout_instruments, :process
38
- alias_method :process, :process_with_scout_instruments
39
-
40
- # replaces values w/ ?
41
- def scout_sanitize_log(log)
42
- return nil if log.length > 1000 # safeguard - don't sanitize large SQL statements
43
- log.gsub(/(=>")((?:[^"]|"")*)"/) do
44
- $1 + '?' + '"'
41
+ alias_method :process_without_scout_instruments, :process
42
+ alias_method :process, :process_with_scout_instruments
43
+
44
+ # replaces values w/ ?
45
+ def scout_sanitize_log(log)
46
+ return nil if log.length > 1000 # safeguard - don't sanitize large SQL statements
47
+ log.gsub(/(=>")((?:[^"]|"")*)"/) do
48
+ $1 + '?' + '"'
49
+ end
45
50
  end
46
51
  end
47
52
  end
@@ -49,6 +54,26 @@ module ScoutApm
49
54
  end
50
55
 
51
56
  end
57
+
58
+ module MopedInstrumentationPrepend
59
+ def process(operation, &callback)
60
+ if operation.respond_to?(:collection)
61
+ collection = operation.collection
62
+ name = "Process/#{collection}/#{operation.class.to_s.split('::').last}"
63
+ self.class.instrument("MongoDB", name, :annotate_layer => { :query => scout_sanitize_log(operation.log_inspect) }) do
64
+ super(operation, &callback)
65
+ end
66
+ end
67
+ end
68
+
69
+ # replaces values w/ ?
70
+ def scout_sanitize_log(log)
71
+ return nil if log.length > 1000 # safeguard - don't sanitize large SQL statements
72
+ log.gsub(/(=>")((?:[^"]|"")*)"/) do
73
+ $1 + '?' + '"'
74
+ end
75
+ end
76
+ end
52
77
  end
53
78
  end
54
79
 
@@ -16,41 +16,69 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  if defined?(::Net) && defined?(::Net::HTTP)
21
21
  @installed = true
22
22
 
23
- logger.info "Instrumenting Net::HTTP"
23
+ logger.info "Instrumenting Net::HTTP. Prepend: #{prepend}"
24
24
 
25
- ::Net::HTTP.class_eval do
26
- include ScoutApm::Tracer
25
+ if prepend
26
+ ::Net::HTTP.send(:include, ScoutApm::Tracer)
27
+ ::Net::HTTP.send(:prepend, NetHttpInstrumentationPrepend)
28
+ else
29
+ ::Net::HTTP.class_eval do
30
+ include ScoutApm::Tracer
27
31
 
28
- def request_with_scout_instruments(*args, &block)
29
- self.class.instrument("HTTP", "request", :ignore_children => true, :desc => request_scout_description(args.first)) do
30
- request_without_scout_instruments(*args, &block)
32
+ def request_with_scout_instruments(*args, &block)
33
+ self.class.instrument("HTTP", "request", :ignore_children => true, :desc => request_scout_description(args.first)) do
34
+ request_without_scout_instruments(*args, &block)
35
+ end
31
36
  end
32
- end
33
37
 
34
- def request_scout_description(req)
35
- path = req.path
36
- path = path.path if path.respond_to?(:path)
38
+ def request_scout_description(req)
39
+ path = req.path
40
+ path = path.path if path.respond_to?(:path)
41
+
42
+ # Protect against a nil address value
43
+ if @address.nil?
44
+ return "No Address Found"
45
+ end
37
46
 
38
- # Protect against a nil address value
39
- if @address.nil?
40
- return "No Address Found"
47
+ max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
48
+ (@address + path.split('?').first)[0..(max_length - 1)]
49
+ rescue
50
+ ""
41
51
  end
42
52
 
43
- max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
44
- (@address + path.split('?').first)[0..(max_length - 1)]
45
- rescue
46
- ""
53
+ alias request_without_scout_instruments request
54
+ alias request request_with_scout_instruments
47
55
  end
48
-
49
- alias request_without_scout_instruments request
50
- alias request request_with_scout_instruments
51
56
  end
52
57
  end
53
58
  end
54
59
  end
60
+
61
+ module NetHttpInstrumentationPrepend
62
+ def request(request, *args, &block)
63
+ self.class.instrument("HTTP", "request", :ignore_children => true, :desc => request_scout_description(request)) do
64
+ super(request, *args, &block)
65
+ end
66
+ end
67
+
68
+ def request_scout_description(req)
69
+ path = req.path
70
+ path = path.path if path.respond_to?(:path)
71
+
72
+ # Protect against a nil address value
73
+ if @address.nil?
74
+ return "No Address Found"
75
+ end
76
+
77
+ max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
78
+ (@address + path.split('?').first)[0..(max_length - 1)]
79
+ rescue
80
+ ""
81
+ end
82
+ end
55
83
  end
56
84
  end
@@ -16,7 +16,7 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  if defined?(ActionDispatch) && defined?(ActionDispatch::Routing) && defined?(ActionDispatch::Routing::RouteSet)
21
21
  @installed = true
22
22
 
@@ -16,28 +16,43 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
20
- if defined?(::Redis) && defined?(::Redis::Client)
19
+ def install(prepend:)
20
+ if defined?(::Redis) && defined?(::Redis::Client) && ::Redis::Client.instance_methods(false).include?(:call)
21
21
  @installed = true
22
22
 
23
- logger.info "Instrumenting Redis"
23
+ logger.info "Instrumenting Redis. Prepend: #{prepend}"
24
24
 
25
- ::Redis::Client.class_eval do
26
- include ScoutApm::Tracer
25
+ if prepend
26
+ ::Redis::Client.send(:include, ScoutApm::Tracer)
27
+ ::Redis::Client.send(:prepend, RedisClientInstrumentationPrepend)
28
+ else
29
+ ::Redis::Client.class_eval do
30
+ include ScoutApm::Tracer
27
31
 
28
- def call_with_scout_instruments(*args, &block)
29
- command = args.first.first rescue "Unknown"
32
+ def call_with_scout_instruments(*args, &block)
33
+ command = args.first.first rescue "Unknown"
30
34
 
31
- self.class.instrument("Redis", command) do
32
- call_without_scout_instruments(*args, &block)
35
+ self.class.instrument("Redis", command) do
36
+ call_without_scout_instruments(*args, &block)
37
+ end
33
38
  end
34
- end
35
39
 
36
- alias_method :call_without_scout_instruments, :call
37
- alias_method :call, :call_with_scout_instruments
40
+ alias_method :call_without_scout_instruments, :call
41
+ alias_method :call, :call_with_scout_instruments
42
+ end
38
43
  end
39
44
  end
40
45
  end
41
46
  end
47
+
48
+ module RedisClientInstrumentationPrepend
49
+ def call(*args, &block)
50
+ command = args.first.first rescue "Unknown"
51
+
52
+ self.class.instrument("Redis", command) do
53
+ super(*args, &block)
54
+ end
55
+ end
56
+ end
42
57
  end
43
58
  end
@@ -0,0 +1,59 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ class Redis5
4
+ attr_reader :context
5
+
6
+ def initialize(context)
7
+ @context = context
8
+ @installed = false
9
+ end
10
+
11
+ def logger
12
+ context.logger
13
+ end
14
+
15
+ def installed?
16
+ @installed
17
+ end
18
+
19
+ def install(prepend:)
20
+ if defined?(::Redis) && defined?(::Redis::Client) && ::Redis::Client.instance_methods(false).include?(:call_v)
21
+ @installed = true
22
+
23
+ logger.info "Instrumenting Redis5. Prepend: #{prepend}"
24
+
25
+ if prepend
26
+ ::Redis::Client.send(:include, ScoutApm::Tracer)
27
+ ::Redis::Client.send(:prepend, Redis5ClientInstrumentationPrepend)
28
+ else
29
+ ::Redis::Client.class_eval do
30
+ include ScoutApm::Tracer
31
+
32
+ def call_with_scout_instruments(args, &block)
33
+ command = args.first rescue "Unknown"
34
+
35
+ self.class.instrument("Redis", command) do
36
+ call_without_scout_instruments(args, &block)
37
+ end
38
+ end
39
+
40
+ alias_method :call_without_scout_instruments, :call_v
41
+ alias_method :call_v, :call_with_scout_instruments
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ module Redis5ClientInstrumentationPrepend
49
+ def call(args, &block)
50
+ command = args.first rescue "Unknown"
51
+
52
+ self.class.instrument("Redis", command) do
53
+ super(args, &block)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
@@ -15,7 +15,7 @@ module ScoutApm
15
15
  @installed
16
16
  end
17
17
 
18
- def install
18
+ def install(prepend:)
19
19
  if defined?(::Sinatra) && defined?(::Sinatra::Base) && ::Sinatra::Base.private_method_defined?(:dispatch!)
20
20
  @installed = true
21
21
 
@@ -16,7 +16,7 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  if defined?(::Typhoeus)
21
21
  @installed = true
22
22
 
@@ -53,7 +53,7 @@ module ScoutApm
53
53
  rescue
54
54
  # Do nothing
55
55
  ensure
56
- domain = DEFAULT_DOMAIN if domain.to_s.blank?
56
+ domain = DEFAULT_DOMAIN if (domain.nil? || domain.empty?)
57
57
  domain
58
58
  end
59
59
 
@@ -23,8 +23,36 @@ module ScoutApm
23
23
  defined?(::Puma) && (File.basename($0) =~ /\Apuma/)
24
24
  end
25
25
 
26
+ # Puma::UserFileDefaultOptions exposes `options` based on three underlying
27
+ # hashes: user_options, file_options, and default_options. While getting an `options`
28
+ # key consults all three underlying hashes, setting an `options` key only sets the
29
+ # user_options hash:
30
+ #
31
+ # def [](key)
32
+ # fetch(key)
33
+ # end
34
+ #
35
+ # def []=(key, value)
36
+ # user_options[key] = value
37
+ # end
38
+ #
39
+ # def fetch(key, default_value = nil)
40
+ # return user_options[key] if user_options.key?(key)
41
+ # return file_options[key] if file_options.key?(key)
42
+ # return default_options[key] if default_options.key?(key)
43
+ #
44
+ # default_value
45
+ # end
46
+ #
47
+ # Because of this, we can't read options[:before_worker_boot], modify, and then re-set
48
+ # options[:before_worker_boot], since doing so could cause duplication if `before_worker_boot`
49
+ # exists on the other two underlying hashes (file_options, default_options).
50
+ #
51
+ # To get around this, we explicitly read from `user_options` only, and still set using `options[]=`,
52
+ # which Puma allows for setting `user_options`.
53
+ #
26
54
  def install
27
- old = ::Puma.cli_config.options[:before_worker_boot] || []
55
+ old = ::Puma.cli_config.options.user_options[:before_worker_boot] || []
28
56
  new = Array(old) + [Proc.new do
29
57
  logger.info "Installing Puma worker loop."
30
58
  ScoutApm::Agent.instance.start_background_worker
@@ -14,7 +14,7 @@ module ScoutApm
14
14
 
15
15
  def add_default_policies
16
16
  add(SlowPolicy::SpeedPolicy.new(context))
17
- add(SlowPolicy::PercentilePolicy.new(context))
17
+ add(SlowPolicy::PercentPolicy.new(context))
18
18
  add(SlowPolicy::AgePolicy.new(context))
19
19
  add(SlowPolicy::PercentilePolicy.new(context))
20
20
  end
@@ -217,6 +217,7 @@ module ScoutApm
217
217
 
218
218
  def initialize(timestamp, context)
219
219
  @timestamp = timestamp
220
+ @context = context
220
221
 
221
222
  @request_traces = ScoredItemSet.new(context.config.value('max_traces'))
222
223
  @job_traces = ScoredItemSet.new(context.config.value('max_traces'))
@@ -230,6 +231,11 @@ module ScoutApm
230
231
  @jobs = Hash.new
231
232
  end
232
233
 
234
+ def logger
235
+ @context.logger
236
+ end
237
+ private :logger
238
+
233
239
  # Merges another StoreReportingPeriod into this one
234
240
  def merge(other)
235
241
  self.
@@ -1,3 +1,3 @@
1
1
  module ScoutApm
2
- VERSION = "5.1.1"
2
+ VERSION = "5.3.5"
3
3
  end
data/lib/scout_apm.rb CHANGED
@@ -87,6 +87,7 @@ require 'scout_apm/instruments/moped'
87
87
  require 'scout_apm/instruments/mongoid'
88
88
  require 'scout_apm/instruments/memcached'
89
89
  require 'scout_apm/instruments/redis'
90
+ require 'scout_apm/instruments/redis5'
90
91
  require 'scout_apm/instruments/influxdb'
91
92
  require 'scout_apm/instruments/elasticsearch'
92
93
  require 'scout_apm/instruments/active_record'
data/test/test_helper.rb CHANGED
@@ -65,6 +65,32 @@ class FakeEnvironment
65
65
  end
66
66
  end
67
67
 
68
+ def fake_rails(version)
69
+ Kernel.const_set("Rails", Module.new)
70
+ Kernel.const_set("ActionController", Module.new)
71
+ r = Kernel.const_get("Rails")
72
+ r.const_set("VERSION", Module.new)
73
+ v = r.const_get("VERSION")
74
+ v.const_set("MAJOR", version)
75
+
76
+ assert_equal version, Rails::VERSION::MAJOR
77
+ end
78
+
79
+ def clean_fake_rails
80
+ Kernel.send(:remove_const, "Rails") if defined?(Kernel::Rails)
81
+ Kernel.send(:remove_const, "ActionController") if defined?(Kernel::ActionController)
82
+ end
83
+
84
+ def fake_sinatra
85
+ Kernel.const_set("Sinatra", Module.new)
86
+ s = Kernel.const_get("Sinatra")
87
+ s.const_set("Base", Module.new)
88
+ end
89
+
90
+ def clean_fake_sinatra
91
+ Kernel.const_unset("Sinatra") if defined?(Kernel::Sinatra)
92
+ end
93
+
68
94
  # Helpers available to all tests
69
95
  class Minitest::Test
70
96
  def setup
@@ -3,8 +3,25 @@ require 'scout_apm/request_manager'
3
3
  require 'scout_apm/background_job_integrations/sidekiq'
4
4
 
5
5
  class SidekiqTest < Minitest::Test
6
+ SidekiqIntegration = ScoutApm::BackgroundJobIntegrations::Sidekiq
6
7
  SidekiqMiddleware = ScoutApm::BackgroundJobIntegrations::SidekiqMiddleware
7
8
 
9
+ ########################################
10
+ # Install
11
+ ########################################
12
+ if (ENV["SCOUT_TEST_FEATURES"] || "").include?("sidekiq_install")
13
+ require 'sidekiq'
14
+
15
+ # Sidekiq::CLI needs to be defined in order for `Sidekiq.configure_server` to work
16
+ Sidekiq::CLI = nil
17
+
18
+ def test_starts_on_startup
19
+ ::ScoutApm::Agent.any_instance.expects(:start)
20
+ SidekiqIntegration.new.install
21
+ Sidekiq.options[:lifecycle_events][:startup].map(&:call)
22
+ end
23
+ end
24
+
8
25
  ########################################
9
26
  # Middleware
10
27
  ########################################
@@ -29,32 +29,4 @@ class EnvironmentTest < Minitest::Test
29
29
  def test_framework_ruby
30
30
  assert_equal :ruby, ScoutApm::Environment.send(:new).framework
31
31
  end
32
-
33
- ############################################################
34
-
35
- def fake_rails(version)
36
- Kernel.const_set("Rails", Module.new)
37
- Kernel.const_set("ActionController", Module.new)
38
- r = Kernel.const_get("Rails")
39
- r.const_set("VERSION", Module.new)
40
- v = r.const_get("VERSION")
41
- v.const_set("MAJOR", version)
42
-
43
- assert_equal version, Rails::VERSION::MAJOR
44
- end
45
-
46
- def clean_fake_rails
47
- Kernel.send(:remove_const, "Rails") if defined?(Kernel::Rails)
48
- Kernel.send(:remove_const, "ActionController") if defined?(Kernel::ActionController)
49
- end
50
-
51
- def fake_sinatra
52
- Kernel.const_set("Sinatra", Module.new)
53
- s = Kernel.const_get("Sinatra")
54
- s.const_set("Base", Module.new)
55
- end
56
-
57
- def clean_fake_sinatra
58
- Kernel.const_unset("Sinatra") if defined?(Kernel::Sinatra)
59
- end
60
32
  end
@@ -24,12 +24,42 @@ class ActiveRecordTest < Minitest::Test
24
24
  class User < ActiveRecord::Base
25
25
  end
26
26
 
27
+ class DumbRailsConfig
28
+ def self.after_initialize; end
29
+ end
30
+
31
+ def test_old_rails_initialization
32
+ recorder = FakeRecorder.new
33
+ agent_context.recorder = recorder
34
+ old_rails_version = (1..2).to_a.sample
35
+ fake_rails(old_rails_version)
36
+
37
+ ::Rails.expects(:configuration).never
38
+
39
+ instrument = ScoutApm::Instruments::ActiveRecord.new(agent_context)
40
+ instrument.install(prepend: false)
41
+ clean_fake_rails
42
+ end
43
+
44
+ def test_modern_rails_initialization
45
+ recorder = FakeRecorder.new
46
+ agent_context.recorder = recorder
47
+ modern_rails_version = (3..7).to_a.sample
48
+ fake_rails(modern_rails_version)
49
+
50
+ ::Rails.expects(:configuration).returns(DumbRailsConfig).once
51
+
52
+ instrument = ScoutApm::Instruments::ActiveRecord.new(agent_context)
53
+ instrument.install(prepend: false)
54
+ clean_fake_rails
55
+ end
56
+
27
57
  def test_instrumentation
28
58
  recorder = FakeRecorder.new
29
59
  agent_context.recorder = recorder
30
60
 
31
61
  instrument = ScoutApm::Instruments::ActiveRecord.new(agent_context)
32
- instrument.install
62
+ instrument.install(prepend: false)
33
63
 
34
64
  ScoutApm::Tracer.instrument("Controller", "foo/bar") do
35
65
  user = User.create
@@ -0,0 +1,24 @@
1
+ if (ENV["SCOUT_TEST_FEATURES"] || "").include?("instruments")
2
+ require 'test_helper'
3
+
4
+ require 'scout_apm/instruments/http_client'
5
+
6
+ require 'httpclient'
7
+
8
+ class HttpClientTest < Minitest::Test
9
+ def setup
10
+ @context = ScoutApm::AgentContext.new
11
+ @instance = ScoutApm::Instruments::HttpClient.new(@context)
12
+ @instrument_manager = ScoutApm::InstrumentManager.new(@context)
13
+ @instance.install(prepend: @instrument_manager.prepend_for_instrument?(@instance.class))
14
+ end
15
+
16
+ def test_installs_using_proper_method
17
+ if @instrument_manager.prepend_for_instrument?(@instance.class) == true
18
+ assert ::HTTPClient.ancestors.include?(ScoutApm::Instruments::HttpClientInstrumentationPrepend)
19
+ else
20
+ assert_equal false, ::HTTPClient.ancestors.include?(ScoutApm::Instruments::HttpClientInstrumentationPrepend)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ if (ENV["SCOUT_TEST_FEATURES"] || "").include?("instruments")
2
+ require 'test_helper'
3
+
4
+ require 'scout_apm/instruments/http'
5
+
6
+ require 'http'
7
+
8
+ class HttpTest < Minitest::Test
9
+ def setup
10
+ @context = ScoutApm::AgentContext.new
11
+ @instance = ScoutApm::Instruments::HTTP.new(@context)
12
+ @instrument_manager = ScoutApm::InstrumentManager.new(@context)
13
+ @instance.install(prepend: @instrument_manager.prepend_for_instrument?(@instance.class))
14
+ end
15
+
16
+ def test_installs_using_proper_method
17
+ if @instrument_manager.prepend_for_instrument?(@instance.class) == true
18
+ assert ::HTTP::Client.ancestors.include?(ScoutApm::Instruments::HTTPInstrumentationPrepend)
19
+ else
20
+ assert_equal false, ::HTTP::Client.ancestors.include?(ScoutApm::Instruments::HTTPInstrumentationPrepend)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ if (ENV["SCOUT_TEST_FEATURES"] || "").include?("instruments")
2
+ require 'test_helper'
3
+
4
+ require 'scout_apm/instruments/moped'
5
+
6
+ require 'moped'
7
+
8
+ class MopedTest < Minitest::Test
9
+ def setup
10
+ @context = ScoutApm::AgentContext.new
11
+ @instance = ScoutApm::Instruments::Moped.new(@context)
12
+ @instrument_manager = ScoutApm::InstrumentManager.new(@context)
13
+ @instance.install(prepend: @instrument_manager.prepend_for_instrument?(@instance.class))
14
+ end
15
+
16
+ def test_installs_using_proper_method
17
+ if @instrument_manager.prepend_for_instrument?(@instance.class) == true
18
+ assert ::Moped::Node.ancestors.include?(ScoutApm::Instruments::MopedInstrumentationPrepend)
19
+ else
20
+ assert_equal false, ::Moped::Node.ancestors.include?(ScoutApm::Instruments::MopedInstrumentationPrepend)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -7,7 +7,9 @@ require 'addressable/uri'
7
7
  class NetHttpTest < Minitest::Test
8
8
  def setup
9
9
  @context = ScoutApm::AgentContext.new
10
- ScoutApm::Instruments::NetHttp.new(@context).install
10
+ @instance = ScoutApm::Instruments::NetHttp.new(@context)
11
+ @instrument_manager = ScoutApm::InstrumentManager.new(@context)
12
+ @instance.install(prepend: @instrument_manager.prepend_for_instrument?(@instance.class))
11
13
  end
12
14
 
13
15
  def test_request_scout_description_for_uri
@@ -24,4 +26,12 @@ class NetHttpTest < Minitest::Test
24
26
  req = Net::HTTP::Get.new(Addressable::URI.parse('http://example.org/here'))
25
27
  assert_equal '/here', Net::HTTP.new('').request_scout_description(req)
26
28
  end
29
+
30
+ def test_installs_using_proper_method
31
+ if @instrument_manager.prepend_for_instrument?(@instance.class) == true
32
+ assert Net::HTTP.ancestors.include?(ScoutApm::Instruments::NetHttpInstrumentationPrepend)
33
+ else
34
+ assert_equal false, Net::HTTP.ancestors.include?(ScoutApm::Instruments::NetHttpInstrumentationPrepend)
35
+ end
36
+ end
27
37
  end