scout_apm 3.0.0.pre27 → 4.0.3

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 (131) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/test.yml +49 -0
  3. data/.gitignore +1 -1
  4. data/.rubocop.yml +5 -5
  5. data/.travis.yml +19 -14
  6. data/CHANGELOG.markdown +139 -4
  7. data/Gemfile +1 -7
  8. data/README.markdown +13 -4
  9. data/Rakefile +1 -1
  10. data/ext/allocations/allocations.c +2 -0
  11. data/gems/README.md +28 -0
  12. data/gems/octoshark.gemfile +4 -0
  13. data/gems/rails3.gemfile +5 -0
  14. data/gems/rails4.gemfile +4 -0
  15. data/gems/rails5.gemfile +4 -0
  16. data/gems/rails6.gemfile +4 -0
  17. data/lib/scout_apm.rb +38 -9
  18. data/lib/scout_apm/agent.rb +29 -10
  19. data/lib/scout_apm/agent/exit_handler.rb +0 -1
  20. data/lib/scout_apm/agent_context.rb +22 -3
  21. data/lib/scout_apm/app_server_load.rb +7 -2
  22. data/lib/scout_apm/attribute_arranger.rb +0 -2
  23. data/lib/scout_apm/auto_instrument.rb +5 -0
  24. data/lib/scout_apm/auto_instrument/instruction_sequence.rb +31 -0
  25. data/lib/scout_apm/auto_instrument/layer.rb +23 -0
  26. data/lib/scout_apm/auto_instrument/parser.rb +27 -0
  27. data/lib/scout_apm/auto_instrument/rails.rb +175 -0
  28. data/lib/scout_apm/background_job_integrations/legacy_sneakers.rb +55 -0
  29. data/lib/scout_apm/background_job_integrations/que.rb +134 -0
  30. data/lib/scout_apm/background_job_integrations/resque.rb +6 -2
  31. data/lib/scout_apm/background_job_integrations/shoryuken.rb +124 -0
  32. data/lib/scout_apm/background_job_integrations/sidekiq.rb +5 -19
  33. data/lib/scout_apm/background_job_integrations/sneakers.rb +87 -0
  34. data/lib/scout_apm/config.rb +45 -8
  35. data/lib/scout_apm/detailed_trace.rb +217 -0
  36. data/lib/scout_apm/environment.rb +19 -1
  37. data/lib/scout_apm/error.rb +27 -0
  38. data/lib/scout_apm/error_service.rb +32 -0
  39. data/lib/scout_apm/error_service/error_buffer.rb +39 -0
  40. data/lib/scout_apm/error_service/error_record.rb +211 -0
  41. data/lib/scout_apm/error_service/ignored_exceptions.rb +66 -0
  42. data/lib/scout_apm/error_service/middleware.rb +32 -0
  43. data/lib/scout_apm/error_service/notifier.rb +33 -0
  44. data/lib/scout_apm/error_service/payload.rb +47 -0
  45. data/lib/scout_apm/error_service/periodic_work.rb +17 -0
  46. data/lib/scout_apm/error_service/railtie.rb +11 -0
  47. data/lib/scout_apm/error_service/sidekiq.rb +80 -0
  48. data/lib/scout_apm/extensions/transaction_callback_payload.rb +1 -1
  49. data/lib/scout_apm/fake_store.rb +3 -0
  50. data/lib/scout_apm/framework_integrations/rails_2.rb +2 -1
  51. data/lib/scout_apm/framework_integrations/rails_3_or_4.rb +3 -1
  52. data/lib/scout_apm/git_revision.rb +6 -3
  53. data/lib/scout_apm/instant/middleware.rb +2 -1
  54. data/lib/scout_apm/instrument_manager.rb +9 -7
  55. data/lib/scout_apm/instruments/action_controller_rails_2.rb +3 -1
  56. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +56 -55
  57. data/lib/scout_apm/instruments/action_view.rb +122 -26
  58. data/lib/scout_apm/instruments/active_record.rb +66 -18
  59. data/lib/scout_apm/instruments/http.rb +48 -0
  60. data/lib/scout_apm/instruments/memcached.rb +43 -0
  61. data/lib/scout_apm/instruments/mongoid.rb +9 -4
  62. data/lib/scout_apm/instruments/net_http.rb +8 -1
  63. data/lib/scout_apm/instruments/typhoeus.rb +88 -0
  64. data/lib/scout_apm/job_record.rb +4 -2
  65. data/lib/scout_apm/layaway_file.rb +4 -0
  66. data/lib/scout_apm/layer.rb +6 -57
  67. data/lib/scout_apm/layer_children_set.rb +9 -8
  68. data/lib/scout_apm/layer_converters/converter_base.rb +15 -30
  69. data/lib/scout_apm/layer_converters/slow_job_converter.rb +12 -2
  70. data/lib/scout_apm/layer_converters/slow_request_converter.rb +14 -4
  71. data/lib/scout_apm/layer_converters/trace_converter.rb +184 -0
  72. data/lib/scout_apm/limited_layer.rb +0 -7
  73. data/lib/scout_apm/metric_stats.rb +0 -8
  74. data/lib/scout_apm/middleware.rb +1 -1
  75. data/lib/scout_apm/periodic_work.rb +19 -0
  76. data/lib/scout_apm/remote/message.rb +4 -0
  77. data/lib/scout_apm/remote/server.rb +13 -1
  78. data/lib/scout_apm/reporter.rb +8 -3
  79. data/lib/scout_apm/reporting.rb +2 -1
  80. data/lib/scout_apm/request_histograms.rb +8 -0
  81. data/lib/scout_apm/serializers/app_server_load_serializer.rb +4 -0
  82. data/lib/scout_apm/serializers/directive_serializer.rb +4 -0
  83. data/lib/scout_apm/serializers/payload_serializer.rb +2 -2
  84. data/lib/scout_apm/serializers/payload_serializer_to_json.rb +30 -15
  85. data/lib/scout_apm/slow_job_record.rb +5 -1
  86. data/lib/scout_apm/slow_policy/age_policy.rb +33 -0
  87. data/lib/scout_apm/slow_policy/percent_policy.rb +22 -0
  88. data/lib/scout_apm/slow_policy/percentile_policy.rb +24 -0
  89. data/lib/scout_apm/slow_policy/policy.rb +21 -0
  90. data/lib/scout_apm/slow_policy/speed_policy.rb +16 -0
  91. data/lib/scout_apm/slow_request_policy.rb +18 -77
  92. data/lib/scout_apm/slow_transaction.rb +3 -1
  93. data/lib/scout_apm/store.rb +0 -1
  94. data/lib/scout_apm/tracked_request.rb +39 -30
  95. data/lib/scout_apm/utils/backtrace_parser.rb +3 -0
  96. data/lib/scout_apm/utils/marshal_logging.rb +90 -0
  97. data/lib/scout_apm/utils/sql_sanitizer.rb +10 -1
  98. data/lib/scout_apm/utils/sql_sanitizer_regex.rb +8 -1
  99. data/lib/scout_apm/utils/sql_sanitizer_regex_1_8_7.rb +6 -0
  100. data/lib/scout_apm/utils/unique_id.rb +27 -0
  101. data/lib/scout_apm/version.rb +1 -1
  102. data/scout_apm.gemspec +13 -7
  103. data/test/test_helper.rb +2 -2
  104. data/test/unit/agent_context_test.rb +29 -0
  105. data/test/unit/auto_instrument/assignments-instrumented.rb +31 -0
  106. data/test/unit/auto_instrument/assignments.rb +31 -0
  107. data/test/unit/auto_instrument/controller-ast.txt +57 -0
  108. data/test/unit/auto_instrument/controller-instrumented.rb +49 -0
  109. data/test/unit/auto_instrument/controller.rb +49 -0
  110. data/test/unit/auto_instrument/rescue_from-instrumented.rb +13 -0
  111. data/test/unit/auto_instrument/rescue_from.rb +13 -0
  112. data/test/unit/auto_instrument_test.rb +54 -0
  113. data/test/unit/environment_test.rb +2 -2
  114. data/test/unit/error_service/error_buffer_test.rb +25 -0
  115. data/test/unit/error_service/ignored_exceptions_test.rb +49 -0
  116. data/test/unit/instruments/active_record_test.rb +40 -0
  117. data/test/unit/layer_children_set_test.rb +9 -0
  118. data/test/unit/request_histograms_test.rb +17 -0
  119. data/test/unit/serializers/payload_serializer_test.rb +39 -5
  120. data/test/unit/slow_request_policy_test.rb +41 -13
  121. data/test/unit/sql_sanitizer_test.rb +78 -0
  122. metadata +101 -62
  123. data/ext/stacks/extconf.rb +0 -37
  124. data/ext/stacks/scout_atomics.h +0 -86
  125. data/ext/stacks/stacks.c +0 -814
  126. data/lib/scout_apm/slow_job_policy.rb +0 -111
  127. data/lib/scout_apm/trace_compactor.rb +0 -312
  128. data/lib/scout_apm/utils/fake_stacks.rb +0 -88
  129. data/test/unit/instruments/active_record_instruments_test.rb +0 -5
  130. data/test/unit/slow_job_policy_test.rb +0 -6
  131. data/tester.rb +0 -53
