appsignal 3.8.1 → 3.9.0

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: f68ce83624657d12b65c203950c7a92681d621bc9f5644fcc61d4123417e8e93
4
- data.tar.gz: ecda706a29b6aea7d52d3620cebb984495c85937acf561a596826fd57c457095
3
+ metadata.gz: 9957483552477f7eceba77181c904899b22ff6657db6782558b2fce96b9571e1
4
+ data.tar.gz: 36c1760ff247804c579bb0b7bf3db2aee1d4ed53ede1a1920d5a8a1fa762f032
5
5
  SHA512:
6
- metadata.gz: 9ec9d7754da4808d85efd335d8e9c00bca8f0e2c16f7a4a9246b9bd9d679519c7550202c1d2f809c786e117cde31c76c8c3405664b9878b9b8c61724a05dca14
7
- data.tar.gz: 955a45291f05e0df7456ae7bef0c7d9be55824b764429a6fffd72985ee252dcf83893e824a610d086c82c0050ae14bb6ddebc6baaf600946c1d50ce55a3ae4d7
6
+ metadata.gz: '068c51758a2d48731ea31a4854cf31ab002c62fd290796832dea372f68078cbe2da29b237eb006aab7b6936b6a85b437a1f28f01d6182fad03425933b73a0241'
7
+ data.tar.gz: 66832484c634de15a474774f49e8c38838faf4b71889c68c4ad7ef897d1ad64c119b926152a228117409103b657f8523599597394b989bbf87553d1c072bf5a1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # AppSignal for Ruby gem Changelog
2
2
 
