Skip to content

Commit 7ca57a6

Browse files
author
Eric Tipton
authored
Add sidekiq_use_scoped_block configuration option (#1038)
* extract scope-creation to .job_scope * Add sidekiq_use_scoped_block configuration option - Will use Rollbar.scoped s.t. calls to Rollbar.log will include the sidekiq scope * Sidekiq::ClearScope -> ResetScope, respect sidekiq_use_scoped_block option * Fix useless `private` directive * git mv spec/rollbar/sidekig/reset_scope_spec.rb spec/rollbar/sidekiq/
1 parent 49284e8 commit 7ca57a6

File tree

6 files changed

+134
-50
lines changed

6 files changed

+134
-50
lines changed

lib/rollbar/configuration.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class Configuration
5555
attr_accessor :uncaught_exception_level
5656
attr_accessor :scrub_headers
5757
attr_accessor :sidekiq_threshold
58+
attr_accessor :sidekiq_use_scoped_block
5859
attr_reader :transform
5960
attr_accessor :verify_ssl_peer
6061
attr_accessor :use_async
@@ -139,6 +140,7 @@ def initialize
139140
@uncaught_exception_level = 'error'
140141
@scrub_headers = ['Authorization']
141142
@sidekiq_threshold = 0
143+
@sidekiq_use_scoped_block = false
142144
@safely = false
143145
@transform = []
144146
@use_async = false

lib/rollbar/plugins/sidekiq.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
Sidekiq.configure_server do |config|
1111
config.server_middleware do |chain|
12-
chain.add Rollbar::Sidekiq::ClearScope
12+
chain.add Rollbar::Sidekiq::ResetScope
1313
end
1414

1515
config.error_handlers << proc do |e, context|

lib/rollbar/plugins/sidekiq/plugin.rb

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,47 @@ module Rollbar
44
class Sidekiq
55
PARAM_BLACKLIST = %w[backtrace error_backtrace error_message error_class].freeze
66

7-
class ClearScope
8-
def call(_worker, _msg, _queue)
9-
Rollbar.reset_notifier!
7+
class ResetScope
8+
def call(_worker, msg, _queue)
9+
Rollbar.reset_notifier! # clears scope
1010

11-
yield
11+
return yield unless Rollbar.configuration.sidekiq_use_scoped_block
12+
13+
Rollbar.scoped(Rollbar::Sidekiq.job_scope(msg)) { yield }
1214
end
1315
end
1416

15-
def self.handle_exception(ctx_hash, e)
16-
job_hash = ctx_hash && (ctx_hash[:job] || ctx_hash)
17-
return if skip_report?(job_hash, e)
17+
def self.handle_exception(msg, e)
18+
return if skip_report?(msg, e)
19+
20+
Rollbar.scope(job_scope(msg)).error(e, :use_exception_level_filters => true)
21+
end
22+
23+
def self.skip_report?(msg, _e)
24+
job_hash = job_hash_from_msg(msg)
25+
26+
return false if job_hash.nil?
27+
28+
# when rollbar middleware catches, sidekiq's retry_job processor hasn't set
29+
# the retry_count for the current job yet, so adding 1 gives the actual retry count
30+
actual_retry_count = job_hash.fetch('retry_count', -1) + 1
31+
job_hash['retry'] && actual_retry_count < ::Rollbar.configuration.sidekiq_threshold
32+
end
1833

34+
def self.job_scope(msg)
1935
scope = {
2036
:framework => "Sidekiq: #{::Sidekiq::VERSION}"
2137
}
38+
job_hash = job_hash_from_msg(msg)
39+
2240
unless job_hash.nil?
2341
params = job_hash.reject { |k| PARAM_BLACKLIST.include?(k) }
2442
scope[:request] = { :params => scrub_params(params) }
2543
scope[:context] = params['class']
2644
scope[:queue] = params['queue']
2745
end
2846

29-
Rollbar.scope(scope).error(e, :use_exception_level_filters => true)
47+
scope
3048
end
3149

3250
def self.scrub_params(params)
@@ -38,22 +56,21 @@ def self.scrub_params(params)
3856
Rollbar::Scrubbers::Params.call(options)
3957
end
4058

41-
def self.skip_report?(job_hash, _e)
42-
return false if job_hash.nil?
43-
44-
# when rollbar middleware catches, sidekiq's retry_job processor hasn't set
45-
# the retry_count for the current job yet, so adding 1 gives the actual retry count
46-
actual_retry_count = job_hash.fetch('retry_count', -1) + 1
47-
job_hash['retry'] && actual_retry_count < ::Rollbar.configuration.sidekiq_threshold
48-
end
49-
59+
# see https://github.com/mperham/sidekiq/wiki/Middleware#server-middleware
5060
def call(_worker, msg, _queue)
51-
Rollbar.reset_notifier!
61+
Rollbar.reset_notifier! # clears scope
5262

53-
yield
63+
return yield unless Rollbar.configuration.sidekiq_use_scoped_block
64+
65+
Rollbar.scoped(Rollbar::Sidekiq.job_scope(msg)) { yield }
5466
rescue Exception => e
5567
Rollbar::Sidekiq.handle_exception(msg, e)
5668
raise
5769
end
70+
71+
def self.job_hash_from_msg(msg)
72+
msg && (msg[:job] || msg)
73+
end
74+
private_class_method :job_hash_from_msg
5875
end
5976
end

spec/rollbar/plugins/sidekiq_spec.rb

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
}
2626
end
2727