@@ -1,6 +1,14 @@
1
+ # Note, this instrument has the same logic in both Tracer and Module Prepend
2
+ # versions. If you update, be sure you update in both spots.
3
+ #
4
+ # The prepend version was added for Rails 6 support - ActiveRecord prepends on
5
+ # top of PartialRenderer#collection_with_template, which can (and does) cause
6
+ # infinite loops with our alias_method approach.
7
+ #
8
+ # Even though Rails 6 forced us to use a prepend version, it is now used for
9
+ # all Rubies that support it.
1
10
  module ScoutApm
2
11
  module Instruments
3
- # instrumentation for Rails 3 and Rails 4 is the same.
4
12
  class ActionView
5
13
  attr_reader :context
6
14
 
@@ -17,37 +25,125 @@ module ScoutApm
17
25
  @installed
18
26
  end
19
27
 
28
+ def prependable?
29
+ context.environment.supports_module_prepend?
30
+ end
31
+
20
32
  def install
21
- if defined?(::ActionView) && defined?(::ActionView::PartialRenderer)
22
- @installed = true
23
-
24
- logger.info "Instrumenting ActionView::PartialRenderer"
25
- ::ActionView::PartialRenderer.class_eval do
26
- include ScoutApm::Tracer
27
-
28
- instrument_method :render_partial,
29
- :type => "View",
30
- :name => '#{@template.virtual_path rescue "Unknown Partial"}/Rendering',
31
- :scope => true
32
-
33
- instrument_method :collection_with_template,
34
- :type => "View",
35
- :name => '#{@template.virtual_path rescue "Unknown Collection"}/Rendering',
36
- :scope => true
33
+ return unless defined?(::ActionView) && defined?(::ActionView::PartialRenderer)
34
+
35
+ if prependable?
36
+ install_using_prepend
37
+ else
38
+ install_using_tracer
39
+ end
40
+ @installed = true
41
+ end
42
+
43
+ def install_using_tracer
44
+ logger.info "Instrumenting ActionView::PartialRenderer"
45
+ ::ActionView::PartialRenderer.class_eval do
46
+ include ScoutApm::Tracer
47
+
48
+ instrument_method :render_partial,
49
+ :type => "View",
50
+ :name => '#{@template.virtual_path rescue "Unknown Partial"}/Rendering',
51
+ :scope => true
52
+
53
+ instrument_method :collection_with_template,
54
+ :type => "View",
55
+ :name => '#{@template.virtual_path rescue "Unknown Collection"}/Rendering',
56
+ :scope => true
57
+ end
58
+
59
+ logger.info "Instrumenting ActionView::TemplateRenderer"
60
+ ::ActionView::TemplateRenderer.class_eval do
61
+ include ScoutApm::Tracer
62
+ instrument_method :render_template,
63
+ :type => "View",
64
+ :name => '#{args[0].virtual_path rescue "Unknown"}/Rendering',
65
+ :scope => true
66
+ end
67
+ end
68
+
69
+ def install_using_prepend
70
+ logger.info "Instrumenting ActionView::PartialRenderer"
71
+ ::ActionView::PartialRenderer.prepend(ActionViewPartialRendererInstruments)
72
+
73
+ logger.info "Instrumenting ActionView::TemplateRenderer"
74
+ ::ActionView::TemplateRenderer.prepend(ActionViewTemplateRendererInstruments)
75
+ end
76
+
77
+ module ActionViewPartialRendererInstruments
78
+ # In Rails 6, the signature changed to pass the view & template args directly, as opposed to through the instance var
79
+ # New signature is: def render_partial(view, template)
80
+ def render_partial(*args, **kwargs)
81
+ req = ScoutApm::RequestManager.lookup
82
+
83
+ maybe_template = args[1]
84
+
85
+ template_name = @template.virtual_path rescue nil # Works on Rails 3.2 -> end of Rails 5 series
86
+ template_name ||= maybe_template.virtual_path rescue nil # Works on Rails 6 -> 6.0.3
87
+ template_name ||= "Unknown Partial"
88
+
89
+ layer_name = template_name + "/Rendering"
90
+ layer = ScoutApm::Layer.new("View", layer_name)
91
+ layer.subscopable!
92
+
93
+ begin
94
+ req.start_layer(layer)
95
+ if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?
96
+ super(*args, **kwargs)
97
+ else
98
+ super(*args)
99
+ end
100
+ ensure
101
+ req.stop_layer
102
+ end
103
+ end
104
+
105
+ def collection_with_template(*args, **kwargs)
106
+ req = ScoutApm::RequestManager.lookup
107
+
108
+ template_name = @template.virtual_path rescue "Unknown Collection"
109
+ template_name ||= "Unknown Collection"
110
+ layer_name = template_name + "/Rendering"
111
+
112
+ layer = ScoutApm::Layer.new("View", layer_name)
113
+ layer.subscopable!
114
+
115
+ begin
116
+ req.start_layer(layer)
117
+ if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?
118
+ super(*args, **kwargs)
119
+ else
120
+ super(*args)
121
+ end
122
+ ensure
123
+ req.stop_layer
37
124
  end
