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
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