28-
let(:ctx_hash) do
28+
let(:msg) do
2929
{ :context => 'Job raised exception', :job => job_hash }
3030
end
3131

@@ -40,42 +40,42 @@
4040
}
4141
end
4242

43-
it 'constructs scope from ctx hash' do
43+
it 'constructs scope from msg' do
4444
allow(rollbar).to receive(:error)
4545
expect(Rollbar).to receive(:scope).with(expected_scope) { rollbar }
4646

47-
described_class.handle_exception(ctx_hash, exception)
47+
described_class.handle_exception(msg, exception)
4848
end
4949

50-
context 'sidekiq < 4.2.3 ctx hash' do
51-
let(:ctx_hash) { job_hash }
50+
context 'sidekiq < 4.2.3 msg' do
51+
let(:msg) { job_hash }
5252

53-
it 'constructs scope from ctx hash' do
53+
it 'constructs scope from msg' do
5454
allow(rollbar).to receive(:error)
5555
expect(Rollbar).to receive(:scope).with(expected_scope) { rollbar }
5656

57-
described_class.handle_exception(ctx_hash, exception)
57+
described_class.handle_exception(msg, exception)
5858
end
5959
end
6060

61-
context 'sidekiq < 4.0.0 nil ctx hash from Launcher#actor_died' do
62-
let(:ctx_hash) { nil }
61+
context 'sidekiq < 4.0.0 nilmsg from Launcher#actor_died' do
62+
let(:msg) { nil }
6363

64-
it 'constructs scope from ctx hash' do
64+
it 'constructs scope from msg' do
6565
allow(rollbar).to receive(:error)
6666
expect(Rollbar).to receive(:scope).with(
6767
:framework => "Sidekiq: #{Sidekiq::VERSION}"
6868
) { rollbar }
6969

70-
described_class.handle_exception(ctx_hash, exception)
70+
described_class.handle_exception(msg, exception)
7171
end
7272
end
7373

7474
it 'sends the passed-in error to rollbar' do
7575
allow(Rollbar).to receive(:scope).and_return(rollbar)
7676
expect(rollbar).to receive(:error).with(exception, :use_exception_level_filters => true)
7777

78-
described_class.handle_exception(ctx_hash, exception)
78+
described_class.handle_exception(msg, exception)
7979
end
8080

