scout_apm 5.1.1 → 5.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a1da3776ca231a4d81c9ab5935e6b644ab46ae5609cef60402ccd5258e07795
4
- data.tar.gz: f583776f39fa426aa43d1942bd83e4bcd23ca3a6f71a2e883df22a74cb2db868
3
+ metadata.gz: 656e36a7b9a11b5870058c46b31e8227c628691f8ab7f7d4de991c3e89b5f13d
4
+ data.tar.gz: 5f27c0af5b3f864a96ea65944c6655106a86aa96dbf489083b1c3a178322d827
5
5
  SHA512:
6
- metadata.gz: bc2f10c76ea8abbb6f74cbe86cbd0e0d1265143a19008307609be35adb57737f474c9a2f59545e2f36b00b5006c5f1b9726f59e70c3e327e6487eb2445e07df6
7
- data.tar.gz: 8863c891bbd5f1e87d56a06f8275cbcf711b15964116cbddbb648398825eed65fa6ce73cd3848815e8ab8a1eec1f8a2e4a878682e2d47d457778786532ee3db4
6
+ metadata.gz: b805ac798aa0f430182e31e9d4b3d924d20624a59406d333f8d8d02ead0d30bece36bf0b127b4b9e04a5cf149cc9e67621ab72f2143f7fcd5c03f70790fedf09
7
+ data.tar.gz: 6883c955de7003baeb2685c369f63532b45e1c25b5859067fdfb2112e31abae6f57e2dc44dd5b06f55d66f3a6b9b778904de864c45905a63cdd9516719d59367
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
 
9
9
  steps:
10
- - uses: actions/checkout@v2
10
+ - uses: actions/checkout@v3
11
11
  - uses: ruby/setup-ruby@v1
12
12
  with:
13
13
  bundler-cache: true
@@ -35,16 +35,33 @@ jobs:
35
35
  gemfile: gems/rails3.gemfile
36
36
  bundler: 1.17.3
37
37
  - ruby: 2.7
38
- - ruby: 3.0
39
-
38
+ - ruby: 2.7
39
+ prepend: true
40
+ - ruby: "3.0"
41
+ - ruby: "3.0"
42
+ prepend: true
43
+ - ruby: "3.0"
44
+ gemfile: gems/instruments.gemfile
45
+ test_features: "instruments"
46
+ - ruby: "3.0"
47
+ gemfile: gems/instruments.gemfile
48
+ prepend: true
49
+ test_features: "instruments"
50
+ - ruby: "3.0"
51
+ gemfile: gems/sidekiq.gemfile
52
+ test_features: "sidekiq_install"
53
+ - ruby: 3.1
54
+ - ruby: 3.2
40
55
  env:
41
56
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
42
57
  SCOUT_TEST_FEATURES: ${{ matrix.test_features }}
58
+ SCOUT_USE_PREPEND: ${{ matrix.prepend }}
43
59
 
44
- runs-on: ubuntu-latest
60
+ # https://github.com/ruby/setup-ruby/issues/496
61
+ runs-on: ${{ matrix.ruby == '2.2' && 'ubuntu-20.04' || 'ubuntu-latest' }}
45
62
 
46
63
  steps:
47
- - uses: actions/checkout@v2
64
+ - uses: actions/checkout@v3
48
65
  - uses: ruby/setup-ruby@v1
49
66
  with:
50
67
  bundler-cache: true
data/CHANGELOG.markdown CHANGED
@@ -1,5 +1,37 @@
1
1
  # Unreleased
2
2
 