125
+ end
126
+ end
127
+
128
+ module ActionViewTemplateRendererInstruments
129
+ def render_template(*args, **kwargs)
130
+ req = ScoutApm::RequestManager.lookup
38
131
 
39
- logger.info "Instrumenting ActionView::TemplateRenderer"
40
- ::ActionView::TemplateRenderer.class_eval do
41
- include ScoutApm::Tracer
42
- instrument_method :render_template,
43
- :type => "View",
44
- :name => '#{args[0].virtual_path rescue "Unknown"}/Rendering',
45
- :scope => true
132
+ template_name = args[0].virtual_path rescue "Unknown"
133
+ template_name ||= "Unknown"
134
+ layer_name = template_name + "/Rendering"
135
+
136
+ layer = ScoutApm::Layer.new("View", layer_name)
137
+ layer.subscopable!
138
+
139
+ begin
140
+ req.start_layer(layer)
141
+ super(*args, **kwargs)
142
+ ensure
143
+ req.stop_layer
46
144
  end
47
145
  end
48
146
  end
49
147
  end
50
148
  end
51
149
  end
52
-
53
-
@@ -82,10 +82,8 @@ module ScoutApm
82
82
 
83
83
  # Install #log tracing
84
84
  if Utils::KlassHelper.defined?("ActiveRecord::ConnectionAdapters::AbstractAdapter")
