appsignal 2.11.2 → 2.11.7

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: 2207fe155b6aec1d0fa6e271f8257e5006db693f3d30d45da0f522185b5498a6
4
- data.tar.gz: 42f76f14cf36b7309ade272924f9137e763f0ca56446189d97ea83b8f95a12f6
3
+ metadata.gz: 45f78817cdaaf759d7bb0fd3109cb6a16557956b485f3c245a524651301de9fc
4
+ data.tar.gz: ca75043dbd897e34817fd24879be0c95fda398c06d1b8a73863da86847eb1f22
5
5
  SHA512:
6
- metadata.gz: af7b2665f84a0ef9dc8fb7806e0095b00f48aa6273a5e5d5a75bf3c59e0910123fb50fd0380b16d6b154bf0a6c0ec8a1b42ce990b02511eaa648372a1178ac1d
7
- data.tar.gz: cdbc11ff5c3e7e3b756a8e3ad4dcb1483d7e6772346e652b042e7b3e08e00130d39c2160ea7ef5e47c44f1c8818a678d0393828bf9730f456bab401393754ad0
6
+ metadata.gz: f9cc2e5f99efd70c3e1e53d1a14cccc6c3373a4aded2ef75b1b3112c6def42dfbf3114e05fd06bfadcf558c0bd4b5e1ebf027e5d258565a94d6f7562c1bfe66d
7
+ data.tar.gz: 88fb1e14b251c8188b45dd4594f65c849bbaa25333434b55353749c424b9d387dfd83c358947a46cdde1ace806c6da0117e99567a601111c4b8d77468826c4f5
data/.rubocop.yml CHANGED
@@ -13,6 +13,8 @@ AllCops:
13
13
  - "gemfiles/vendor/**/*"
14
14
  - "vendor/**/*"
15
15
  - "benchmark.rake"
16
+ - "lib/appsignal/integrations/object_ruby_modern.rb"
17
+ - "spec/lib/appsignal/integrations/object_spec.rb"
16
18
  DisplayCopNames: true
17
19
  UseCache: true
18
20
  CacheRootDirectory: ./tmp
@@ -31,7 +31,7 @@ global_job_config:
31
31
  prologue:
32
32
  commands:
33
33
  - checkout
34
- - git -C /home/semaphore/.rbenv/plugins/ruby-build pull
34
+ - rm -f $HOME/.rbenv/plugins/rbenv-gem-rehash/etc/rbenv.d/exec/~gem-rehash.bash
35
35
  - sem-version ruby $RUBY_VERSION
36
36
  - "./support/check_versions"
37
37
  - cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ # 2.11.7