3
+ # 5.3.5
4
+ * Fix adding instrumentation of ActiveRecord after configuration has initialized for Rails versions greater than 3. (#465)
5
+ * Fix typo with double use of PercentilePolicy, instead of PercentPolicy, for scoring. (#468)
6
+ * Fix span annotations/desc for external service requests with the use of prepend. (#471)
7
+ * Fix ActiveSupport methods and replace them with non ActiveSupport methods. (#474)
8
+
9
+ # 5.3.4
10
+ Unused.
11
+
12
+ # 5.3.3
13
+
14
+ * Fix double firing of Puma `on_worker_boot` when preloading. (#463)
15
+
16
+ # 5.3.2
17
+
18
+ * Update redis instruments to support redis v5.0+ (#458)
19
+ # 5.3.1
20
+
21
+ * Fix typo in HTTPClient prepend instrumentation (#457)
22
+
23
+ # 5.3.0
24
+
25
+ * Add configuraiton option to use `Module#prepend` instead of `Module#alias_method` (default)
26
+ for instrumentation (#448). The default method for instrumentation has not changed, but
27
+ configuration options were added to allow switching to `Module#prepend` for most
28
+ instrumentation. Refer to the documentation for more information:
29
+ [Library Instrumentation Method](https://scoutapm.com/docs/ruby/configuration#library-instrumentation-method)
30
+
31
+ # 5.2.0
32
+
33
+ * Use Sidekiq lifecycle hooks to start Scout agent on Sidekiq start. (#449)
34
+
3
35
  # 5.1.1
4
36
 
5
37
  * Improvements to SqlServer scrubbing in SqlSanitizer (#422)
@@ -0,0 +1,6 @@
1
+ eval_gemfile("../Gemfile")
2
+
3
+ gem 'httpclient'
4
+ gem 'http'
5
+ gem 'redis'
6
+ gem 'moped'
@@ -0,0 +1,4 @@
1
+ eval_gemfile("../Gemfile")
2
+
3
+ # https://github.com/scoutapp/scout_apm_ruby/issues/449
4
+ gem 'sidekiq', '~> 6.5.0'
@@ -37,17 +37,11 @@ module ScoutApm
37
37
  end
38
38
 
39
39
  def install_processor
40
- require 'sidekiq/processor' # sidekiq v4 has not loaded this file by this point
41
-
42
- ::Sidekiq::Processor.class_eval do
43
- def initialize_with_scout(*args)
40
+ ::Sidekiq.configure_server do |config|
41
+ config.on(:startup) do
44
42
  agent = ::ScoutApm::Agent.instance
45
43
  agent.start
46
- initialize_without_scout(*args)
47
44
  end
48
-
49
- alias_method :initialize_without_scout, :initialize
50
- alias_method :initialize, :initialize_with_scout
51
45
  end
52
46
  end
53
47
  end
@@ -35,7 +35,13 @@ require 'scout_apm/environment'
35
35
  # start_resque_server_instrument - Used in special situations with certain Resque installs
36
36
  # timeline_traces - true/false to enable sending of of the timeline trace format.
37
37
  # auto_instruments - true/false whether to install autoinstruments. Only installed if on a supported Ruby version.
38
- # auto_instruments_ignore - An array of file names to exclude from autoinstruments (Ex: ['application_controller']).
38
+ # auto_instruments_ignore - An array of file names to exclude from autoinstruments (Ex: ['application_controller']).
39
+ # use_prepend - Whether to apply instrumentation using Module#Prepend instead
40
+ # of Module#alias_method (Default: false)
41
+ # alias_method_instruments - If `use_prepend` is true, continue to use Module#alias_method for
42
+ # any instruments listed in this array. Default: []
43
+ # prepend_instruments - If `use_prepend` is false, force using Module#prepend for any
44
+ # instruments listed in this array. Default: []
39
45
  #
40
46
  # Any of these config settings can be set with an environment variable prefixed
41
47
  # by SCOUT_ and uppercasing the key: SCOUT_LOG_LEVEL for instance.
@@ -85,6 +91,9 @@ module ScoutApm
85
91
  'timeline_traces',
86
92
  'auto_instruments',
87
93
  'auto_instruments_ignore',
94
+ 'use_prepend',
95
+ 'alias_method_instruments',
96
+ 'prepend_instruments',
88
97
 
89
98
  # Error Service Related Configuration
90
99
  'errors_enabled',
@@ -189,6 +198,9 @@ module ScoutApm
189
198
  'timeline_traces' => BooleanCoercion.new,
190
199
  'auto_instruments' => BooleanCoercion.new,
191
200
  'auto_instruments_ignore' => JsonCoercion.new,
201
+ 'use_prepend' => BooleanCoercion.new,
202
+ 'alias_method_instruments' => JsonCoercion.new,
203
+ 'prepend_instruments' => JsonCoercion.new,
192
204
  'errors_enabled' => BooleanCoercion.new,
193
205
  'errors_ignored_exceptions' => JsonCoercion.new,
194
206
  'errors_filtered_params' => JsonCoercion.new,
@@ -305,6 +317,9 @@ module ScoutApm
305
317
  'timeline_traces' => true,
306
318
  'auto_instruments' => false,
307
319
  'auto_instruments_ignore' => [],
320
+ 'use_prepend' => false,
321
+ 'alias_method_instruments' => [],
322
+ 'prepend_instruments' => [],
308
323
  'ssl_cert_file' => File.join( File.dirname(__FILE__), *%w[.. .. data cacert.pem] ),
309
324
  'errors_enabled' => false,
310
325
  'errors_ignored_exceptions' => %w(ActiveRecord::RecordNotFound ActionController::RoutingError),
@@ -35,6 +35,7 @@ module ScoutApm
35
35
  install_instrument(ScoutApm::Instruments::HTTP)
36
36
  install_instrument(ScoutApm::Instruments::Memcached)
37
37
  install_instrument(ScoutApm::Instruments::Redis)
38
+ install_instrument(ScoutApm::Instruments::Redis5)
38
39
  install_instrument(ScoutApm::Instruments::InfluxDB)
39
40
  install_instrument(ScoutApm::Instruments::Elasticsearch)
40
41
  install_instrument(ScoutApm::Instruments::Grape)
@@ -50,6 +51,23 @@ module ScoutApm
50
51
  (config.value("disabled_instruments") || []).include?(instrument_short_name)
51
52
  end
52
53
 
54
+ def prepend_for_instrument?(instrument_klass)
55
+ instrument_short_name = instrument_klass.name.split("::").last
56
+
57
+ # `use_prepend` defaults to false, which means we use `alias_method` by default.
58
+ # If `use_prepend` is `true`, then we should default to using `prepend` unless
59
+ # the instrument is explicitly listed in the `alias_method_instruments` config array.
60
+ if config.value("use_prepend")
61
+ return false if (config.value("alias_method_instruments") || []).include?(instrument_short_name)
62
+ return true
63
+ else
64
+ # `use_prepend` is false, but we should use `prepend` if the instrument is
65
+ # explicitly listed in the `prepend_instruments` array.
66
+ return true if (config.value("prepend_instruments") || []).include?(instrument_short_name)
67
+ return false
68
+ end
69
+ end
70
+
53
71
  private
54
72
 
55
73
  def install_instrument(instrument_klass)
@@ -62,7 +80,7 @@ module ScoutApm
62
80
 
63
81
  instance = instrument_klass.new(context)
64
82
  @installed_instruments << instance
65
- instance.install
83
+ instance.install(prepend: prepend_for_instrument?(instrument_klass))
66
84
  end
67
85
 
68
86
  def already_installed?(instrument_klass)
@@ -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?(::ActionController) && defined?(::ActionController::Base)
21
21
  @installed = true
22
22
 
@@ -21,7 +21,7 @@ module ScoutApm
21
21
  @installed = true
22
22
  end
23
23
 
24
- def install
24
+ def install(prepend:)
25
25
  if !defined?(::ActiveSupport)
26
26
  return
27
27
  end
@@ -29,7 +29,7 @@ module ScoutApm
29
29
  context.environment.supports_module_prepend?
30
30
  end
31
31
 
32
- def install
32
+ def install(prepend:)
33
33
  return unless defined?(::ActionView) && defined?(::ActionView::PartialRenderer)
34
34
 
35
35
  if prependable?
@@ -50,7 +50,7 @@ module ScoutApm
50
50
  @installed
51
51
  end
52
52
 
53
- def install
53
+ def install(prepend:)
54
54
  if install_via_after_initialize?
55
55
  Rails.configuration.after_initialize do
56
56
  add_instruments
@@ -66,7 +66,7 @@ module ScoutApm
66
66
  defined?(::Rails) &&
67
67
  defined?(::Rails::VERSION) &&
68
68
  defined?(::Rails::VERSION::MAJOR) &&
69
- ::Rails::VERSION::MAJOR.to_i == 3 &&
69
+ ::Rails::VERSION::MAJOR.to_i >= 3 &&
70
70
  ::Rails.respond_to?(:configuration)
71
71
  end
72
72
 
@@ -18,66 +18,115 @@ module ScoutApm
18
18
  @installed
19
19
  end
20
20
 
21
- def install
21
+ def install(prepend:)
22
22
  if defined?(::Elasticsearch) &&
23
23
  defined?(::Elasticsearch::Transport) &&
24
24
  defined?(::Elasticsearch::Transport::Client)
25
25
 
26
26
  @installed = true
27
27
 
28
- logger.info "Instrumenting Elasticsearch"
28
+ logger.info "Instrumenting Elasticsearch. Prepend: #{prepend}"
29
29
 
30
- ::Elasticsearch::Transport::Client.class_eval do
31
- include ScoutApm::Tracer
30
+ if prepend
31
+ ::Elasticsearch::Transport::Client.send(:include, ScoutApm::Tracer)
32
+ ::Elasticsearch::Transport::Client.send(:prepend, ElasticsearchTransportClientInstrumentationPrepend)
33
+ else
34
+ ::Elasticsearch::Transport::Client.class_eval do
35
+ include ScoutApm::Tracer
32
36
 
33
- def perform_request_with_scout_instruments(*args, &block)
34
- name = _sanitize_name(args[1])
37
+ def perform_request_with_scout_instruments(*args, &block)
38
+ name = _sanitize_name(args[1])
35
39
 
36
- self.class.instrument("Elasticsearch", name, :ignore_children => true) do
37
- perform_request_without_scout_instruments(*args, &block)
40
+ self.class.instrument("Elasticsearch", name, :ignore_children => true) do
41
+ perform_request_without_scout_instruments(*args, &block)
42
+ end
38
43
  end
39
- end
40
44
 
41
- alias_method :perform_request_without_scout_instruments, :perform_request
42
- alias_method :perform_request, :perform_request_with_scout_instruments
43
-
44
- def _sanitize_name(name)
45
- name = name.split("/").last.gsub(/^_/, '')
46
- allowed_names = ["bench",
47
- "bulk",
48
- "count",
49
- "exists",
50
- "explain",
51
- "field_stats",
52
- "health",
53
- "mget",
54
- "mlt",
55
- "mpercolate",
56
- "msearch",
57
- "mtermvectors",
58
- "percolate",
59
- "query",
60
- "scroll",
61
- "search_shards",
62
- "source",
63
- "suggest",
64
- "template",
65
- "termvectors",
66
- "update",
67
- "search", ]
68
-
69
- if allowed_names.include?(name)
70
- name
71
- else
45
+ alias_method :perform_request_without_scout_instruments, :perform_request
46
+ alias_method :perform_request, :perform_request_with_scout_instruments
47
+
48
+ def _sanitize_name(name)
49
+ name = name.split("/").last.gsub(/^_/, '')
50
+ allowed_names = ["bench",
51
+ "bulk",
52
+ "count",
53
+ "exists",
54
+ "explain",
55
+ "field_stats",
56
+ "health",
57
+ "mget",
58
+ "mlt",
59
+ "mpercolate",
60
+ "msearch",
61
+ "mtermvectors",
62
+ "percolate",
63
+ "query",
64
+ "scroll",
65
+ "search_shards",
66
+ "source",
67
+ "suggest",
68
+ "template",
69
+ "termvectors",
70
+ "update",
71
+ "search", ]
72
+
73
+ if allowed_names.include?(name)
74
+ name
75
+ else
76
+ "Unknown"
77
+ end
78
+ rescue
72
79
  "Unknown"
73
80
  end
74
- rescue
75
- "Unknown"
76
81
  end
77
82
  end
78
83
  end
79
84
  end
80
85
  end
86
+
87
+ module ElasticsearchTransportClientInstrumentationPrepend
88
+ def perform_request(*args, &block)
89
+ name = _sanitize_name(args[1])
90
+
91
+ self.class.instrument("Elasticsearch", name, :ignore_children => true) do
92
+ super(*args, &block)
93
+ end
94
+ end
95
+
96
+ def _sanitize_name(name)
97
+ name = name.split("/").last.gsub(/^_/, '')
98
+ allowed_names = ["bench",
99
+ "bulk",
100
+ "count",
101
+ "exists",
102
+ "explain",
103
+ "field_stats",
104
+ "health",
105
+ "mget",
106
+ "mlt",
107
+ "mpercolate",
108
+ "msearch",
109
+ "mtermvectors",
110
+ "percolate",
111
+ "query",
112
+ "scroll",
113
+ "search_shards",
114
+ "source",
115
+ "suggest",
116
+ "template",
117
+ "termvectors",
118
+ "update",
119
+ "search", ]
120
+
121
+ if allowed_names.include?(name)
122
+ name
123
+ else
124
+ "Unknown"
125
+ end
126
+ rescue
127
+ "Unknown"
128
+ end
129
+ end
81
130
  end
82
131
  end
83
132
 
@@ -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?(::Grape) && defined?(::Grape::Endpoint)
21
21
  @installed = true
22
22
 
@@ -16,33 +16,53 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  if defined?(::HTTP) && defined?(::HTTP::Client)
21
21
  @installed = true
22
22
 
23
- logger.info "Instrumenting HTTP::Client"
23
+ logger.info "Instrumenting HTTP::Client. Prepend: #{prepend}"
24
24
 
25
- ::HTTP::Client.class_eval do
26
- include ScoutApm::Tracer
25
+ if prepend
26
+ ::HTTP::Client.send(:include, ScoutApm::Tracer)
27
+ ::HTTP::Client.send(:prepend, HTTPInstrumentationPrepend)
28
+ else
29
+ ::HTTP::Client.class_eval do
30
+ include ScoutApm::Tracer
27
31
 
28
- def request_with_scout_instruments(verb, uri, opts = {})
29
- self.class.instrument("HTTP", verb, :ignore_children => true, :desc => request_scout_description(verb, uri)) do
30
- request_without_scout_instruments(verb, uri, opts)
32
+ def request_with_scout_instruments(verb, uri, opts = {})
33
+ self.class.instrument("HTTP", verb, :ignore_children => true, :desc => request_scout_description(verb, uri)) do
34
+ request_without_scout_instruments(verb, uri, opts)
35
+ end
31
36
  end
32
- end
33
37
 
34
- def request_scout_description(verb, uri)
35
- max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
36
- (String(uri).split('?').first)[0..(max_length - 1)]
37
- rescue
38
- ""
39
- end
38
+ def request_scout_description(verb, uri)
39
+ max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
40
+ (String(uri).split('?').first)[0..(max_length - 1)]
41
+ rescue
42
+ ""
43
+ end
40
44
 
41
- alias request_without_scout_instruments request
42
- alias request request_with_scout_instruments
45
+ alias request_without_scout_instruments request
46
+ alias request request_with_scout_instruments
47
+ end
43
48
  end
44
49
  end
45
50
  end
46
51
  end
52
+
53
+ module HTTPInstrumentationPrepend
54
+ def request(verb, uri, opts = {})
55
+ self.class.instrument("HTTP", verb, :ignore_children => true, :desc => request_scout_description(verb, uri)) do
56
+ super(verb, uri, opts)
57
+ end
58
+ end
59
+
60
+ def request_scout_description(verb, uri)
61
+ max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
62
+ (String(uri).split('?').first)[0..(max_length - 1)]
63
+ rescue
64
+ ""
65
+ end
66
+ end
47
67
  end
48
68
  end
@@ -16,33 +16,52 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  if defined?(::HTTPClient)
21
21
  @installed = true
22
22
 
23
- logger.info "Instrumenting HTTPClient"
23
+ logger.info "Instrumenting HTTPClient. Prepend: #{prepend}"
24
24
 
25
- ::HTTPClient.class_eval do
26
- include ScoutApm::Tracer
25
+ if prepend
26
+ ::HTTPClient.send(:include, ScoutApm::Tracer)
27
+ ::HTTPClient.send(:prepend, HttpClientInstrumentationPrepend)
28
+ else
29
+ ::HTTPClient.class_eval do
30
+ include ScoutApm::Tracer
27
31
 
28
- def request_with_scout_instruments(*args, &block)
32
+ def request_with_scout_instruments(*args, &block)
29
33
 
30
- method = args[0].to_s
31
- url = args[1]
34
+ method = args[0].to_s
35
+ url = args[1]
32
36
 
33
- max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
34
- url = url && url.to_s[0..(max_length - 1)]
37
+ max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
38
+ url = url && url.to_s[0..(max_length - 1)]
35
39
 
36
- self.class.instrument("HTTP", method, :desc => url) do
37
- request_without_scout_instruments(*args, &block)
40
+ self.class.instrument("HTTP", method, :desc => url) do
41
+ request_without_scout_instruments(*args, &block)
42
+ end
38
43
  end
39
- end
40
44
 
41
- alias request_without_scout_instruments request
42
- alias request request_with_scout_instruments
45
+ alias request_without_scout_instruments request
46
+ alias request request_with_scout_instruments
47
+ end
43
48
  end
44
49
  end
45
50
  end
46
51
  end
52
+
53
+ module HttpClientInstrumentationPrepend
54
+ def request(*args, &block)
55
+ method = args[0].to_s
56
+ url = args[1]
57
+
58
+ max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
59
+ url = url && url.to_s[0..(max_length - 1)]
60
+
61
+ self.class.instrument("HTTP", method, :desc => url) do
62
+ super(*args, &block)
63
+ end
64
+ end
65
+ end
47
66
  end
48
67
  end
@@ -16,11 +16,11 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  if defined?(::InfluxDB)
21
21
  @installed = true
22
22
 
23
- logger.debug "Instrumenting InfluxDB"
23
+ logger.debug "Instrumenting InfluxDB."
24
24
 
25
25
  ::InfluxDB::Client.class_eval do
26
26
  include ScoutApm::Tracer
@@ -16,28 +16,43 @@ module ScoutApm
16
16
  @installed
17
17
  end
18
18
 
19
- def install
19
+ def install(prepend:)
20
20
  if defined?(::Dalli) && defined?(::Dalli::Client)
21
21
  @installed = true
22
22
 
23
- logger.info "Instrumenting Memcached"
23
+ logger.info "Instrumenting Memcached. Prepend: #{prepend}"
24
24
 
25
- ::Dalli::Client.class_eval do
26
- include ScoutApm::Tracer
25
+ if prepend
26
+ ::Dalli::Client.send(:include, ScoutApm::Tracer)
27
+ ::Dalli::Client.send(:prepend, MemcachedInstrumentationPrepend)
28
+ else
29
+ ::Dalli::Client.class_eval do
30
+ include ScoutApm::Tracer
27
31
 
28
- def perform_with_scout_instruments(*args, &block)
29
- command = args.first rescue "Unknown"
32
+ def perform_with_scout_instruments(*args, &block)
33
+ command = args.first rescue "Unknown"
30
34
 
31
- self.class.instrument("Memcached", command) do
32
- perform_without_scout_instruments(*args, &block)
35
+ self.class.instrument("Memcached", command) do
36
+ perform_without_scout_instruments(*args, &block)
37
+ end
33
38
  end
34
- end
35
39
 
36
- alias_method :perform_without_scout_instruments, :perform
37
- alias_method :perform, :perform_with_scout_instruments
40
+ alias_method :perform_without_scout_instruments, :perform
41
+ alias_method :perform, :perform_with_scout_instruments
42
+ end
38
43
  end
39
44
  end
40
45
  end
41
46
  end
47
+
48
+ module MemcachedInstrumentationPrepend
49
+ def perform(*args, &block)
50
+ command = args.first rescue "Unknown"
51
+
52
+ self.class.instrument("Memcached", command) do
53
+ super(*args, &block)
54
+ end
55
+ end
56
+ end
42
57
  end
43
58
  end
@@ -24,7 +24,7 @@ module ScoutApm
24
24
  @installed
25
25
  end
26
26
 
27
- def install
27
+ def install(prepend:)
28
28
  if defined?(ActionDispatch) && defined?(ActionDispatch::MiddlewareStack) && defined?(ActionDispatch::MiddlewareStack::Middleware)
29
29
  @installed = true
30
30
 
@@ -21,7 +21,7 @@ module ScoutApm
21
21
  @installed
22
22
  end
23
23
 
24
- def install
24
+ def install(prepend:)
25
25
  if defined?(ActionDispatch) && defined?(ActionDispatch::MiddlewareStack)
26
26
  @installed = true
27
27