85
- ::ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
86
- include ::ScoutApm::Instruments::ActiveRecordInstruments
87
- include ::ScoutApm::Tracer
88
- end
85
+ ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecordInstruments)
86
+ ::ActiveRecord::ConnectionAdapters::AbstractAdapter.include(Tracer)
89
87
  end
90
88
 
91
89
  if Utils::KlassHelper.defined?("ActiveRecord::Base")
@@ -168,17 +166,63 @@ module ScoutApm
168
166
  #
169
167
  ################################################################################
170
168
  module ActiveRecordInstruments
171
- def self.included(instrumented_class)
169
+ def self.prepended(instrumented_class)
172
170
  ScoutApm::Agent.instance.context.logger.info "Instrumenting #{instrumented_class.inspect}"
173
- instrumented_class.class_eval do
174
- unless instrumented_class.method_defined?(:log_without_scout_instruments)
175
- alias_method :log_without_scout_instruments, :log
176
- alias_method :log, :log_with_scout_instruments
171
+ end
172
+
173
+ def log(*args, &block)
174
+ # Extract data from the arguments
175
+ sql, name = args
176
+ metric_name = Utils::ActiveRecordMetricName.new(sql, name)
177
+ desc = SqlList.new(sql)
178
+
179
+ # Get current ScoutApm context
180
+ req = ScoutApm::RequestManager.lookup
181
+ current_layer = req.current_layer
182
+
183
+ # If we call #log, we have a real query to run, and we've already
184
+ # gotten through the cache gatekeeper. Since we want to only trace real
185
+ # queries, and not repeated identical queries that just hit cache, we
186
+ # mark layer as ignorable initially in #find_by_sql, then only when we
187
+ # know it's a real database call do we mark it back as usable.
188
+ #
189
+ # This flag is later used in SlowRequestConverter to skip adding ignorable layers
190
+ current_layer.annotate_layer(:ignorable => false) if current_layer
191
+
192
+ # Either: update the current layer and yield, don't start a new one.
193
+ if current_layer && current_layer.type == "ActiveRecord"
194
+ # TODO: Get rid of call .to_s, need to find this without forcing a previous run of the name logic
195
+ if current_layer.name.to_s == Utils::ActiveRecordMetricName::DEFAULT_METRIC
196
+ current_layer.name = metric_name
197
+ end
198
+
199
+ if current_layer.desc.nil?
200
+ current_layer.desc = SqlList.new
201
+ end
202
+ current_layer.desc.merge(desc)
203
+
204
+ super(*args, &block)
205
+
206
+ # OR: Start a new layer, we didn't pick up instrumentation earlier in the stack.
207
+ else
208
+ layer = ScoutApm::Layer.new("ActiveRecord", metric_name)
209
+ layer.desc = desc
210
+ req.start_layer(layer)
211
+ begin
212
+ super(*args, &block)
213
+ ensure
214
+ req.stop_layer
177
215
  end
