scout_apm 4.0.3 → 4.0.4

Sign up to get free protection for your applications and to get access to all the features.
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