3
+ ## 3.9.0
4
+
5
+ _Published on 2024-06-21._
6
+
7
+ ### Added
8
+
9
+ - [500b2b4b](https://github.com/appsignal/appsignal-ruby/commit/500b2b4bb57a29663a197ff063c672e6b0c44769) minor - Report Sidekiq errors when a job is dead/discarded. Configure the new `sidekiq_report_errors` config option to "discard" to only report errors when the job is not retried further.
10
+
11
+ ### Changed
12
+
13
+ - [c76952ff](https://github.com/appsignal/appsignal-ruby/commit/c76952ff5c8bd6e9d1d841a3aeb600b27494bb43) patch - Improve instrumentation for mounted Sinatra apps in Rails apps. The sample reported for the Sinatra request will now include the time spent in Rails and its middleware.
14
+ - [661b8e08](https://github.com/appsignal/appsignal-ruby/commit/661b8e08de962e8f95326f0bbc9c0061b8cc0a62) patch - Support apps that have multiple Appsignal::Rack::EventHandler-s in the middleware stack.
15
+ - [7382afa3](https://github.com/appsignal/appsignal-ruby/commit/7382afa3e9c89ce0c9f3430fb71825736e484e82) patch - Improve support for instrumentation of nested pure Rack and Sinatra apps. It will now report more of the request's duration and events. This also improves support for apps that have multiple Rack GenericInstrumentation or SinatraInstrumentation middlewares.
16
+
17
+ ### Fixed
18
+
19
+ - [2478eb19](https://github.com/appsignal/appsignal-ruby/commit/2478eb19f51c18433785347d02af18f405eeeabd) patch - Fix issue with AppSignal getting stuck in a boot loop when loading the Sinatra integration with: `require "appsignal/integrations/sinatra"`
20
+ This could happen in nested applications, like a Sinatra app in a Rails app. It will now use the first config AppSignal starts with.
21
+
3
22
  ## 3.8.1
4
23
 
5
24
  _Published on 2024-06-17._
@@ -47,6 +47,7 @@ module Appsignal
47
47
  ],
48
48
  :send_environment_metadata => true,
49
49
  :send_params => true,
50
+ :sidekiq_report_errors => "all",
50
51
  :transaction_debug_mode => false
51
52
  }.freeze
52
53
 
@@ -67,7 +68,7 @@ module Appsignal
67
68
 
68
69
  ENV_TO_KEY_MAPPING = {
69
70
  "APPSIGNAL_ACTIVE" => :active,
70
- "APPSIGNAL_ACTIVE_JOB_REPORT_ERRORS" => :activejob_report_errors,
71
+ "APPSIGNAL_ACTIVEJOB_REPORT_ERRORS" => :activejob_report_errors,
71
72
  "APPSIGNAL_APP_NAME" => :name,
72
73
  "APPSIGNAL_BIND_ADDRESS" => :bind_address,
73
74
  "APPSIGNAL_CA_FILE_PATH" => :ca_file_path,
@@ -108,6 +109,7 @@ module Appsignal
108
109
  "APPSIGNAL_SEND_ENVIRONMENT_METADATA" => :send_environment_metadata,
109
110
  "APPSIGNAL_SEND_PARAMS" => :send_params,
110
111
  "APPSIGNAL_SEND_SESSION_DATA" => :send_session_data,
112
+ "APPSIGNAL_SIDEKIQ_REPORT_ERRORS" => :sidekiq_report_errors,
111
113
  "APPSIGNAL_SKIP_SESSION_DATA" => :skip_session_data,
112
114
  "APPSIGNAL_STATSD_PORT" => :statsd_port,
113
115
  "APPSIGNAL_TRANSACTION_DEBUG_MODE" => :transaction_debug_mode,
@@ -117,7 +119,7 @@ module Appsignal
117
119
  }.freeze
118
120
  # @api private
119
121
  ENV_STRING_KEYS = %w[
120
- APPSIGNAL_ACTIVE_JOB_REPORT_ERRORS
122
+ APPSIGNAL_ACTIVEJOB_REPORT_ERRORS
121
123
  APPSIGNAL_APP_NAME
122
124
  APPSIGNAL_BIND_ADDRESS
123
125
  APPSIGNAL_CA_FILE_PATH
@@ -130,6 +132,7 @@ module Appsignal
130
132
  APPSIGNAL_LOGGING_ENDPOINT
131
133
  APPSIGNAL_PUSH_API_ENDPOINT
132
134
  APPSIGNAL_PUSH_API_KEY
135
+ APPSIGNAL_SIDEKIQ_REPORT_ERRORS
133
136
  APPSIGNAL_STATSD_PORT
134
137
  APPSIGNAL_WORKING_DIRECTORY_PATH
135
138
  APPSIGNAL_WORKING_DIR_PATH
@@ -563,6 +566,11 @@ module Appsignal
563
566
  config[:activejob_report_errors] = "all"
564
567
  end
565
568
 
569
+ if config_hash[:sidekiq_report_errors] == "discard" &&
570
+ !Appsignal::Hooks::SidekiqHook.version_5_1_or_higher?
571
+ config[:sidekiq_report_errors] = "all"
572
+ end
573
+
566
574
  config
567
575
  end
568
576
 
@@ -5,10 +5,23 @@ module Appsignal
5
5
  class SidekiqHook < Appsignal::Hooks::Hook
6
6
  register :sidekiq
7
7
 
8
- def dependencies_present?
8
+ def self.version_5_1_or_higher?
9
+ @version_5_1_or_higher ||=
10
+ if dependencies_present?
11
+ Gem::Version.new(::Sidekiq::VERSION) >= Gem::Version.new("5.1.0")
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ def self.dependencies_present?
9
18
  defined?(::Sidekiq)
10
19
  end
11
20
 
21
+ def dependencies_present?
22
+ self.class.dependencies_present?
23
+ end
24
+
12
25
  def install
13
26
  require "appsignal/integrations/sidekiq"
14
27
  Appsignal::Probes.register :sidekiq, Appsignal::Probes::SidekiqProbe
@@ -16,6 +29,10 @@ module Appsignal
16
29
  ::Sidekiq.configure_server do |config|
17
30
  config.error_handlers <<
18
31
  Appsignal::Integrations::SidekiqErrorHandler.new
32
+ if config.respond_to? :death_handlers
33
+ config.death_handlers <<
34
+ Appsignal::Integrations::SidekiqDeathHandler.new
35
+ end
19
36
 
20
37
  config.server_middleware do |chain|
21
38
  if chain.respond_to? :prepend
@@ -4,32 +4,51 @@ require "yaml"
4
4
 
5
5
  module Appsignal
6
6
  module Integrations
7
+ # Handler for job death events. We get notified when a job has exhausted
8
+ # its retries.
9
+ #
10
+ # This is called before the SidekiqErrorHandler so it doesn't need to worry
11
+ # about completing the transaction.
12
+ #
13
+ # Introduced in Sidekiq 5.1.
14
+ class SidekiqDeathHandler
15
+ def call(_job_context, exception)
16
+ return unless Appsignal.config[:sidekiq_report_errors] == "discard"
17
+
18
+ transaction = Appsignal::Transaction.current
19
+ transaction.set_error(exception)
20
+ end
21
+ end
22
+
7
23
  # Error handler for Sidekiq to report errors from jobs and internal Sidekiq
8
24
  # errors.
9
25
  #
10
26
  # @api private
11
27
  class SidekiqErrorHandler
28
+ # Sidekiq 7.1.5 introduced the third sidekiq_config argument. It is not
29
+ # given on older Sidekiq versions.
12
30
  def call(exception, sidekiq_context, _sidekiq_config = nil)
13
- transaction =
14
- if Appsignal::Transaction.current?
15
- Appsignal::Transaction.current
16
- else
17
- # Sidekiq error outside of the middleware scope.
18
- # Can be a job JSON parse error or some other error happening in
19
- # Sidekiq.
20
- transaction =
21
- Appsignal::Transaction.create(
22
- SecureRandom.uuid, # Newly generated job id
23
- Appsignal::Transaction::BACKGROUND_JOB,
24
- Appsignal::Transaction::GenericRequest.new({})
25
- )
26
- transaction.set_action_if_nil("SidekiqInternal")
27
- transaction.set_metadata("sidekiq_error", sidekiq_context[:context])
28
- transaction.params = { :jobstr => sidekiq_context[:jobstr] }
29
- transaction
31
+ if Appsignal::Transaction.current?
32
+ if Appsignal.config[:sidekiq_report_errors] == "all"
33
+ transaction = Appsignal::Transaction.current
34
+ transaction.set_error(exception)
30
35
  end
36
+ else
37
+ # Sidekiq error outside of the middleware scope.
38
+ # Can be a job JSON parse error or some other error happening in
39
+ # Sidekiq.
40
+ transaction =
41
+ Appsignal::Transaction.create(
42
+ SecureRandom.uuid, # Newly generated job id
43
+ Appsignal::Transaction::BACKGROUND_JOB,
44
+ Appsignal::Transaction::GenericRequest.new({})
45
+ )
46
+ transaction.set_action_if_nil("SidekiqInternal")
47
+ transaction.set_metadata("sidekiq_error", sidekiq_context[:context])
48
+ transaction.params = { :jobstr => sidekiq_context[:jobstr] }
49
+ transaction.set_error(exception)
50
+ end
31
51
 
32
- transaction.set_error(exception)
33
52
  Appsignal::Transaction.complete_current!
34
53
  end
35
54
  end
@@ -5,13 +5,15 @@ require "appsignal/rack/sinatra_instrumentation"
5
5
 
6
6
  Appsignal.internal_logger.debug("Loading Sinatra (#{Sinatra::VERSION}) integration")
7
7
 
8
- app_settings = ::Sinatra::Application.settings
9
- Appsignal.config = Appsignal::Config.new(
10
- app_settings.root || Dir.pwd,
11
- app_settings.environment
12
- )
8
+ unless Appsignal.active?
9
+ app_settings = ::Sinatra::Application.settings
10
+ Appsignal.config = Appsignal::Config.new(
11
+ app_settings.root || Dir.pwd,
12
+ app_settings.environment
13
+ )
13
14
 
14
- Appsignal.start_logger
15
- Appsignal.start
15
+ Appsignal.start_logger
16
+ Appsignal.start
17
+ end
16
18
 
17
19
  ::Sinatra::Base.use(Appsignal::Rack::SinatraBaseInstrumentation) if Appsignal.active?
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rack"
4
+
5
+ module Appsignal
6
+ # @api private
7
+ module Rack
8
+ class AbstractMiddleware
9
+ def initialize(app, options = {})
10
+ Appsignal.internal_logger.debug "Initializing #{self.class}"
11
+ @app = app
12
+ @options = options
13
+ @request_class = options.fetch(:request_class, ::Rack::Request)
14
+ @params_method = options.fetch(:params_method, :params)
15
+ @instrument_span_name = options.fetch(:instrument_span_name, "process.abstract")
16
+ end
17
+
18
+ def call(env)
19
+ if Appsignal.active?
20
+ request = request_for(env)
21
+ # Supported nested instrumentation middlewares by checking if there's
22
+ # already a transaction active for this request.
23
+ wrapped_instrumentation = env.key?(Appsignal::Rack::APPSIGNAL_TRANSACTION)
24
+ transaction =
25
+ if wrapped_instrumentation
26
+ env[Appsignal::Rack::APPSIGNAL_TRANSACTION]
27
+ else
28
+ Appsignal::Transaction.create(
29
+ SecureRandom.uuid,
30
+ Appsignal::Transaction::HTTP_REQUEST,
31
+ request
32
+ )
33
+ end
34
+
35
+ add_transaction_metadata_before(transaction, request)
36
+ if wrapped_instrumentation
37
+ instrument_wrapped_request(request, transaction)
38
+ else
39
+ # Set transaction on the request environment so other nested
40
+ # middleware can detect if there is parent instrumentation
41
+ # middleware active.
42
+ env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = transaction
43
+ instrument_request(request, transaction)
44
+ end
45
+ else
46
+ @app.call(env)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ # Another instrumentation middleware is active earlier in the stack, so
53
+ # don't report any exceptions here, the top instrumentation middleware
54
+ # will be the one reporting the exception.
55
+ #
56
+ # Either another {GenericInstrumentation} or {EventHandler} is higher in
57
+ # the stack and will report the exception and complete the transaction.
58
+ #
59
+ # @see {#instrument_request}
60
+ def instrument_wrapped_request(request, transaction)
61
+ instrument_app_call(request.env)
62
+ ensure
63
+ add_transaction_metadata_after(transaction, request)
64
+ end
65
+
66
+ # Instrument the request fully. This is used by the top instrumentation
67
+ # middleware in the middleware stack. Unlike
68
+ # {#instrument_wrapped_request} this will report any exceptions being
69
+ # raised.
70
+ #
71
+ # @see {#instrument_wrapped_request}
72
+ def instrument_request(request, transaction)
73
+ instrument_app_call(request.env)
74
+ rescue Exception => error # rubocop:disable Lint/RescueException
75
+ transaction.set_error(error)
76
+ raise error
77
+ ensure
78
+ add_transaction_metadata_after(transaction, request)
79
+
80
+ # Complete transaction because this is the top instrumentation middleware.
81
+ Appsignal::Transaction.complete_current!
82
+ end
83
+
84
+ def instrument_app_call(env)
85
+ Appsignal.instrument(@instrument_span_name) do
86
+ @app.call(env)
87
+ end
88
+ end
89
+
90
+ # Add metadata to the transaction based on the request environment.
91
+ # Override this method to set metadata before the app is called.
92
+ # Call `super` to also include the default set metadata.
93
+ def add_transaction_metadata_before(transaction, request)
94
+ params = params_for(request)
95
+ transaction.params = params if params
96
+ end
97
+
98
+ # Add metadata to the transaction based on the request environment.
99
+ # Override this method to set metadata after the app is called.
100
+ # Call `super` to also include the default set metadata.
101
+ def add_transaction_metadata_after(transaction, request)
102
+ default_action =
103
+ request.env["appsignal.route"] || request.env["appsignal.action"]
104
+ transaction.set_action_if_nil(default_action)
105
+ transaction.set_metadata("path", request.path)
106
+ transaction.set_metadata("method", request.request_method)
107
+ transaction.set_http_or_background_queue_start
108
+ end
109
+
110
+ def params_for(request)
111
+ return unless request.respond_to?(@params_method)
112
+
113
+ request.send(@params_method)
114
+ rescue => error
115
+ # Getting params from the request has been know to fail.
116
+ Appsignal.internal_logger.debug(
117
+ "Exception while getting params in #{self.class} from '#{@params_method}': #{error}"
118
+ )
119
+ nil
120
+ end
121
+
122
+ def request_for(env)
123
+ @request_class.new(env)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -3,6 +3,7 @@
3
3
  module Appsignal
4
4
  module Rack
5
5
  APPSIGNAL_TRANSACTION = "appsignal.transaction"
6
+ APPSIGNAL_EVENT_HANDLER_ID = "appsignal.event_handler_id"
6
7
  RACK_AFTER_REPLY = "rack.after_reply"
7
8
 
8
9
  class EventHandler
@@ -16,8 +17,22 @@ module Appsignal
16
17
  )
17
18
  end
18
19
 
20
+ attr_reader :id
21
+
22
+ def initialize
23
+ @id = SecureRandom.uuid
24
+ end
25
+
26
+ def request_handler?(given_id)
27
+ id == given_id
28
+ end
29
+
19
30
  def on_start(request, _response)
31
+ event_handler = self
20
32
  self.class.safe_execution("Appsignal::Rack::EventHandler#on_start") do
33
+ request.env[APPSIGNAL_EVENT_HANDLER_ID] ||= id
34
+ return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
35
+
21
36
  transaction = Appsignal::Transaction.create(
22
37
  SecureRandom.uuid,
23
38
  Appsignal::Transaction::HTTP_REQUEST,
@@ -29,6 +44,8 @@ module Appsignal
29
44
  request.env[RACK_AFTER_REPLY] << proc do
30
45
  Appsignal::Rack::EventHandler
31
46
  .safe_execution("Appsignal::Rack::EventHandler's after_reply") do
47
+ next unless event_handler.request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
48
+
32
49
  transaction.finish_event("process_request.rack", "", "")
33
50
  transaction.set_http_or_background_queue_start
34
51
 
@@ -48,6 +65,8 @@ module Appsignal
48
65
 
49
66
  def on_error(request, _response, error)
50
67
  self.class.safe_execution("Appsignal::Rack::EventHandler#on_error") do
68
+ return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
69
+
51
70
  transaction = request.env[APPSIGNAL_TRANSACTION]
52
71
  return unless transaction
53
72
 
@@ -57,6 +76,8 @@ module Appsignal
57
76
 
58
77
  def on_finish(request, response)
59
78
  self.class.safe_execution("Appsignal::Rack::EventHandler#on_finish") do
79
+ return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
80
+
60
81
  transaction = request.env[APPSIGNAL_TRANSACTION]
61
82
  return unless transaction
62
83
 
@@ -5,42 +5,15 @@ require "rack"
5
5
  module Appsignal
6
6
  # @api private
7
7
  module Rack
8
- class GenericInstrumentation
8
+ class GenericInstrumentation < AbstractMiddleware
9
9
  def initialize(app, options = {})
10
- Appsignal.internal_logger.debug "Initializing Appsignal::Rack::GenericInstrumentation"
11
- @app = app
12
- @options = options
10
+ options[:instrument_span_name] ||= "process_action.generic"
11
+ super
13
12
  end
14
13
 
15
- def call(env)
16
- if Appsignal.active?
17
- call_with_appsignal_monitoring(env)
18
- else
19
- @app.call(env)
20
- end
21
- end
22
-
23
- def call_with_appsignal_monitoring(env)
24
- request = ::Rack::Request.new(env)
25
- transaction = Appsignal::Transaction.create(
26
- SecureRandom.uuid,
27
- Appsignal::Transaction::HTTP_REQUEST,
28
- request
29
- )
30
- begin
31
- Appsignal.instrument("process_action.generic") do
32
- @app.call(env)
33
- end
34
- rescue Exception => error # rubocop:disable Lint/RescueException
35
- transaction.set_error(error)
36
- raise error
37
- ensure
38
- transaction.set_action_if_nil(env["appsignal.route"] || "unknown")
39
- transaction.set_metadata("path", request.path)
40
- transaction.set_metadata("method", request.request_method)
41
- transaction.set_http_or_background_queue_start
42
- Appsignal::Transaction.complete_current!
43
- end
14
+ def add_transaction_metadata_after(transaction, request)
15
+ super
16
+ transaction.set_action_if_nil("unknown")
44
17
  end
45
18
  end
46
19
  end
@@ -28,53 +28,29 @@ module Appsignal
28
28
  end
29
29
  end
30
30
 
31
- class SinatraBaseInstrumentation
31
+ class SinatraBaseInstrumentation < AbstractMiddleware
32
32
  attr_reader :raise_errors_on
33
33
 
34
34
  def initialize(app, options = {})
35
- Appsignal.internal_logger.debug "Initializing Appsignal::Rack::SinatraBaseInstrumentation"
36
- @app = app
37
- @options = options
38
- @raise_errors_on = raise_errors?(@app)
35
+ options[:request_class] ||= Sinatra::Request
36
+ options[:params_method] ||= :params
37
+ options[:instrument_span_name] ||= "process_action.sinatra"
38
+ super
39
+ @raise_errors_on = raise_errors?(app)
39
40
  end
40
41
 
41
- def call(env)
42
- if Appsignal.active?
43
- call_with_appsignal_monitoring(env)
44
- else
45
- @app.call(env)
46
- end
47
- end
42
+ private
48
43
 
49
- def call_with_appsignal_monitoring(env)
50
- options = { :force => @options.include?(:force) && @options[:force] }
51
- options.merge!(:params_method => @options[:params_method]) if @options[:params_method]
52
- request = @options.fetch(:request_class, Sinatra::Request).new(env)
53
- transaction = Appsignal::Transaction.create(
54
- SecureRandom.uuid,
55
- Appsignal::Transaction::HTTP_REQUEST,
56
- request,
57
- options
58
- )
59
- begin
60
- Appsignal.instrument("process_action.sinatra") do
61
- @app.call(env)
62
- end
63
- rescue Exception => error # rubocop:disable Lint/RescueException
64
- transaction.set_error(error)
65
- raise error
66
- ensure
67
- # If raise_error is off versions of Sinatra don't raise errors, but store
68
- # them in the sinatra.error env var.
69
- if !raise_errors_on && env["sinatra.error"] && !env["sinatra.skip_appsignal_error"]
70
- transaction.set_error(env["sinatra.error"])
71
- end
72
- transaction.set_action_if_nil(action_name(env))
73
- transaction.set_metadata("path", request.path)
74
- transaction.set_metadata("method", request.request_method)
75
- transaction.set_http_or_background_queue_start
76
- Appsignal::Transaction.complete_current!
44
+ def add_transaction_metadata_after(transaction, request)
45
+ env = request.env
46
+ transaction.set_action_if_nil(action_name(env))
47
+ # If raise_error is off versions of Sinatra don't raise errors, but store
48
+ # them in the sinatra.error env var.
49
+ if !raise_errors_on && env["sinatra.error"] && !env["sinatra.skip_appsignal_error"]
50
+ transaction.set_error(env["sinatra.error"])
77
51
  end
52
+
53
+ super
78
54
  end
79
55
 
80
56
  def action_name(env)
@@ -88,8 +64,6 @@ module Appsignal
88
64
  end
89
65
  end
90
66
 
91
- private
92
-
93
67
  def raise_errors?(app)
94
68
  app.respond_to?(:settings) &&
95
69
  app.settings.respond_to?(:raise_errors) &&
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- VERSION = "3.8.1"
4
+ VERSION = "3.9.0"
5
5
  end
data/lib/appsignal.rb CHANGED
@@ -326,6 +326,7 @@ require "appsignal/garbage_collection"
326
326
  require "appsignal/integrations/railtie" if defined?(::Rails)
327
327
  require "appsignal/transaction"
328
328
  require "appsignal/version"
329
+ require "appsignal/rack/abstract_middleware"
329
330
  require "appsignal/rack/generic_instrumentation"
330
331
  require "appsignal/rack/event_handler"
331
332
  require "appsignal/transmitter"
@@ -187,6 +187,7 @@ describe Appsignal::Config do
187
187
  :send_environment_metadata => true,
188
188
  :send_params => true,
189
189
  :send_session_data => true,
190
+ :sidekiq_report_errors => "all",
190
191
  :transaction_debug_mode => false
191
192
  )
192
193
  end
@@ -583,6 +584,33 @@ describe Appsignal::Config do
583
584
  end
584
585
  end
585
586
  end
587
+
588
+ context "sidekiq_report_errors" do
589
+ let(:config_options) { { :sidekiq_report_errors => "discard" } }
590
+ before do
591
+ if Appsignal::Hooks::SidekiqHook.instance_variable_defined?(:@version_5_1_or_higher)
592
+ Appsignal::Hooks::SidekiqHook.remove_instance_variable(:@version_5_1_or_higher)
593
+ end
594
+ end
595
+
596
+ context "when Sidekiq >= 5.1 and 'discard'" do
597
+ before { stub_const("Sidekiq::VERSION", "5.1.0") }
598
+
599
+ it "does not override the sidekiq_report_errors value" do
600
+ expect(config[:sidekiq_report_errors]).to eq("discard")
601
+ expect(config.override_config[:sidekiq_report_errors]).to be_nil
602
+ end
603
+ end
604
+
605
+ context "when Sidekiq < 5.1 and 'discard'" do
606
+ before { stub_const("Sidekiq::VERSION", "5.0.0") }
607
+
608
+ it "sets sidekiq_report_errors to 'all'" do
609
+ expect(config[:sidekiq_report_errors]).to eq("all")
610
+ expect(config.override_config[:sidekiq_report_errors]).to eq("all")
611
+ end
612
+ end
613
+ end
586
614
  end
587
615
 
588
616
  describe "config keys" do