178
216
  end
179
217
  end
218
+ end
180
219
 
181
- def log_with_scout_instruments(*args, &block)
220
+ module ActiveRecordInstruments
221
+ def self.prepended(instrumented_class)
222
+ ScoutApm::Agent.instance.context.logger.info "Instrumenting #{instrumented_class.inspect}"
223
+ end
224
+
225
+ def log(*args, &block)
182
226
  # Extract data from the arguments
183
227
  sql, name = args
184
228
  metric_name = Utils::ActiveRecordMetricName.new(sql, name)
@@ -209,7 +253,7 @@ module ScoutApm
209
253
  end
210
254
  current_layer.desc.merge(desc)
211
255
 
212
- log_without_scout_instruments(*args, &block)
256
+ super(*args, &block)
213
257
 
214
258
  # OR: Start a new layer, we didn't pick up instrumentation earlier in the stack.
215
259
  else
@@ -217,7 +261,7 @@ module ScoutApm
217
261
  layer.desc = desc
218
262
  req.start_layer(layer)
219
263
  begin
220
- log_without_scout_instruments(*args, &block)
264
+ super(*args, &block)
221
265
  ensure
222
266
  req.stop_layer
223
267
  end
@@ -264,14 +308,18 @@ module ScoutApm
264
308
  end
265
309
  end
266
310
 
267
- def find_by_sql_with_scout_instruments(*args, &block)
311
+ def find_by_sql_with_scout_instruments(*args, **kwargs, &block)
268
312
  req = ScoutApm::RequestManager.lookup
269
313
  layer = ScoutApm::Layer.new("ActiveRecord", Utils::ActiveRecordMetricName::DEFAULT_METRIC)
270
314
  layer.annotate_layer(:ignorable => true)
271
315
  req.start_layer(layer)
272
316
  req.ignore_children!
273
317
  begin
274
- find_by_sql_without_scout_instruments(*args, &block)
318
+ if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?
319
+ find_by_sql_without_scout_instruments(*args, **kwargs, &block)
320
+ else
321
+ find_by_sql_without_scout_instruments(*args, &block)
322
+ end
275
323
  ensure
276
324
  req.acknowledge_children!
277
325
  req.stop_layer
@@ -349,7 +397,7 @@ module ScoutApm
349
397
  end
350
398
 
351
399
  module ActiveRecordUpdateInstruments
352
- def save(*args, &block)
400
+ def save(*args, **options, &block)
353
401
  model = self.class.name
354
402
  operation = self.persisted? ? "Update" : "Create"
355
403
 
@@ -359,14 +407,14 @@ module ScoutApm
359
407
  req.start_layer(layer)
360
408
  req.ignore_children!
361
409
  begin
362
- super(*args, &block)
410
+ super(*args, **options, &block)
363
411
  ensure
364
412
  req.acknowledge_children!
365
413
  req.stop_layer
366
414
  end
367
415
  end
368
416
 
369
- def save!(*args, &block)
417
+ def save!(*args, **options, &block)
370
418
  model = self.class.name
371
419
  operation = self.persisted? ? "Update" : "Create"
372
420
 