8181
context 'with fields in job hash to be scrubbed' do
@@ -153,7 +153,7 @@
153153
end
154154

155155
describe '#call' do
156-
let(:msg) { ['hello'] }
156+
let(:msg) { { 'class' => 'SomeWorker', 'queue' => 'default' } }
157157
let(:exception) { StandardError.new('oh noes') }
158158
let(:middleware_block) { proc { raise exception } }
159159

@@ -165,5 +165,37 @@
165165

166166
expect { subject.call(nil, msg, nil, &middleware_block) }.to raise_error(exception)
167167
end
168+
169+
context 'when the block calls Rollbar.log without raising an error' do
170+
let(:middleware_block) { proc { Rollbar.log('warning', 'Danger, Will Robinson') } }
171+
172+
context 'and Rollbar.configuration.sidekiq_use_scoped_block is false (default)' do
173+
before do
174+
Rollbar.configuration.sidekiq_use_scoped_block = false
175+
end
176+
177+
it 'does NOT send the scope information to rollbar' do
178+
expect(Rollbar).to receive(:log) do
179+
expect(Rollbar.scope_object).not_to be_eql(described_class.job_scope(msg))
180+
end
181+
182+
subject.call(nil, msg, nil, &middleware_block)
183+
end
184+
end
185+
186+
context 'and Rollbar.configuration.sidekiq_use_scoped_block is true' do
187+
before do
188+
Rollbar.configuration.sidekiq_use_scoped_block = true
189+
end
190+
191+
it 'sends the scope information to rollbar' do
192+
expect(Rollbar).to receive(:log) do
193+
expect(Rollbar.scope_object).to be_eql(described_class.job_scope(msg))
194+
end
195+
196+
subject.call(nil, msg, nil, &middleware_block)
197+
end
198+
end
199+
end
168200
end
169201
end

spec/rollbar/sidekig/clear_scope_spec.rb

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require 'spec_helper'
2+
3+
require 'sidekiq'
4+
5+
Rollbar.plugins.load!
6+
7+
describe Rollbar::Sidekiq::ResetScope, :reconfigure_notifier => false do
8+
describe '#call' do
9+
let(:middleware_block) { proc {} }
10+
11+
it 'calls Rollbar.reset_notifier!' do
12+
expect(Rollbar).to receive(:reset_notifier!)
13+
14+
subject.call(nil, nil, nil, &middleware_block)
15+
end
16+
17+
context 'when the block calls Rollbar.log without raising an error' do
18+
let(:middleware_block) { proc { Rollbar.log('warning', 'Danger, Will Robinson') } }
19+
let(:msg) { { 'class' => 'SomeWorker', 'queue' => 'default' } }
20+
21+
context 'and Rollbar.configuration.sidekiq_use_scoped_block is false (default)' do
22+
before do
23+
Rollbar.configuration.sidekiq_use_scoped_block = false
24+
end
25+
26+
it 'does NOT send the scope information to rollbar' do
27+
expect(Rollbar).to receive(:log) do
28+
expect(Rollbar.scope_object).not_to be_eql(Rollbar::Sidekiq.job_scope(msg))
29+
end
30+
31+
subject.call(nil, msg, nil, &middleware_block)
32+
end
33+
end
34+
35+
context 'and Rollbar.configuration.sidekiq_use_scoped_block is true' do
36+
before do
37+
Rollbar.configuration.sidekiq_use_scoped_block = true
38+
end
39+
40+
it 'sends the scope information to rollbar' do
41+
expect(Rollbar).to receive(:log) do
42+
expect(Rollbar.scope_object).to be_eql(Rollbar::Sidekiq.job_scope(msg))
43+
end
44+
45+
subject.call(nil, msg, nil, &middleware_block)
46+
end
47+
end
48+
end
49+
end
50+
end

0 commit comments

Comments
 (0)