4
+ - Fix ActionCable integration in test environment using `stub_connection`.
5
+ PR #705
6
+
7
+ # 2.11.6
8
+ - Prepend Sidekiq middleware to wrap all Sidekiq middleware. Catches more
9
+ errors and provide more complete performance measurements. PR #698
10
+
11
+ # 2.11.5
12
+ - Add more detailed logging to finish_event calls when the event is unknown, so
13
+ we know what event is being tried to finish. Commit
14
+ c888a04d1b9ac947652b29c111c650fb5a5cf71c
15
+
16
+ # 2.11.4
17
+ - Support Ruby 3.0 for Object method instrumentation with keyword arguments
18
+ (https://docs.appsignal.com/ruby/instrumentation/method-instrumentation.html)
19
+ PR #693
20
+
21
+ # 2.11.3
22
+ - Support Shoryuken batch workers. PR #687
23
+
3
24
  # 2.11.2
4
25
  - Support Ruby 3.0. PR #681
5
26
  - Support breadcrumbs. PR #666
data/Rakefile CHANGED
@@ -275,7 +275,8 @@ namespace :publish do
275
275
  Dir.chdir("#{File.dirname(__FILE__)}/pkg") do
276
276
  Dir["*.gem"].each do |gem_package|
277
277
  puts "## Publishing gem package: #{gem_package}"
278
- system "gem push #{gem_package}"
278
+ result = system "gem push #{gem_package}"
279
+ raise "Failed to Push gem" unless result
279
280
  end
280
281
  end
281
282
  end
@@ -374,19 +375,21 @@ end
374
375
  begin
375
376
  require "rspec/core/rake_task"
376
377
  is_jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
377
- unless is_jruby
378
- jruby_opts = "--exclude-pattern=spec/lib/appsignal/extension/jruby_spec.rb"
379
- end
378
+ excludes = []
379
+ excludes << "spec/lib/appsignal/extension/jruby_spec.rb" unless is_jruby
380
+ is_ruby19 = RUBY_VERSION < "2.0"
381
+ excludes << "spec/lib/appsignal/integrations/object_spec.rb" if is_ruby19
382
+ exclude_pattern = "--exclude-pattern=#{excludes.join(",")}" if excludes.any?
380
383
 
381
384
  desc "Run the AppSignal gem test suite."
382
385
  RSpec::Core::RakeTask.new :test do |t|
383
- t.rspec_opts = jruby_opts
386
+ t.rspec_opts = exclude_pattern
384
387
  end
385
388
 
386
389
  namespace :test do
387
390
  desc "Run the Appsignal gem test in an extension failure scenario"
388
391
  RSpec::Core::RakeTask.new :failure do |t|
389
- t.rspec_opts = "#{jruby_opts} --tag extension_installation_failure"
392
+ t.rspec_opts = "#{exclude_pattern} --tag extension_installation_failure"
390
393
  end
391
394
  end
392
395
  rescue LoadError # rubocop:disable Lint/HandleExceptions
data/build_matrix.yml CHANGED
@@ -32,7 +32,7 @@ semaphore: # Default `.semaphore/semaphore.yml` contents
32
32
  prologue:
33
33
  commands:
34
34
  - checkout
35
- - git -C /home/semaphore/.rbenv/plugins/ruby-build pull
35
+ - rm -f $HOME/.rbenv/plugins/rbenv-gem-rehash/etc/rbenv.d/exec/~gem-rehash.bash
36
36
  - sem-version ruby $RUBY_VERSION
37
37
  - ./support/check_versions
38
38
  - cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
data/ext/agent.yml CHANGED
@@ -1,62 +1,62 @@
1
1
  ---
2
- version: 361340a
2
+ version: d98461b
3
3
  mirrors:
4
4
  - https://appsignal-agent-releases.global.ssl.fastly.net
5
5
  - https://d135dj0rjqvssy.cloudfront.net
6
6
  triples:
7
7
  x86_64-darwin:
8
8
  static:
9
- checksum: 4e08cb0cef0ea7e30f8d507380b923f6cfa14adaea12c81804e118acd6395b57
9
+ checksum: 178ab2329c7b29cf45140e4707e75c20379fa0c7dfd7f39266a7a95aea510780
10
10
  filename: appsignal-x86_64-darwin-all-static.tar.gz
11
11
  dynamic:
12
- checksum: 1a9c3e26bd453fe60a2f511d536e64bdeddb1f939664bda90d6a41eaeedf5250
12
+ checksum: '0923985cc78c5cf278f45d530679954b94b1a91c87453369116fc05525e29864'
13
13
  filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
14
14
  universal-darwin:
15
15
  static:
16
- checksum: 4e08cb0cef0ea7e30f8d507380b923f6cfa14adaea12c81804e118acd6395b57
16
+ checksum: 178ab2329c7b29cf45140e4707e75c20379fa0c7dfd7f39266a7a95aea510780
17
17
  filename: appsignal-x86_64-darwin-all-static.tar.gz
18
18
  dynamic:
19
- checksum: 1a9c3e26bd453fe60a2f511d536e64bdeddb1f939664bda90d6a41eaeedf5250
19
+ checksum: '0923985cc78c5cf278f45d530679954b94b1a91c87453369116fc05525e29864'
20
20
  filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
21
21
  i686-linux:
22
22
  static:
23
- checksum: 01c027b3e472cb39d844284fcc8ba532628c00731b912e0e9718646ed124ae6e
23
+ checksum: cb772a8a178edb25d666b650efda80149c98e80e4264435d6176f8a6104f959a
24
24
  filename: appsignal-i686-linux-all-static.tar.gz
25
25
  dynamic:
26
- checksum: 30696eac3ae5646bcb21ff86a1824dd4511a41dd323514e4a97a41b5ff09e2f8
26
+ checksum: c9ac51f4d1b3cc13773d8fa8ea5cfad6af7909144d85186cef9324ec0531bdac
27
27
  filename: appsignal-i686-linux-all-dynamic.tar.gz
28
28
  x86-linux:
29
29
  static:
30
- checksum: 01c027b3e472cb39d844284fcc8ba532628c00731b912e0e9718646ed124ae6e
30
+ checksum: cb772a8a178edb25d666b650efda80149c98e80e4264435d6176f8a6104f959a
31
31
  filename: appsignal-i686-linux-all-static.tar.gz
32
32
  dynamic:
33
- checksum: 30696eac3ae5646bcb21ff86a1824dd4511a41dd323514e4a97a41b5ff09e2f8
33
+ checksum: c9ac51f4d1b3cc13773d8fa8ea5cfad6af7909144d85186cef9324ec0531bdac
34
34
  filename: appsignal-i686-linux-all-dynamic.tar.gz
35
35
  x86_64-linux:
36
36
  static:
37
- checksum: fe2038d6fa468fc23900fea6d8179d2b37d41d54f4ff33c573116183ac1cb491
37
+ checksum: d6c280e992d74f97d59da9827ec5707ca4f6776b0568cde1c083c1113e4b7104
38
38
  filename: appsignal-x86_64-linux-all-static.tar.gz
39
39
  dynamic:
40
- checksum: bcbf9546b078fb8bbaae5e7df4ed84831346c814bc865a47d32a3a095a84acbb
40
+ checksum: ef1a3f5d4b2ed61ea2ae4d5cb1a261a0e685fb9d3e7ea9efe455498aad386e59
41
41
  filename: appsignal-x86_64-linux-all-dynamic.tar.gz
42
42
  x86_64-linux-musl:
43
43
  static:
44
- checksum: b2ee5579a62b76a1d2f41f4e06749c4c549f9aaa40764862eff49c5a6a8841f1
44
+ checksum: 9cf8ad34392662746a45cfce18113ad19cc29954789e2058f30e527163f2e98a
45
45
  filename: appsignal-x86_64-linux-musl-all-static.tar.gz
46
46
  dynamic:
47
- checksum: 53cd2464853e61c2d8f911ec32ff98cb48f824293ffd575da6743bc34625a7eb
47
+ checksum: 01bd76983227648d9bc41d035e1552fcf18d62f0d6818bf7bb7fc2e7c166513d
48
48
  filename: appsignal-x86_64-linux-musl-all-dynamic.tar.gz
49
49
  x86_64-freebsd:
50
50
  static:
51
- checksum: f228dd2f2cf951c9eb9f04487be50fdfdc3d29a956e639787a4022bd73f02e53
51
+ checksum: 403a597cbdbdba08460c5c9e93347ed9ad1d24333204e6d72db342deb266a296
52
52
  filename: appsignal-x86_64-freebsd-all-static.tar.gz
53
53
  dynamic:
54
- checksum: 030b322b2cb15607260cbb0424c03f6e41646dca7aacc43a30279ad63a336541
54
+ checksum: a1faae80ae09a6588c4cd35cb91dfa4b2176fc3cb17fbf79db80194c21e75bf9
55
55
  filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
56
56
  amd64-freebsd:
57
57
  static:
58
- checksum: f228dd2f2cf951c9eb9f04487be50fdfdc3d29a956e639787a4022bd73f02e53
58
+ checksum: 403a597cbdbdba08460c5c9e93347ed9ad1d24333204e6d72db342deb266a296
59
59
  filename: appsignal-x86_64-freebsd-all-static.tar.gz
60
60
  dynamic:
61
- checksum: 030b322b2cb15607260cbb0424c03f6e41646dca7aacc43a30279ad63a336541
61
+ checksum: a1faae80ae09a6588c4cd35cb91dfa4b2176fc3cb17fbf79db80194c21e75bf9
62
62
  filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
@@ -56,7 +56,11 @@ module Appsignal
56
56
  def install_callbacks
57
57
  ActionCable::Channel::Base.set_callback :subscribe, :around, :prepend => true do |channel, inner|
58
58
  # The request is only the original websocket request
59
- env = channel.connection.env
59
+ connection = channel.connection
60
+ # #env is not available on the Rails ConnectionStub class used in the
61
+ # Rails app test suite. If we call `#env` it causes an error to occur
62
+ # in apps' test suites.
63
+ env = connection.respond_to?(:env) ? connection.env : {}
60
64
  request = ActionDispatch::Request.new(env)
61
65
  env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||=
62
66
  request.request_id || SecureRandom.uuid
@@ -84,7 +88,11 @@ module Appsignal
84
88
 
85
89
  ActionCable::Channel::Base.set_callback :unsubscribe, :around, :prepend => true do |channel, inner|
86
90
  # The request is only the original websocket request
87
- env = channel.connection.env
91
+ connection = channel.connection
92
+ # #env is not available on the Rails ConnectionStub class used in the
93
+ # Rails app test suite. If we call `#env` it causes an error to occur
94
+ # in apps' test suites.
95
+ env = connection.respond_to?(:env) ? connection.env : {}
88
96
  request = ActionDispatch::Request.new(env)
89
97
  env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||=
90
98
  request.request_id || SecureRandom.uuid
@@ -5,21 +5,60 @@ module Appsignal
5
5
  # @api private
6
6
  class ShoryukenMiddleware
7
7
  def call(worker_instance, queue, sqs_msg, body)
8
- metadata = { :queue => queue }.merge(sqs_msg.attributes)
8
+ batch = sqs_msg.is_a?(Array)
9
+ attributes =
10
+ if batch
11
+ # We can't instrument batched message separately, the `yield` will
12
+ # perform all the batched messages.
13
+ # To provide somewhat useful metadata, Get first message based on
14
+ # SentTimestamp, and use its attributes as metadata for the
15
+ # transaction. We can't combine them all because then they would
16
+ # overwrite each other and the last message (in an sorted order)
17
+ # would be used as the source of the metadata. With the
18
+ # oldest/first message at least some useful information is stored
19
+ # such as the first received time and the number of retries for the
20
+ # first message. The newer message should have lower values and
21
+ # timestamps in their metadata.
22
+ first_msg = sqs_msg.min do |a, b|
23
+ a.attributes["SentTimestamp"].to_i <=> b.attributes["SentTimestamp"].to_i
24
+ end
25
+ # Add batch => true metadata so people can recognize when a
26
+ # transaction is about a batch of messages.
27
+ first_msg.attributes.merge(:batch => true)
28
+ else
29
+ sqs_msg.attributes.merge(:message_id => sqs_msg.message_id)
30
+ end
31
+ metadata = { :queue => queue }.merge(attributes)
9
32
  options = {
10
33
  :class => worker_instance.class.name,
11
34
  :method => "perform",
12
35
  :metadata => metadata
13
36
  }
14
37
 
15
- args = body.is_a?(Hash) ? body : { :params => body }
38
+ args =
39
+ if batch
40
+ bodies = {}
41
+ sqs_msg.each_with_index do |msg, index|
42
+ # Store all separate bodies on a hash with the key being the
43
+ # message_id
44
+ bodies[msg.message_id] = body[index]
45
+ end
46
+ bodies
47
+ else
48
+ case body
49
+ when Hash
50
+ body
51
+ else
52
+ { :params => body }
53
+ end
54
+ end
16
55
  options[:params] = Appsignal::Utils::HashSanitizer.sanitize(
17
56
  args,
18
57
  Appsignal.config[:filter_parameters]
19
58
  )
20
59
 
21
- if sqs_msg.attributes.key?("SentTimestamp")
22
- options[:queue_start] = Time.at(sqs_msg.attributes["SentTimestamp"].to_i / 1000)
60
+ if attributes.key?("SentTimestamp")
61
+ options[:queue_start] = Time.at(attributes["SentTimestamp"].to_i / 1000)
23
62
  end
24
63
 
25
64
  Appsignal.monitor_transaction("perform_job.shoryuken", options) do
@@ -16,7 +16,11 @@ module Appsignal
16
16
 
17
17
  ::Sidekiq.configure_server do |config|
18
18
  config.server_middleware do |chain|
19
- chain.add Appsignal::Hooks::SidekiqPlugin
19
+ if chain.respond_to? :prepend
20
+ chain.prepend Appsignal::Hooks::SidekiqPlugin
21
+ else
22
+ chain.add Appsignal::Hooks::SidekiqPlugin
23
+ end
20
24
  end
21
25
  end
22
26
  end
@@ -4,38 +4,8 @@ if defined?(Appsignal)
4
4
  Appsignal::Environment.report_enabled("object_instrumentation")
5
5
  end
6
6
 
7
- class Object
8
- def self.appsignal_instrument_class_method(method_name, options = {})
9
- singleton_class.send \
10
- :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
11
- singleton_class.send(:define_method, method_name) do |*args, &block|
12
- name = options.fetch(:name) do
13
- "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
14
- end
15
- Appsignal.instrument name do
16
- send "appsignal_uninstrumented_#{method_name}", *args, &block
17
- end
18
- end
19
- end
20
-
21
- def self.appsignal_instrument_method(method_name, options = {})
22
- alias_method "appsignal_uninstrumented_#{method_name}", method_name
23
- define_method method_name do |*args, &block|
24
- name = options.fetch(:name) do
25
- "#{method_name}.#{appsignal_reverse_class_name}.other"
26
- end
27
- Appsignal.instrument name do
28
- send "appsignal_uninstrumented_#{method_name}", *args, &block
29
- end
30
- end
31
- end
32
-
33
- def self.appsignal_reverse_class_name
34
- return "AnonymousClass" unless name
35
- name.split("::").reverse.join(".")
36
- end
37
-
38
- def appsignal_reverse_class_name
39
- self.class.appsignal_reverse_class_name
40
- end
7
+ if RUBY_VERSION < "2.0"
8
+ require "appsignal/integrations/object_ruby_19"
9
+ else
10
+ require "appsignal/integrations/object_ruby_modern"
41
11
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
4
+ def self.appsignal_instrument_class_method(method_name, options = {})
5
+ singleton_class.send \
6
+ :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
7
+ singleton_class.send(:define_method, method_name) do |*args, &block|
8
+ name = options.fetch(:name) do
9
+ "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
10
+ end
11
+ Appsignal.instrument name do
12
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
13
+ end
14
+ end
15
+ end
16
+
17
+ def self.appsignal_instrument_method(method_name, options = {})
18
+ alias_method "appsignal_uninstrumented_#{method_name}", method_name
19
+ define_method method_name do |*args, &block|
20
+ name = options.fetch(:name) do
21
+ "#{method_name}.#{appsignal_reverse_class_name}.other"
22
+ end
23
+ Appsignal.instrument name do
24
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.appsignal_reverse_class_name
30
+ return "AnonymousClass" unless name
31
+ name.split("::").reverse.join(".")
32
+ end
33
+
34
+ def appsignal_reverse_class_name
35
+ self.class.appsignal_reverse_class_name
36
+ end
37
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
4
+ if Appsignal::System.ruby_2_7_or_newer?
5
+ def self.appsignal_instrument_class_method(method_name, options = {})
6
+ singleton_class.send \
7
+ :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
8
+ singleton_class.send(:define_method, method_name) do |*args, **kwargs, &block|
9
+ name = options.fetch(:name) do
10
+ "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
11
+ end
12
+ Appsignal.instrument name do
13
+ send "appsignal_uninstrumented_#{method_name}", *args, **kwargs, &block
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.appsignal_instrument_method(method_name, options = {})
19
+ alias_method "appsignal_uninstrumented_#{method_name}", method_name
20
+ define_method method_name do |*args, **kwargs, &block|
21
+ name = options.fetch(:name) do
22
+ "#{method_name}.#{appsignal_reverse_class_name}.other"
23
+ end
24
+ Appsignal.instrument name do
25
+ send "appsignal_uninstrumented_#{method_name}", *args, **kwargs, &block
26
+ end
27
+ end
28
+ end
29
+ else
30
+ def self.appsignal_instrument_class_method(method_name, options = {})
31
+ singleton_class.send \
32
+ :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
33
+ singleton_class.send(:define_method, method_name) do |*args, &block|
34
+ name = options.fetch(:name) do
35
+ "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
36
+ end
37
+ Appsignal.instrument name do
38
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
39
+ end
40
+ end
41
+ end
42
+
43
+ def self.appsignal_instrument_method(method_name, options = {})
44
+ alias_method "appsignal_uninstrumented_#{method_name}", method_name
45
+ define_method method_name do |*args, &block|
46
+ name = options.fetch(:name) do
47
+ "#{method_name}.#{appsignal_reverse_class_name}.other"
48
+ end
49
+ Appsignal.instrument name do
50
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.appsignal_reverse_class_name
57
+ return "AnonymousClass" unless name
58
+ name.split("::").reverse.join(".")
59
+ end
60
+
61
+ def appsignal_reverse_class_name
62
+ self.class.appsignal_reverse_class_name
63
+ end
64
+ end
@@ -79,5 +79,9 @@ module Appsignal
79
79
  def self.jruby?
80
80
  RUBY_PLATFORM == "java"
81
81
  end
82
+
83
+ def self.ruby_2_7_or_newer?
84
+ RUBY_VERSION > "2.7"
85
+ end
82
86
  end
83
87
  end