scout_apm 4.0.3 → 4.0.4
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/CHANGELOG.markdown +6 -0
- data/lib/scout_apm.rb +1 -0
- data/lib/scout_apm/background_job_integrations/delayed_job.rb +1 -1
- data/lib/scout_apm/background_job_integrations/faktory.rb +103 -0
- data/lib/scout_apm/environment.rb +2 -1
- data/lib/scout_apm/serializers/payload_serializer_to_json.rb +11 -25
- data/lib/scout_apm/tracer.rb +2 -2
- data/lib/scout_apm/version.rb +1 -1
- data/test/unit/tracer_test.rb +25 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16b10ca7e3c7474546feb2b367438e9fabeb2c799e85608b96afb3ddea37b647
|
4
|
+
data.tar.gz: 044ced73909cff452e59bccf14e7dfcf344fd8f6262c5b633b0d3239995609fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2ae77ef620e77bce7b267fe8c39ff2f91945dfffc3ad008dd01cbd3b45268a8b44624713652d1df2bdeb2789bedb1fdb98aa58742b48326b1821ea01482132d
|
7
|
+
data.tar.gz: c533bf6cf2822f7688b4377e9f69e005eb1255c0c03cd000dd5d4edaef74b7761b4b8af9b8d39d1229480fd7f2cd0b0f6bcaf1890be5b3f6a9540bf7f8e03f64
|
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# 4.0.4
|
2
|
+
|
3
|
+
* Add Faktory Support (#385)
|
4
|
+
* Remove Regexp hack for 1.8.7 (no longer supported) (#384)
|
5
|
+
* More robust DelayedJob detection (#382)
|
6
|
+
* Fix kwargs handling in Tracing module (#381)
|
1
7
|
# 4.0.3
|
2
8
|
|
3
9
|
* Handle edge case with nil Typhoeus current-layer (#380)
|
data/lib/scout_apm.rb
CHANGED
@@ -58,6 +58,7 @@ require 'scout_apm/server_integrations/webrick'
|
|
58
58
|
require 'scout_apm/server_integrations/null'
|
59
59
|
|
60
60
|
require 'scout_apm/background_job_integrations/sidekiq'
|
61
|
+
require 'scout_apm/background_job_integrations/faktory'
|
61
62
|
require 'scout_apm/background_job_integrations/delayed_job'
|
62
63
|
require 'scout_apm/background_job_integrations/resque'
|
63
64
|
require 'scout_apm/background_job_integrations/shoryuken'
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module BackgroundJobIntegrations
|
3
|
+
class Faktory
|
4
|
+
attr_reader :logger
|
5
|
+
|
6
|
+
def name
|
7
|
+
:faktory
|
8
|
+
end
|
9
|
+
|
10
|
+
def present?
|
11
|
+
defined?(::Faktory)
|
12
|
+
end
|
13
|
+
|
14
|
+
def forking?
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
def install
|
19
|
+
add_middleware
|
20
|
+
install_processor
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_middleware
|
24
|
+
::Faktory.configure_worker do |config|
|
25
|
+
config.worker_middleware do |chain|
|
26
|
+
chain.add FaktoryMiddleware
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def install_processor
|
32
|
+
require 'faktory/processor' # sidekiq v4 has not loaded this file by this point
|
33
|
+
|
34
|
+
::Faktory::Processor.class_eval do
|
35
|
+
def initialize_with_scout(*args)
|
36
|
+
agent = ::ScoutApm::Agent.instance
|
37
|
+
agent.start
|
38
|
+
initialize_without_scout(*args)
|
39
|
+
end
|
40
|
+
|
41
|
+
alias_method :initialize_without_scout, :initialize
|
42
|
+
alias_method :initialize, :initialize_with_scout
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# We insert this middleware into the Sidekiq stack, to capture each job,
|
48
|
+
# and time them.
|
49
|
+
class FaktoryMiddleware
|
50
|
+
def call(worker_instance, job)
|
51
|
+
queue = job["queue"]
|
52
|
+
|
53
|
+
req = ScoutApm::RequestManager.lookup
|
54
|
+
req.annotate_request(:queue_latency => latency(job))
|
55
|
+
|
56
|
+
begin
|
57
|
+
req.start_layer(ScoutApm::Layer.new('Queue', queue))
|
58
|
+
started_queue = true
|
59
|
+
req.start_layer(ScoutApm::Layer.new('Job', job_class(job)))
|
60
|
+
started_job = true
|
61
|
+
|
62
|
+
yield
|
63
|
+
rescue
|
64
|
+
req.error!
|
65
|
+
raise
|
66
|
+
ensure
|
67
|
+
req.stop_layer if started_job
|
68
|
+
req.stop_layer if started_queue
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
UNKNOWN_CLASS_PLACEHOLDER = 'UnknownJob'.freeze
|
73
|
+
ACTIVE_JOB_KLASS = 'ActiveJob::QueueAdapters::FaktoryAdapter::JobWrapper'.freeze
|
74
|
+
|
75
|
+
def job_class(job)
|
76
|
+
job_class = job.fetch('jobtype', UNKNOWN_CLASS_PLACEHOLDER)
|
77
|
+
|
78
|
+
if job_class == ACTIVE_JOB_KLASS && job.key?('custom') && job['custom'].key?('wrapped')
|
79
|
+
begin
|
80
|
+
job_class = job['custom']['wrapped']
|
81
|
+
rescue
|
82
|
+
ACTIVE_JOB_KLASS
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
job_class
|
87
|
+
rescue
|
88
|
+
UNKNOWN_CLASS_PLACEHOLDER
|
89
|
+
end
|
90
|
+
|
91
|
+
def latency(job, time = Time.now)
|
92
|
+
created_at = Time.parse(job['enqueued_at'] || job['created_at'])
|
93
|
+
if created_at
|
94
|
+
(time - created_at)
|
95
|
+
else
|
96
|
+
0
|
97
|
+
end
|
98
|
+
rescue
|
99
|
+
0
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -30,6 +30,7 @@ module ScoutApm
|
|
30
30
|
ScoutApm::BackgroundJobIntegrations::Sneakers.new,
|
31
31
|
ScoutApm::BackgroundJobIntegrations::DelayedJob.new,
|
32
32
|
ScoutApm::BackgroundJobIntegrations::Que.new,
|
33
|
+
ScoutApm::BackgroundJobIntegrations::Faktory.new,
|
33
34
|
]
|
34
35
|
|
35
36
|
FRAMEWORK_INTEGRATIONS = [
|
@@ -197,7 +198,7 @@ module ScoutApm
|
|
197
198
|
ruby_2? || ruby_3?
|
198
199
|
end
|
199
200
|
|
200
|
-
# Returns true if this Ruby version
|
201
|
+
# Returns true if this Ruby version makes positional and keyword arguments incompatible
|
201
202
|
def supports_kwarg_delegation?
|
202
203
|
ruby_3? || (ruby_2? && ruby_minor >= 7)
|
203
204
|
end
|
@@ -45,31 +45,17 @@ module ScoutApm
|
|
45
45
|
"{#{str_parts.join(",")}}"
|
46
46
|
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
'\\' => '\\\\',
|
60
|
-
}
|
61
|
-
else
|
62
|
-
ESCAPE_MAPPINGS = {
|
63
|
-
# Stackoverflow answer on gsub matches and backslashes - https://stackoverflow.com/a/4149087/2705125
|
64
|
-
'\\' => '\\\\\\\\',
|
65
|
-
"\b" => '\\b',
|
66
|
-
"\t" => '\\t',
|
67
|
-
"\n" => '\\n',
|
68
|
-
"\f" => '\\f',
|
69
|
-
"\r" => '\\r',
|
70
|
-
'"' => '\\"',
|
71
|
-
}
|
72
|
-
end
|
48
|
+
ESCAPE_MAPPINGS = {
|
49
|
+
# Stackoverflow answer on gsub matches and backslashes
|
50
|
+
# https://stackoverflow.com/a/4149087/2705125
|
51
|
+
'\\' => '\\\\\\\\',
|
52
|
+
"\b" => '\\b',
|
53
|
+
"\t" => '\\t',
|
54
|
+
"\n" => '\\n',
|
55
|
+
"\f" => '\\f',
|
56
|
+
"\r" => '\\r',
|
57
|
+
'"' => '\\"',
|
58
|
+
}
|
73
59
|
|
74
60
|
def escape(string)
|
75
61
|
ESCAPE_MAPPINGS.inject(string.to_s) {|s, (bad, good)|
|
data/lib/scout_apm/tracer.rb
CHANGED
@@ -91,7 +91,7 @@ module ScoutApm
|
|
91
91
|
|
92
92
|
def _instrumented_method_string(instrumented_name, uninstrumented_name, type, name, options={})
|
93
93
|
method_str = <<-EOF
|
94
|
-
def #{instrumented_name}(*args, &block)
|
94
|
+
def #{instrumented_name}(*args#{", **kwargs" if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?}, &block)
|
95
95
|
name = begin
|
96
96
|
"#{name}"
|
97
97
|
rescue => e
|
@@ -103,7 +103,7 @@ module ScoutApm
|
|
103
103
|
name,
|
104
104
|
{:scope => #{options[:scope] || false}}
|
105
105
|
) do
|
106
|
-
#{uninstrumented_name}(*args, &block)
|
106
|
+
#{uninstrumented_name}(*args#{", **kwargs" if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?}, &block)
|
107
107
|
end
|
108
108
|
end
|
109
109
|
EOF
|
data/lib/scout_apm/version.rb
CHANGED
data/test/unit/tracer_test.rb
CHANGED
@@ -65,6 +65,31 @@ class TracerTest < Minitest::Test
|
|
65
65
|
assert_recorded(recorder, "Test", "name")
|
66
66
|
end
|
67
67
|
|
68
|
+
if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?
|
69
|
+
def test_instrument_method_with_keyword_args
|
70
|
+
initial_value = Warning[:deprecated]
|
71
|
+
Warning[:deprecated] = true
|
72
|
+
recorder = FakeRecorder.new
|
73
|
+
ScoutApm::Agent.instance.context.recorder = recorder
|
74
|
+
|
75
|
+
klass = Class.new { include ScoutApm::Tracer }
|
76
|
+
|
77
|
+
invoked = false
|
78
|
+
klass.send(:define_method, :work) { |run:| invoked = true }
|
79
|
+
klass.instrument_method(:work, :type => "Test", :name => "name")
|
80
|
+
|
81
|
+
args = { run: false }
|
82
|
+
assert_output(nil, '') do
|
83
|
+
klass.new.work(**args)
|
84
|
+
end
|
85
|
+
|
86
|
+
assert invoked, "instrumented code was not invoked"
|
87
|
+
assert_recorded(recorder, "Test", "name")
|
88
|
+
ensure
|
89
|
+
Warning[:deprecated] = initial_value
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
68
93
|
private
|
69
94
|
|
70
95
|
def assert_recorded(recorder, type, name)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scout_apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Haynes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -251,6 +251,7 @@ files:
|
|
251
251
|
- lib/scout_apm/auto_instrument/parser.rb
|
252
252
|
- lib/scout_apm/auto_instrument/rails.rb
|
253
253
|
- lib/scout_apm/background_job_integrations/delayed_job.rb
|
254
|
+
- lib/scout_apm/background_job_integrations/faktory.rb
|
254
255
|
- lib/scout_apm/background_job_integrations/legacy_sneakers.rb
|
255
256
|
- lib/scout_apm/background_job_integrations/que.rb
|
256
257
|
- lib/scout_apm/background_job_integrations/resque.rb
|
@@ -479,7 +480,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
479
480
|
- !ruby/object:Gem::Version
|
480
481
|
version: '0'
|
481
482
|
requirements: []
|
482
|
-
rubygems_version: 3.
|
483
|
+
rubygems_version: 3.1.2
|
483
484
|
signing_key:
|
484
485
|
specification_version: 4
|
485
486
|
summary: Ruby application performance monitoring
|