scout_apm 3.0.0.pre10 → 3.0.0.pre11
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.markdown +47 -0
- data/Guardfile +42 -0
- data/lib/scout_apm.rb +14 -0
- data/lib/scout_apm/agent.rb +58 -1
- data/lib/scout_apm/agent/logging.rb +6 -1
- data/lib/scout_apm/app_server_load.rb +21 -11
- data/lib/scout_apm/background_job_integrations/resque.rb +85 -0
- data/lib/scout_apm/background_job_integrations/sidekiq.rb +19 -3
- data/lib/scout_apm/background_recorder.rb +43 -0
- data/lib/scout_apm/background_worker.rb +6 -6
- data/lib/scout_apm/config.rb +14 -3
- data/lib/scout_apm/environment.rb +14 -0
- data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +112 -70
- data/lib/scout_apm/instruments/action_view.rb +49 -0
- data/lib/scout_apm/instruments/active_record.rb +2 -2
- data/lib/scout_apm/instruments/mongoid.rb +10 -2
- data/lib/scout_apm/instruments/resque.rb +40 -0
- data/lib/scout_apm/layer_children_set.rb +7 -2
- data/lib/scout_apm/rack.rb +26 -0
- data/lib/scout_apm/remote/message.rb +23 -0
- data/lib/scout_apm/remote/recorder.rb +57 -0
- data/lib/scout_apm/remote/router.rb +49 -0
- data/lib/scout_apm/remote/server.rb +58 -0
- data/lib/scout_apm/request_manager.rb +1 -1
- data/lib/scout_apm/synchronous_recorder.rb +26 -0
- data/lib/scout_apm/tracked_request.rb +53 -5
- data/lib/scout_apm/utils/backtrace_parser.rb +3 -3
- data/lib/scout_apm/utils/scm.rb +14 -0
- data/lib/scout_apm/version.rb +1 -1
- data/scout_apm.gemspec +2 -0
- data/test/unit/remote/test_message.rb +13 -0
- data/test/unit/remote/test_router.rb +33 -0
- data/test/unit/remote/test_server.rb +15 -0
- data/test/unit/test_tracked_request.rb +87 -0
- data/test/unit/utils/backtrace_parser_test.rb +5 -0
- data/test/unit/utils/scm.rb +17 -0
- metadata +52 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36bac9cf47e89f5cec6475b574b6cd948339d627
|
4
|
+
data.tar.gz: dd2bc23001811e393950d502f04b2a359dae083d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d2e5b8270afe767d63890df65b8ea6f1fba96f4a2187cd58537372e13c7555f94875b3884473f210eb6e96f1815240508a53c50638e0ba74ad96075d9364888
|
7
|
+
data.tar.gz: 7b0169e3e311061dc20da5088f7b22247ec3acf66ba145b827a926ef87763bf6e576282a282611c2d5178412de7b8ade5a24a7c50e730399c560e1f846626020
|
data/.gitignore
CHANGED
data/CHANGELOG.markdown
CHANGED
@@ -1,6 +1,52 @@
|
|
1
|
+
<<<<<<< HEAD
|
1
2
|
# 3.0.0
|
2
3
|
|
3
4
|
* ScoutProf BETA
|
5
|
+
=======
|
6
|
+
# 2.1.32
|
7
|
+
|
8
|
+
* Better naming when using Resque + ActiveJob
|
9
|
+
* Better naming when using Sidekiq + DelayedExtension
|
10
|
+
>>>>>>> master
|
11
|
+
|
12
|
+
# 2.1.31
|
13
|
+
|
14
|
+
* Better detection of Resque queue names
|
15
|
+
* Fix passing arguments through Active Record instrumentation. (Thanks to Nick Quaranto for providing the fix)
|
16
|
+
* Stricter checks to prevent agent from starting in Rails console
|
17
|
+
|
18
|
+
# 2.1.30
|
19
|
+
|
20
|
+
* Add Resque support.
|
21
|
+
|
22
|
+
# 2.1.29
|
23
|
+
|
24
|
+
* Add `scm_subdirectory` option. Useful for when your app code does not live in your SCM root directory.
|
25
|
+
|
26
|
+
# 2.1.28
|
27
|
+
|
28
|
+
* Changes to app server load data
|
29
|
+
|
30
|
+
# 2.1.27
|
31
|
+
|
32
|
+
* Don't attempt to call `current_layer.type` on nil
|
33
|
+
|
34
|
+
# 2.1.26
|
35
|
+
|
36
|
+
* Bug fix [4b188d6](https://github.com/scoutapp/scout_apm_ruby/commit/4b188d698852c86b86d8768ea5b37d706ce544fe)
|
37
|
+
|
38
|
+
# 2.1.25
|
39
|
+
|
40
|
+
* Automatically instrument API and Metal controllers.
|
41
|
+
|
42
|
+
# 2.1.24
|
43
|
+
|
44
|
+
* Capture additional layers of application backtrace frames. (From 3 -> 8)
|
45
|
+
|
46
|
+
# 2.1.23
|
47
|
+
|
48
|
+
* Extend Mongoid instrumentation to 6.x
|
49
|
+
>>>>>>> master
|
4
50
|
|
5
51
|
# 2.1.22
|
6
52
|
|
@@ -66,6 +112,7 @@
|
|
66
112
|
# 2.1.9
|
67
113
|
|
68
114
|
* Send raw histograms of response time, enabling more accurate 95th %iles
|
115
|
+
* Raw histograms are used in Apdex calculations
|
69
116
|
* Gzip payloads
|
70
117
|
* Fix Mongoid (5.0) + Mongo (2.1) support
|
71
118
|
* Initial Delayed Job support
|
data/Guardfile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
guard :minitest do
|
19
|
+
# with Minitest::Unit
|
20
|
+
watch(%r{^test/(.*)\/?test_(.*)\.rb$})
|
21
|
+
watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
|
22
|
+
watch(%r{^test/test_helper\.rb$}) { 'test' }
|
23
|
+
|
24
|
+
# with Minitest::Spec
|
25
|
+
# watch(%r{^spec/(.*)_spec\.rb$})
|
26
|
+
# watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
27
|
+
# watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
|
28
|
+
|
29
|
+
# Rails 4
|
30
|
+
# watch(%r{^app/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
|
31
|
+
# watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
|
32
|
+
# watch(%r{^app/controllers/(.+)_controller\.rb$}) { |m| "test/integration/#{m[1]}_test.rb" }
|
33
|
+
# watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
|
34
|
+
# watch(%r{^lib/(.+)\.rb$}) { |m| "test/lib/#{m[1]}_test.rb" }
|
35
|
+
# watch(%r{^test/.+_test\.rb$})
|
36
|
+
# watch(%r{^test/test_helper\.rb$}) { 'test' }
|
37
|
+
|
38
|
+
# Rails < 4
|
39
|
+
# watch(%r{^app/controllers/(.*)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" }
|
40
|
+
# watch(%r{^app/helpers/(.*)\.rb$}) { |m| "test/helpers/#{m[1]}_test.rb" }
|
41
|
+
# watch(%r{^app/models/(.*)\.rb$}) { |m| "test/unit/#{m[1]}_test.rb" }
|
42
|
+
end
|
data/lib/scout_apm.rb
CHANGED
@@ -15,6 +15,7 @@ require 'thread'
|
|
15
15
|
require 'time'
|
16
16
|
require 'yaml'
|
17
17
|
require 'rbconfig'
|
18
|
+
require 'webrick'
|
18
19
|
|
19
20
|
#####################################
|
20
21
|
# Gem Requires
|
@@ -54,6 +55,7 @@ require 'scout_apm/server_integrations/null'
|
|
54
55
|
|
55
56
|
require 'scout_apm/background_job_integrations/sidekiq'
|
56
57
|
require 'scout_apm/background_job_integrations/delayed_job'
|
58
|
+
require 'scout_apm/background_job_integrations/resque'
|
57
59
|
|
58
60
|
require 'scout_apm/framework_integrations/rails_2'
|
59
61
|
require 'scout_apm/framework_integrations/rails_3_or_4'
|
@@ -84,6 +86,7 @@ require 'scout_apm/instruments/sinatra'
|
|
84
86
|
require 'scout_apm/instruments/process/process_cpu'
|
85
87
|
require 'scout_apm/instruments/process/process_memory'
|
86
88
|
require 'scout_apm/instruments/percentile_sampler'
|
89
|
+
require 'scout_apm/instruments/action_view'
|
87
90
|
require 'allocations'
|
88
91
|
|
89
92
|
begin
|
@@ -100,6 +103,7 @@ require 'scout_apm/utils/backtrace_parser'
|
|
100
103
|
require 'scout_apm/utils/installed_gems'
|
101
104
|
require 'scout_apm/utils/klass_helper'
|
102
105
|
require 'scout_apm/utils/null_logger'
|
106
|
+
require 'scout_apm/utils/scm'
|
103
107
|
require 'scout_apm/utils/sql_sanitizer'
|
104
108
|
require 'scout_apm/utils/time'
|
105
109
|
require 'scout_apm/utils/unique_id'
|
@@ -124,6 +128,8 @@ require 'scout_apm/tracer'
|
|
124
128
|
require 'scout_apm/context'
|
125
129
|
require 'scout_apm/instant_reporting'
|
126
130
|
require 'scout_apm/trace_compactor'
|
131
|
+
require 'scout_apm/background_recorder'
|
132
|
+
require 'scout_apm/synchronous_recorder'
|
127
133
|
|
128
134
|
require 'scout_apm/metric_meta'
|
129
135
|
require 'scout_apm/metric_stats'
|
@@ -151,6 +157,14 @@ require 'scout_apm/middleware'
|
|
151
157
|
|
152
158
|
require 'scout_apm/instant/middleware'
|
153
159
|
|
160
|
+
require 'scout_apm/rack'
|
161
|
+
|
162
|
+
require 'scout_apm/remote/server'
|
163
|
+
require 'scout_apm/remote/router'
|
164
|
+
require 'scout_apm/remote/message'
|
165
|
+
require 'scout_apm/remote/recorder'
|
166
|
+
require 'scout_apm/instruments/resque'
|
167
|
+
|
154
168
|
if defined?(Rails) && defined?(Rails::VERSION) && defined?(Rails::VERSION::MAJOR) && Rails::VERSION::MAJOR >= 3 && defined?(Rails::Railtie)
|
155
169
|
module ScoutApm
|
156
170
|
class Railtie < Rails::Railtie
|
data/lib/scout_apm/agent.rb
CHANGED
@@ -10,6 +10,7 @@ module ScoutApm
|
|
10
10
|
|
11
11
|
# Accessors below are for associated classes
|
12
12
|
attr_accessor :store
|
13
|
+
attr_reader :recorder
|
13
14
|
attr_accessor :layaway
|
14
15
|
attr_accessor :config
|
15
16
|
attr_accessor :logger
|
@@ -41,6 +42,9 @@ module ScoutApm
|
|
41
42
|
@process_start_time = Time.now
|
42
43
|
@options ||= options
|
43
44
|
|
45
|
+
# until the agent is started, there's no recorder
|
46
|
+
@recorder = nil
|
47
|
+
|
44
48
|
# Start up without attempting to load a configuration file. We need to be
|
45
49
|
# able to lookup configuration options like "application_root" which would
|
46
50
|
# then in turn influence where the configuration file came from.
|
@@ -54,6 +58,7 @@ module ScoutApm
|
|
54
58
|
@request_histograms_by_time = Hash.new { |h, k| h[k] = ScoutApm::RequestHistograms.new }
|
55
59
|
|
56
60
|
@store = ScoutApm::Store.new
|
61
|
+
|
57
62
|
@layaway = ScoutApm::Layaway.new(config, environment)
|
58
63
|
@metric_lookup = Hash.new
|
59
64
|
|
@@ -84,6 +89,11 @@ module ScoutApm
|
|
84
89
|
return false unless force?
|
85
90
|
end
|
86
91
|
|
92
|
+
if environment.interactive?
|
93
|
+
logger.warn "Agent attempting to load in interactive mode. #{force? ? 'Forcing agent to start' : 'Not starting agent'}"
|
94
|
+
return false unless force?
|
95
|
+
end
|
96
|
+
|
87
97
|
if app_server_missing?(options) && background_job_missing?
|
88
98
|
if force?
|
89
99
|
logger.warn "Agent starting (forced)"
|
@@ -111,13 +121,14 @@ module ScoutApm
|
|
111
121
|
def start(options = {})
|
112
122
|
@options.merge!(options)
|
113
123
|
|
114
|
-
|
115
124
|
@config = ScoutApm::Config.with_file(@config.value("config_file"))
|
116
125
|
layaway.config = config
|
117
126
|
|
118
127
|
init_logger
|
119
128
|
logger.info "Attempting to start Scout Agent [#{ScoutApm::VERSION}] on [#{environment.hostname}]"
|
120
129
|
|
130
|
+
@recorder = create_recorder
|
131
|
+
|
121
132
|
@config.log_settings
|
122
133
|
|
123
134
|
@ignored_uris = ScoutApm::IgnoredUris.new(config.value('ignore'))
|
@@ -262,6 +273,9 @@ module ScoutApm
|
|
262
273
|
ScoutApm::Instruments::Stacks.start
|
263
274
|
end
|
264
275
|
|
276
|
+
@recorder = create_recorder
|
277
|
+
logger.info("recorder is now: #{@recorder.class}")
|
278
|
+
|
265
279
|
@background_worker = ScoutApm::BackgroundWorker.new
|
266
280
|
@background_worker_thread = Thread.new do
|
267
281
|
@background_worker.start {
|
@@ -303,6 +317,7 @@ module ScoutApm
|
|
303
317
|
end
|
304
318
|
end
|
305
319
|
|
320
|
+
install_instrument(ScoutApm::Instruments::ActionView)
|
306
321
|
install_instrument(ScoutApm::Instruments::ActiveRecord)
|
307
322
|
install_instrument(ScoutApm::Instruments::Moped)
|
308
323
|
install_instrument(ScoutApm::Instruments::Mongoid)
|
@@ -341,5 +356,47 @@ module ScoutApm
|
|
341
356
|
def background_job_missing?(options = {})
|
342
357
|
environment.background_job_integration.nil? && !options[:skip_background_job_check]
|
343
358
|
end
|
359
|
+
|
360
|
+
def clear_recorder
|
361
|
+
@recorder = nil
|
362
|
+
end
|
363
|
+
|
364
|
+
def create_recorder
|
365
|
+
if @recorder
|
366
|
+
return @recorder
|
367
|
+
end
|
368
|
+
|
369
|
+
if config.value("async_recording")
|
370
|
+
logger.debug("Using asynchronous recording")
|
371
|
+
ScoutApm::BackgroundRecorder.new(logger).start
|
372
|
+
else
|
373
|
+
logger.debug("Using synchronous recording")
|
374
|
+
ScoutApm::SynchronousRecorder.new(logger).start
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
def start_remote_server(bind, port)
|
379
|
+
return if @remote_server && @remote_server.running?
|
380
|
+
|
381
|
+
logger.info("Starting Remote Agent Server")
|
382
|
+
|
383
|
+
# Start the listening web server only in parent process.
|
384
|
+
@remote_server = ScoutApm::Remote::Server.new(
|
385
|
+
bind,
|
386
|
+
port,
|
387
|
+
ScoutApm::Remote::Router.new(ScoutApm::SynchronousRecorder.new(logger), logger),
|
388
|
+
logger
|
389
|
+
)
|
390
|
+
|
391
|
+
@remote_server.start
|
392
|
+
end
|
393
|
+
|
394
|
+
# Execute this in the child process of a remote agent. The parent is
|
395
|
+
# expected to have its accepting webserver up and running
|
396
|
+
def use_remote_recorder(host, port)
|
397
|
+
logger.debug("Becoming Remote Agent (reporting to: #{host}:#{port})")
|
398
|
+
@recorder = ScoutApm::Remote::Recorder.new(host, port, logger)
|
399
|
+
@store = ScoutApm::FakeStore.new
|
400
|
+
end
|
344
401
|
end
|
345
402
|
end
|
@@ -27,20 +27,30 @@ module ScoutApm
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def data
|
30
|
-
{ :server_time => Time.now,
|
31
|
-
:framework => ScoutApm::Environment.instance.framework_integration.human_name,
|
32
|
-
:framework_version => ScoutApm::Environment.instance.framework_integration.version,
|
33
|
-
:environment => ScoutApm::Environment.instance.framework_integration.env,
|
34
|
-
:app_server => ScoutApm::Environment.instance.app_server,
|
30
|
+
{ :server_time => to_s_safe(Time.now),
|
31
|
+
:framework => to_s_safe(ScoutApm::Environment.instance.framework_integration.human_name),
|
32
|
+
:framework_version => to_s_safe(ScoutApm::Environment.instance.framework_integration.version),
|
33
|
+
:environment => to_s_safe(ScoutApm::Environment.instance.framework_integration.env),
|
34
|
+
:app_server => to_s_safe(ScoutApm::Environment.instance.app_server),
|
35
35
|
:ruby_version => RUBY_VERSION,
|
36
|
-
:hostname => ScoutApm::Environment.instance.hostname,
|
37
|
-
:database_engine => ScoutApm::Environment.instance.database_engine, # Detected
|
38
|
-
:database_adapter => ScoutApm::Environment.instance.raw_database_adapter, # Raw
|
39
|
-
:application_name => ScoutApm::Environment.instance.application_name,
|
36
|
+
:hostname => to_s_safe(ScoutApm::Environment.instance.hostname),
|
37
|
+
:database_engine => to_s_safe(ScoutApm::Environment.instance.database_engine), # Detected
|
38
|
+
:database_adapter => to_s_safe(ScoutApm::Environment.instance.raw_database_adapter), # Raw
|
39
|
+
:application_name => to_s_safe(ScoutApm::Environment.instance.application_name),
|
40
40
|
:libraries => ScoutApm::Utils::InstalledGems.new.run,
|
41
|
-
:paas => ScoutApm::Environment.instance.platform_integration.name,
|
42
|
-
:git_sha => ScoutApm::Environment.instance.git_revision.sha
|
41
|
+
:paas => to_s_safe(ScoutApm::Environment.instance.platform_integration.name),
|
42
|
+
:git_sha => to_s_safe(ScoutApm::Environment.instance.git_revision.sha)
|
43
43
|
}
|
44
44
|
end
|
45
|
+
|
46
|
+
# Calls `.to_s` on the object passed in.
|
47
|
+
# Returns literal string 'to_s error' if the object does not respond to .to_s
|
48
|
+
def to_s_safe(obj)
|
49
|
+
if obj.respond_to?(:to_s)
|
50
|
+
obj.to_s
|
51
|
+
else
|
52
|
+
'to_s error'
|
53
|
+
end
|
54
|
+
end
|
45
55
|
end
|
46
56
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module BackgroundJobIntegrations
|
3
|
+
class Resque
|
4
|
+
def name
|
5
|
+
:resque
|
6
|
+
end
|
7
|
+
|
8
|
+
def present?
|
9
|
+
defined?(::Resque) &&
|
10
|
+
::Resque.respond_to?(:before_first_fork) &&
|
11
|
+
::Resque.respond_to?(:after_fork)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Lies. This forks really aggressively, but we have to do handling
|
15
|
+
# of it manually here, rather than via any sort of automatic
|
16
|
+
# background worker starting
|
17
|
+
def forking?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def install
|
22
|
+
install_before_fork
|
23
|
+
install_after_fork
|
24
|
+
end
|
25
|
+
|
26
|
+
def install_before_fork
|
27
|
+
::Resque.before_first_fork do
|
28
|
+
begin
|
29
|
+
ScoutApm::Agent.instance.start(:skip_app_server_check => true)
|
30
|
+
ScoutApm::Agent.instance.start_background_worker
|
31
|
+
ScoutApm::Agent.instance.start_remote_server(bind, port)
|
32
|
+
rescue Errno::EADDRINUSE
|
33
|
+
ScoutApm::Agent.instance.logger.warn "Error while Installing Resque Instruments, Port #{port} already in use. Set via the `remote_agent_port` configuration option"
|
34
|
+
rescue => e
|
35
|
+
ScoutApm::Agent.instance.logger.warn "Error while Installing Resque before_first_fork: #{e.inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def install_after_fork
|
41
|
+
::Resque.after_fork do
|
42
|
+
begin
|
43
|
+
ScoutApm::Agent.instance.use_remote_recorder(bind, port)
|
44
|
+
inject_job_instrument
|
45
|
+
rescue => e
|
46
|
+
ScoutApm::Agent.instance.logger.warn "Error while Installing Resque after_fork: #{e.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Insert ourselves into the point when resque turns a string "TestJob"
|
52
|
+
# into the class constant TestJob, and insert our instrumentation plugin
|
53
|
+
# into that constantized class
|
54
|
+
#
|
55
|
+
# This automates away any need for the user to insert our instrumentation into
|
56
|
+
# each of their jobs
|
57
|
+
def inject_job_instrument
|
58
|
+
::Resque::Job.class_eval do
|
59
|
+
def payload_class_with_scout_instruments
|
60
|
+
klass = payload_class_without_scout_instruments
|
61
|
+
klass.extend(ScoutApm::Instruments::Resque)
|
62
|
+
klass
|
63
|
+
end
|
64
|
+
alias_method :payload_class_without_scout_instruments, :payload_class
|
65
|
+
alias_method :payload_class, :payload_class_with_scout_instruments
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def bind
|
72
|
+
config.value("remote_agent_host")
|
73
|
+
end
|
74
|
+
|
75
|
+
def port
|
76
|
+
config.value("remote_agent_port")
|
77
|
+
end
|
78
|
+
|
79
|
+
def config
|
80
|
+
@config || ScoutApm::Agent.instance.config
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
@@ -55,8 +55,6 @@ module ScoutApm
|
|
55
55
|
# We insert this middleware into the Sidekiq stack, to capture each job,
|
56
56
|
# and time them.
|
57
57
|
class SidekiqMiddleware
|
58
|
-
ACTIVE_JOB_KLASS = 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper'.freeze
|
59
|
-
|
60
58
|
def call(_worker, msg, queue)
|
61
59
|
req = ScoutApm::RequestManager.lookup
|
62
60
|
req.job!
|
@@ -89,12 +87,30 @@ module ScoutApm
|
|
89
87
|
end
|
90
88
|
|
91
89
|
UNKNOWN_CLASS_PLACEHOLDER = 'UnknownJob'.freeze
|
90
|
+
ACTIVE_JOB_KLASS = 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper'.freeze
|
91
|
+
DELAYED_WRAPPER_KLASS = 'Sidekiq::Extensions::DelayedClass'.freeze
|
92
|
+
|
92
93
|
|
93
94
|
def job_class(msg)
|
94
95
|
job_class = msg.fetch('class', UNKNOWN_CLASS_PLACEHOLDER)
|
96
|
+
|
95
97
|
if job_class == ACTIVE_JOB_KLASS && msg.key?('wrapped')
|
96
|
-
|
98
|
+
begin
|
99
|
+
job_class = msg['wrapped']
|
100
|
+
rescue
|
101
|
+
ACTIVE_JOB_KLASS
|
102
|
+
end
|
103
|
+
elsif job_class == DELAYED_WRAPPER_KLASS
|
104
|
+
begin
|
105
|
+
yml = msg['args'].first
|
106
|
+
deserialized_args = YAML.load(yml)
|
107
|
+
klass, method, *rest = deserialized_args
|
108
|
+
job_class = [klass,method].map(&:to_s).join(".")
|
109
|
+
rescue
|
110
|
+
DELAYED_WRAPPER_KLASS
|
111
|
+
end
|
97
112
|
end
|
113
|
+
|
98
114
|
job_class
|
99
115
|
rescue
|
100
116
|
UNKNOWN_CLASS_PLACEHOLDER
|