@@ -375,7 +423,7 @@ module ScoutApm
375
423
  req.start_layer(layer)
376
424
  req.ignore_children!
377
425
  begin
378
- super(*args, &block)
426
+ super(*args, **options, &block)
379
427
  ensure
380
428
  req.acknowledge_children!
381
429
  req.stop_layer
@@ -0,0 +1,48 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ class HTTP
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
20
+ if defined?(::HTTP) && defined?(::HTTP::Client)
21
+ @installed = true
22
+
23
+ logger.info "Instrumenting HTTP::Client"
24
+
25
+ ::HTTP::Client.class_eval do
26
+ include ScoutApm::Tracer
27
+
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)
31
+ end
32
+ end
33
+
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
40
+
41
+ alias request_without_scout_instruments request
42
+ alias request request_with_scout_instruments
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,43 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ class Memcached
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
20
+ if defined?(::Dalli) && defined?(::Dalli::Client)
21
+ @installed = true
22
+
23
+ logger.info "Instrumenting Memcached"
24
+
25
+ ::Dalli::Client.class_eval do
26
+ include ScoutApm::Tracer
27
+
28
+ def perform_with_scout_instruments(*args, &block)
29
+ command = args.first rescue "Unknown"
30
+
31
+ self.class.instrument("Memcached", command) do
32
+ perform_without_scout_instruments(*args, &block)
33
+ end
34
+ end
35
+
36
+ alias_method :perform_without_scout_instruments, :perform
37
+ alias_method :perform, :perform_with_scout_instruments
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -37,8 +37,8 @@ module ScoutApm
37
37
  ### See moped instrument for Moped driven deploys
38
38
 
39
39
  ### 5.x Mongoid
40
- if (mongoid_v5? || mongoid_v6?) && defined?(::Mongoid::Contextual::Mongo)
41
- logger.info "Instrumenting Mongoid 5.x/6.x"
40
+ if (mongoid_v5? || mongoid_v6? || mongoid_v7?) && defined?(::Mongoid::Contextual::Mongo)
41
+ logger.info "Instrumenting Mongoid 5.x/6.x/7.x"
42
42
  # All the public methods from Mongoid::Contextual::Mongo.
43
43
  # TODO: Geo and MapReduce support (?). They are in other Contextual::* classes
44
44
  methods = [
@@ -54,8 +54,6 @@ module ScoutApm
54
54
  if ::Mongoid::Contextual::Mongo.method_defined?(method)
55
55
  with_scout_instruments = %Q[
56
56
  def #{method}_with_scout_instruments(*args, &block)
57
-
58
-
59
57
  req = ScoutApm::RequestManager.lookup
60
58
  *db, collection = view.collection.namespace.split(".")
61
59
 
@@ -112,6 +110,13 @@ module ScoutApm
112
110
  end
113
111
  end
114
112
 
113
+ def mongoid_v7?
114
+ if defined?(::Mongoid::VERSION)
115
+ ::Mongoid::VERSION =~ /\A7/
116
+ else
117
+ false
118
+ end
119
+ end
115
120
 
116
121
  # Example of what a filter looks like: => {"founded"=>{"$gte"=>"1980-1-1"}, "name"=>{"$in"=>["Tool", "Deftones", "Melvins"]}}
117
122
  # Approach: find every leaf-node, clear it. inspect the whole thing when done.
@@ -25,7 +25,7 @@ module ScoutApm
25
25
  ::Net::HTTP.class_eval do
26
26
  include ScoutApm::Tracer
27
27
 
28
- def request_with_scout_instruments(*args,&block)
28
+ def request_with_scout_instruments(*args, &block)
29
29
  self.class.instrument("HTTP", "request", :ignore_children => true, :desc => request_scout_description(args.first)) do
30
30
  request_without_scout_instruments(*args, &block)
31
31
  end
@@ -35,8 +35,15 @@ module ScoutApm
35
35
  path = req.path
36
36
  path = path.path if path.respond_to?(:path)
37
37
 
38
+ # Protect against a nil address value
39
+ if @address.nil?
40
+ return "No Address Found"
41
+ end
42
+
38
43
  max_length = ScoutApm::Agent.instance.context.config.value('instrument_http_url_length')
39
44
  (@address + path.split('?').first)[0..(max_length - 1)]
45
+ rescue
46
+ ""
40
47
  end
41
48
 
42
49
  alias request_without_scout_instruments request