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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b992479d1f96a3acca3f9cdbbafad0eb87e6fc88ec53e5de8f6360d01fe21eae
4
- data.tar.gz: 2bd72c79abe8628029ac8c541e0fccff18e54fe5d43558148daebe95e7418e0c
3
+ metadata.gz: 16b10ca7e3c7474546feb2b367438e9fabeb2c799e85608b96afb3ddea37b647
4
+ data.tar.gz: 044ced73909cff452e59bccf14e7dfcf344fd8f6262c5b633b0d3239995609fd
5
5
  SHA512:
6
- metadata.gz: edf84c2a3b8a60961e9f3452b2ca0f10b963501becd9d30889a0acb671ac39267ee44e31279a78ae6a6375365e9c06c9f8d24b8c8f426fa2e512be6c5b141a1f
7
- data.tar.gz: 713bd41d14c74e0655e38002195355263f9413fab013deddb67019437c193169968d26b6a33a058cf8480b8249bd7cf87a6ccf530f2a9b319c8fd1b5875af8e7
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'
@@ -11,7 +11,7 @@ module ScoutApm
11
11
  end
12
12
 
13
13
  def present?
14
- defined?(::Delayed::Job)
14
+ defined?(::Delayed::Worker)
15
15
  end
16
16
 
17
17
  def forking?
@@ -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 supports Module#prepend.
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
- # Ruby 1.8.7 seems to be fundamentally different in how gsub or regexes
49
- # work. This is a hack and will be removed as soon as we can drop
50
- # support
51
- if RUBY_VERSION == "1.8.7"
52
- ESCAPE_MAPPINGS = {
53
- "\b" => '\\b',
54
- "\t" => '\\t',
55
- "\n" => '\\n',
56
- "\f" => '\\f',
57
- "\r" => '\\r',
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)|
@@ -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
@@ -1,3 +1,3 @@
1
1
  module ScoutApm
2
- VERSION = "4.0.3"
2
+ VERSION = "4.0.4"
3
3
  end
@@ -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.3
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-01-20 00:00:00.000000000 Z
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.0.8
483
+ rubygems_version: 3.1.2
483
484
  signing_key:
484
485
  specification_version: 4
485
486
  summary: Ruby application performance monitoring