scout_apm 2.3.5 → 2.4.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +0 -23
- data/lib/scout_apm.rb +21 -10
- data/lib/scout_apm/agent.rb +98 -336
- data/lib/scout_apm/agent/exit_handler.rb +64 -0
- data/lib/scout_apm/agent/preconditions.rb +69 -0
- data/lib/scout_apm/agent_context.rb +226 -0
- data/lib/scout_apm/app_server_load.rb +20 -18
- data/lib/scout_apm/background_job_integrations/resque.rb +7 -8
- data/lib/scout_apm/background_job_integrations/sidekiq.rb +2 -8
- data/lib/scout_apm/background_recorder.rb +8 -3
- data/lib/scout_apm/background_worker.rb +14 -7
- data/lib/scout_apm/config.rb +35 -29
- data/lib/scout_apm/context.rb +11 -4
- data/lib/scout_apm/db_query_metric_set.rb +17 -5
- data/lib/scout_apm/debug.rb +1 -1
- data/lib/scout_apm/environment.rb +10 -14
- data/lib/scout_apm/framework_integrations/sinatra.rb +1 -1
- data/lib/scout_apm/git_revision.rb +13 -8
- data/lib/scout_apm/histogram.rb +1 -1
- data/lib/scout_apm/instant/middleware.rb +7 -7
- data/lib/scout_apm/instant_reporting.rb +7 -7
- data/lib/scout_apm/instrument_manager.rb +87 -0
- data/lib/scout_apm/instruments/action_controller_rails_2.rb +12 -7
- data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +16 -11
- data/lib/scout_apm/instruments/action_view.rb +11 -7
- data/lib/scout_apm/instruments/active_record.rb +28 -51
- data/lib/scout_apm/instruments/elasticsearch.rb +10 -6
- data/lib/scout_apm/instruments/grape.rb +12 -8
- data/lib/scout_apm/instruments/http_client.rb +11 -10
- data/lib/scout_apm/instruments/influxdb.rb +10 -6
- data/lib/scout_apm/instruments/middleware_detailed.rb +11 -5
- data/lib/scout_apm/instruments/middleware_summary.rb +11 -5
- data/lib/scout_apm/instruments/mongoid.rb +10 -5
- data/lib/scout_apm/instruments/moped.rb +11 -6
- data/lib/scout_apm/instruments/net_http.rb +11 -9
- data/lib/scout_apm/instruments/percentile_sampler.rb +8 -6
- data/lib/scout_apm/instruments/process/process_cpu.rb +8 -4
- data/lib/scout_apm/instruments/process/process_memory.rb +15 -10
- data/lib/scout_apm/instruments/rails_router.rb +12 -6
- data/lib/scout_apm/instruments/redis.rb +10 -6
- data/lib/scout_apm/instruments/samplers.rb +11 -0
- data/lib/scout_apm/instruments/sinatra.rb +5 -4
- data/lib/scout_apm/layaway.rb +26 -39
- data/lib/scout_apm/layaway_file.rb +8 -3
- data/lib/scout_apm/layer.rb +1 -1
- data/lib/scout_apm/layer_converters/converter_base.rb +4 -2
- data/lib/scout_apm/layer_converters/database_converter.rb +1 -1
- data/lib/scout_apm/layer_converters/histograms.rb +2 -2
- data/lib/scout_apm/layer_converters/slow_job_converter.rb +4 -3
- data/lib/scout_apm/layer_converters/slow_request_converter.rb +5 -4
- data/lib/scout_apm/logger.rb +143 -0
- data/lib/scout_apm/middleware.rb +7 -9
- data/lib/scout_apm/periodic_work.rb +28 -0
- data/lib/scout_apm/remote/server.rb +0 -2
- data/lib/scout_apm/reporter.rb +14 -8
- data/lib/scout_apm/reporting.rb +135 -0
- data/lib/scout_apm/request_manager.rb +4 -7
- data/lib/scout_apm/serializers/payload_serializer.rb +1 -1
- data/lib/scout_apm/slow_job_policy.rb +6 -2
- data/lib/scout_apm/slow_job_record.rb +5 -5
- data/lib/scout_apm/slow_request_policy.rb +6 -2
- data/lib/scout_apm/slow_transaction.rb +5 -5
- data/lib/scout_apm/store.rb +22 -16
- data/lib/scout_apm/synchronous_recorder.rb +7 -3
- data/lib/scout_apm/tasks/doctor.rb +75 -0
- data/lib/scout_apm/tasks/support.rb +22 -0
- data/lib/scout_apm/tracer.rb +5 -5
- data/lib/scout_apm/tracked_request.rb +23 -35
- data/lib/scout_apm/utils/backtrace_parser.rb +1 -1
- data/lib/scout_apm/utils/installed_gems.rb +7 -3
- data/lib/scout_apm/utils/klass_helper.rb +8 -2
- data/lib/scout_apm/utils/scm.rb +1 -1
- data/lib/scout_apm/utils/sql_sanitizer.rb +4 -6
- data/lib/scout_apm/version.rb +1 -1
- data/lib/tasks/doctor.rake +11 -0
- data/test/test_helper.rb +15 -2
- data/test/unit/agent_test.rb +1 -54
- data/test/unit/config_test.rb +9 -5
- data/test/unit/context_test.rb +4 -4
- data/test/unit/db_query_metric_set_test.rb +11 -4
- data/test/unit/fake_store_test.rb +1 -1
- data/test/unit/git_revision_test.rb +3 -3
- data/test/unit/instruments/net_http_test.rb +2 -1
- data/test/unit/instruments/percentile_sampler_test.rb +5 -9
- data/test/unit/layaway_test.rb +10 -5
- data/test/unit/layer_converters/metric_converter_test.rb +2 -2
- data/test/unit/slow_request_policy_test.rb +7 -3
- data/test/unit/sql_sanitizer_test.rb +0 -6
- data/test/unit/store_test.rb +11 -8
- metadata +15 -7
- data/lib/scout_apm/agent/logging.rb +0 -74
- data/lib/scout_apm/agent/reporting.rb +0 -129
- data/lib/scout_apm/utils/null_logger.rb +0 -13
@@ -4,10 +4,14 @@
|
|
4
4
|
|
5
5
|
module ScoutApm
|
6
6
|
class SynchronousRecorder
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :context
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
@
|
9
|
+
def initialize(context)
|
10
|
+
@context = context
|
11
|
+
end
|
12
|
+
|
13
|
+
def logger
|
14
|
+
context.logger
|
11
15
|
end
|
12
16
|
|
13
17
|
def start
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module Tasks
|
3
|
+
class Doctor
|
4
|
+
def self.run!
|
5
|
+
new.run!
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize()
|
9
|
+
end
|
10
|
+
|
11
|
+
def run!
|
12
|
+
puts "Scout Doctor"
|
13
|
+
puts "============"
|
14
|
+
puts
|
15
|
+
puts "Detected App Server: #{agent_context.environment.app_server_integration.name}"
|
16
|
+
# puts "Detected Background Job: #{agent_context.environment.background_job_integration.name}"
|
17
|
+
puts
|
18
|
+
puts "Instruments:"
|
19
|
+
puts "----------------------------------------"
|
20
|
+
puts installed_instruments
|
21
|
+
puts
|
22
|
+
puts
|
23
|
+
puts "Configuration Settings:"
|
24
|
+
puts "-------------|------------------------------|-------"
|
25
|
+
puts " From | Key | Value "
|
26
|
+
puts "-------------|------------------------------|-------"
|
27
|
+
puts configuration_settings
|
28
|
+
puts
|
29
|
+
puts
|
30
|
+
puts "Misc:"
|
31
|
+
puts "---------------"
|
32
|
+
puts "Layaway Files stored at: #{agent_context.layaway.directory}"
|
33
|
+
puts "Logs stored at: #{log_details}"
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def agent_context
|
38
|
+
ScoutApm::Agent.instance.context
|
39
|
+
end
|
40
|
+
|
41
|
+
def installed_instruments
|
42
|
+
ScoutApm::Agent.
|
43
|
+
instance.
|
44
|
+
instrument_manager.
|
45
|
+
installed_instruments.
|
46
|
+
map{|instance| "#{instance.installed? ? "Installed " : "Not Installed"} - #{instance.class.to_s}"}.
|
47
|
+
join("\n")
|
48
|
+
end
|
49
|
+
|
50
|
+
def configuration_settings
|
51
|
+
all_settings = agent_context.config.all_settings
|
52
|
+
|
53
|
+
longest_key = all_settings.
|
54
|
+
map{|setting| setting[:key] }.
|
55
|
+
inject(0) { |len, key| key.length > len ? key.length : len }
|
56
|
+
|
57
|
+
format_string = "%12s | %-#{longest_key}s | %s"
|
58
|
+
|
59
|
+
all_settings.
|
60
|
+
map{|setting| sprintf format_string, setting[:source], setting[:key], setting[:value]}.
|
61
|
+
join("\n")
|
62
|
+
end
|
63
|
+
|
64
|
+
def log_details
|
65
|
+
if agent_context.logger.log_destination == STDOUT
|
66
|
+
"STDOUT"
|
67
|
+
elsif agent_context.logger.log_destination == STDERR
|
68
|
+
"STDERR"
|
69
|
+
else
|
70
|
+
"#{agent_context.logger.log_file_path}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module Tasks
|
3
|
+
class Support
|
4
|
+
def self.run!
|
5
|
+
puts "Support Task"
|
6
|
+
new.run!
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@doctor = ScoutApm::Tasks::Doctor.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def run!
|
14
|
+
instruments = @doctor.installed_instruments
|
15
|
+
config = @doctor.configuration_settings
|
16
|
+
collect_logs
|
17
|
+
|
18
|
+
post_data
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/scout_apm/tracer.rb
CHANGED
@@ -45,13 +45,13 @@ module ScoutApm
|
|
45
45
|
# type - "View" or "ActiveRecord" and similar
|
46
46
|
# name - "users/show", "App#find"
|
47
47
|
def instrument_method(method_name, options = {})
|
48
|
-
ScoutApm::Agent.instance.logger.info "Instrumenting #{method_name}"
|
48
|
+
ScoutApm::Agent.instance.context.logger.info "Instrumenting #{method_name}"
|
49
49
|
type = options[:type] || "Custom"
|
50
50
|
name = options[:name] || "#{self.name}/#{method_name.to_s}"
|
51
51
|
|
52
52
|
instrumented_name, uninstrumented_name = _determine_instrumented_name(method_name, type)
|
53
53
|
|
54
|
-
ScoutApm::Agent.instance.logger.info "Instrumenting #{instrumented_name}, #{uninstrumented_name}"
|
54
|
+
ScoutApm::Agent.instance.context.logger.info "Instrumenting #{instrumented_name}, #{uninstrumented_name}"
|
55
55
|
|
56
56
|
return if !_instrumentable?(method_name) or _instrumented?(instrumented_name, method_name)
|
57
57
|
|
@@ -91,7 +91,7 @@ module ScoutApm
|
|
91
91
|
name = begin
|
92
92
|
"#{name}"
|
93
93
|
rescue => e
|
94
|
-
ScoutApm::Agent.instance.logger.error("Error raised while interpreting instrumented name: %s, %s" % ['#{name}', e.message])
|
94
|
+
ScoutApm::Agent.instance.context.logger.error("Error raised while interpreting instrumented name: %s, %s" % ['#{name}', e.message])
|
95
95
|
"Unknown"
|
96
96
|
end
|
97
97
|
|
@@ -110,14 +110,14 @@ module ScoutApm
|
|
110
110
|
# The method must exist to be instrumented.
|
111
111
|
def _instrumentable?(method_name)
|
112
112
|
exists = method_defined?(method_name) || private_method_defined?(method_name)
|
113
|
-
ScoutApm::Agent.instance.logger.warn "The method [#{self.name}##{method_name}] does not exist and will not be instrumented" unless exists
|
113
|
+
ScoutApm::Agent.instance.context.logger.warn "The method [#{self.name}##{method_name}] does not exist and will not be instrumented" unless exists
|
114
114
|
exists
|
115
115
|
end
|
116
116
|
|
117
117
|
# +True+ if the method is already instrumented.
|
118
118
|
def _instrumented?(instrumented_name, method_name)
|
119
119
|
instrumented = method_defined?(instrumented_name)
|
120
|
-
ScoutApm::Agent.instance.logger.warn("The method [#{self.name}##{method_name}] has already been instrumented") if instrumented
|
120
|
+
ScoutApm::Agent.instance.context.logger.warn("The method [#{self.name}##{method_name}] has already been instrumented") if instrumented
|
121
121
|
instrumented
|
122
122
|
end
|
123
123
|
|
@@ -39,26 +39,23 @@ module ScoutApm
|
|
39
39
|
# this is set in the controller instumentation (ActionControllerRails3Rails4 according)
|
40
40
|
attr_accessor :instant_key
|
41
41
|
|
42
|
-
# Whereas the instant_key gets set per-request in reponse to a URL param, dev_trace is set in the config file
|
43
|
-
attr_accessor :dev_trace
|
44
|
-
|
45
42
|
# An object that responds to `record!(TrackedRequest)` to store this tracked request
|
46
43
|
attr_reader :recorder
|
47
44
|
|
48
|
-
def initialize(store)
|
45
|
+
def initialize(agent_context, store)
|
46
|
+
@agent_context = agent_context
|
49
47
|
@store = store #this is passed in so we can use a real store (normal operation) or fake store (instant mode only)
|
50
48
|
@layers = []
|
51
49
|
@call_set = Hash.new { |h, k| h[k] = CallSet.new }
|
52
50
|
@annotations = {}
|
53
51
|
@ignoring_children = 0
|
54
|
-
@context = Context.new
|
52
|
+
@context = Context.new(agent_context)
|
55
53
|
@root_layer = nil
|
56
54
|
@error = false
|
57
55
|
@stopping = false
|
58
56
|
@instant_key = nil
|
59
57
|
@mem_start = mem_usage
|
60
|
-
@
|
61
|
-
@recorder = ScoutApm::Agent.instance.recorder
|
58
|
+
@recorder = agent_context.recorder
|
62
59
|
|
63
60
|
ignore_request! if @recorder.nil?
|
64
61
|
end
|
@@ -152,9 +149,15 @@ module ScoutApm
|
|
152
149
|
@call_set[layer.name].update!(layer.desc)
|
153
150
|
end
|
154
151
|
|
152
|
+
# Grab backtraces more aggressively when running in dev trace mode
|
153
|
+
def backtrace_threshold
|
154
|
+
@agent_context.dev_trace_enabled? ? 0.05 : 0.5 # the minimum threshold in seconds to record the backtrace for a metric.
|
155
|
+
end
|
156
|
+
|
155
157
|
# This may be in bytes or KB based on the OSX. We store this as-is here and only do conversion to MB in Layer Converters.
|
158
|
+
# XXX: Move this to environment?
|
156
159
|
def mem_usage
|
157
|
-
ScoutApm::Instruments::Process::ProcessMemory.rss
|
160
|
+
ScoutApm::Instruments::Process::ProcessMemory.new(@agent_context).rss
|
158
161
|
end
|
159
162
|
|
160
163
|
def capture_mem_delta!
|
@@ -261,7 +264,7 @@ module ScoutApm
|
|
261
264
|
restore_store if @store.nil?
|
262
265
|
|
263
266
|
# Bail out early if the user asked us to ignore this uri
|
264
|
-
return if
|
267
|
+
return if @agent_context.ignored_uris.ignore?(annotations[:uri])
|
265
268
|
|
266
269
|
converters = [
|
267
270
|
LayerConverters::Histograms,
|
@@ -279,7 +282,7 @@ module ScoutApm
|
|
279
282
|
layer_finder = LayerConverters::FindLayerByType.new(self)
|
280
283
|
walker = LayerConverters::DepthFirstWalker.new(self.root_layer)
|
281
284
|
converters = converters.map do |klass|
|
282
|
-
instance = klass.new(self, layer_finder, @store)
|
285
|
+
instance = klass.new(@agent_context, self, layer_finder, @store)
|
283
286
|
instance.register_hooks(walker)
|
284
287
|
instance
|
285
288
|
end
|
@@ -292,26 +295,8 @@ module ScoutApm
|
|
292
295
|
trace = converter.call
|
293
296
|
ScoutApm::InstantReporting.new(trace, instant_key).call
|
294
297
|
end
|
295
|
-
|
296
|
-
if web? || job?
|
297
|
-
ensure_background_worker
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
# Ensure the background worker thread is up & running - a fallback if other
|
302
|
-
# detection doesn't achieve this at boot.
|
303
|
-
def ensure_background_worker
|
304
|
-
agent = ScoutApm::Agent.instance
|
305
|
-
agent.start(:skip_app_server_check => true) unless agent.started?
|
306
|
-
|
307
|
-
if agent.start_background_worker(:quiet)
|
308
|
-
agent.logger.info("Force Started BG Worker")
|
309
|
-
end
|
310
|
-
rescue => e
|
311
|
-
true
|
312
298
|
end
|
313
299
|
|
314
|
-
|
315
300
|
# Only call this after the request is complete
|
316
301
|
def unique_name
|
317
302
|
return nil if ignoring_request?
|
@@ -376,11 +361,6 @@ module ScoutApm
|
|
376
361
|
@ignoring_children > 0
|
377
362
|
end
|
378
363
|
|
379
|
-
# Grab backtraces more aggressively when running in dev trace mode
|
380
|
-
def backtrace_threshold
|
381
|
-
dev_trace ? 0.05 : 0.5 # the minimum threshold in seconds to record the backtrace for a metric.
|
382
|
-
end
|
383
|
-
|
384
364
|
################################################################################
|
385
365
|
# Ignoring the rest of a request
|
386
366
|
################################################################################
|
@@ -390,6 +370,10 @@ module ScoutApm
|
|
390
370
|
# layers, and delete any existing layer info. This class will still exist,
|
391
371
|
# and respond to methods as normal, but `record!` won't be called, and no
|
392
372
|
# data will be recorded.
|
373
|
+
#
|
374
|
+
# We still need to keep track of the current layer depth (via
|
375
|
+
# @ignoring_depth counter) so we know when to report that the class was
|
376
|
+
# "reported", and ready to be recreated for the next request.
|
393
377
|
|
394
378
|
def ignore_request!
|
395
379
|
return if @ignoring_request
|
@@ -425,9 +409,13 @@ module ScoutApm
|
|
425
409
|
end
|
426
410
|
|
427
411
|
def logger
|
428
|
-
|
412
|
+
@agent_context.logger
|
429
413
|
end
|
430
414
|
|
415
|
+
###########################
|
416
|
+
# Serialization Helpers
|
417
|
+
###########################
|
418
|
+
|
431
419
|
# Actually go fetch & make-real any lazily created data.
|
432
420
|
# Clean up any cleverness in objects.
|
433
421
|
# Makes this object ready to be Marshal Dumped (or otherwise serialized)
|
@@ -440,7 +428,7 @@ module ScoutApm
|
|
440
428
|
# Go re-fetch the store based on what the Agent's official one is. Used
|
441
429
|
# after hydrating a dumped TrackedRequest
|
442
430
|
def restore_store
|
443
|
-
@store =
|
431
|
+
@store = @agent_context.store
|
444
432
|
end
|
445
433
|
end
|
446
434
|
end
|
@@ -11,7 +11,7 @@ module ScoutApm
|
|
11
11
|
|
12
12
|
attr_reader :call_stack
|
13
13
|
|
14
|
-
def initialize(call_stack, root=ScoutApm::
|
14
|
+
def initialize(call_stack, root=ScoutApm::Agent.instance.context.environment.root)
|
15
15
|
@call_stack = call_stack
|
16
16
|
# We can't use a constant as it'd be too early to fetch environment info
|
17
17
|
#
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
module Utils
|
3
3
|
class InstalledGems
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
@
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
|
+
end
|
9
|
+
|
10
|
+
def logger
|
11
|
+
context.logger
|
8
12
|
end
|
9
13
|
|
10
14
|
def run
|
@@ -5,6 +5,12 @@ module ScoutApm
|
|
5
5
|
# KlassHelper.defined?("ActiveRecord::Base") #=> true / false
|
6
6
|
|
7
7
|
def self.defined?(*names)
|
8
|
+
lookup(*names) != :missing_class
|
9
|
+
end
|
10
|
+
|
11
|
+
# KlassHelper.lookup("ActiveRecord::Base") => ActiveRecord::Base
|
12
|
+
# KlassHelper.lookup("ActiveRecord::SomethingThatDoesNotExist") => :missing_class
|
13
|
+
def self.lookup(*names)
|
8
14
|
if names.length == 1
|
9
15
|
names = names[0].split("::")
|
10
16
|
end
|
@@ -15,11 +21,11 @@ module ScoutApm
|
|
15
21
|
begin
|
16
22
|
obj = obj.const_get(name)
|
17
23
|
rescue NameError
|
18
|
-
return
|
24
|
+
return :missing_class
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
22
|
-
|
28
|
+
obj
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
data/lib/scout_apm/utils/scm.rb
CHANGED
@@ -4,7 +4,7 @@ module ScoutApm
|
|
4
4
|
class Scm
|
5
5
|
# Takes an *already relative* path +path+
|
6
6
|
# Returns a relative path, prepending the configured +scm_subdirectory+ environment string
|
7
|
-
def self.relative_scm_path(path, scm_subdirectory = ScoutApm::
|
7
|
+
def self.relative_scm_path(path, scm_subdirectory = ScoutApm::Agent.instance.context.environment.scm_subdirectory)
|
8
8
|
@@scm_subdirectory ||= scm_subdirectory.sub(/^\//, '')
|
9
9
|
@@scm_subdirectoy_blank ||= @@scm_subdirectory.empty?
|
10
10
|
@@scm_subdirectoy_blank ? path : File.join(@@scm_subdirectory, path)
|
@@ -16,7 +16,7 @@ module ScoutApm
|
|
16
16
|
|
17
17
|
def initialize(sql)
|
18
18
|
@raw_sql = sql
|
19
|
-
@database_engine = ScoutApm::
|
19
|
+
@database_engine = ScoutApm::Agent.instance.context.environment.database_engine
|
20
20
|
@sanitized = false # only sanitize once.
|
21
21
|
end
|
22
22
|
|
@@ -74,19 +74,17 @@ module ScoutApm
|
|
74
74
|
encodings.all?{|enc| Encoding.find(enc) rescue false}
|
75
75
|
end
|
76
76
|
|
77
|
-
MAX_SQL_LENGTH = 16384
|
78
|
-
|
79
77
|
def scrubbed(str)
|
80
|
-
return '' if !str.is_a?(String) || str.length >
|
78
|
+
return '' if !str.is_a?(String) || str.length > 4000 # safeguard - don't sanitize or scrub large SQL statements
|
81
79
|
return str if !str.respond_to?(:encode) # Ruby <= 1.8 doesn't have string encoding
|
82
80
|
return str if str.valid_encoding? # Whatever encoding it is, it is valid and we can operate on it
|
83
|
-
ScoutApm::Agent.instance.logger.debug "Scrubbing invalid sql encoding."
|
81
|
+
ScoutApm::Agent.instance.context.logger.debug "Scrubbing invalid sql encoding."
|
84
82
|
if str.respond_to?(:scrub) # Prefer to scrub before we have to convert
|
85
83
|
return str.scrub('_')
|
86
84
|
elsif has_encodings?(['UTF-8', 'binary'])
|
87
85
|
return str.encode('UTF-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '_')
|
88
86
|
end
|
89
|
-
ScoutApm::Agent.instance.logger.debug "Unable to scrub invalid sql encoding."
|
87
|
+
ScoutApm::Agent.instance.context.logger.debug "Unable to scrub invalid sql encoding."
|
90
88
|
''
|
91
89
|
end
|
92
90
|
|
data/lib/scout_apm/version.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
namespace :scout do
|
2
|
+
desc "Prints out details of the detected environment"
|
3
|
+
task :doctor => :environment do
|
4
|
+
ScoutApm::Tasks::Doctor.run!
|
5
|
+
end
|
6
|
+
|
7
|
+
desc "Collect logs, settings and environment to help debug issues"
|
8
|
+
task :support => :environment do
|
9
|
+
ScoutApm::Tasks::Support.run!
|
10
|
+
end
|
11
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -41,6 +41,14 @@ class FakeConfigOverlay
|
|
41
41
|
def has_key?(key)
|
42
42
|
@values.has_key?(key)
|
43
43
|
end
|
44
|
+
|
45
|
+
def name
|
46
|
+
"agent-test-config-overlay"
|
47
|
+
end
|
48
|
+
|
49
|
+
def any_keys_found?
|
50
|
+
true
|
51
|
+
end
|
44
52
|
end
|
45
53
|
|
46
54
|
class FakeEnvironment
|
@@ -66,7 +74,7 @@ class Minitest::Test
|
|
66
74
|
end
|
67
75
|
|
68
76
|
def teardown
|
69
|
-
ScoutApm::Agent.instance.
|
77
|
+
ScoutApm::Agent.instance.stop_background_worker
|
70
78
|
File.delete(DATA_FILE_PATH) if File.exist?(DATA_FILE_PATH)
|
71
79
|
end
|
72
80
|
|
@@ -85,8 +93,13 @@ class Minitest::Test
|
|
85
93
|
FakeEnvironment.new(values)
|
86
94
|
end
|
87
95
|
|
96
|
+
# XXX: Make it easy to override context here?
|
88
97
|
def make_fake_config(values)
|
89
|
-
ScoutApm::Config.new(FakeConfigOverlay.new(values))
|
98
|
+
ScoutApm::Config.new(agent_context, [FakeConfigOverlay.new(values), ScoutApm::Config::ConfigNull.new] )
|
99
|
+
end
|
100
|
+
|
101
|
+
def agent_context
|
102
|
+
ScoutApm::AgentContext.new
|
90
103
|
end
|
91
104
|
|
92
105
|
DATA_FILE_DIR = File.dirname(__FILE__) + '/tmp'
|