Skip to content

Commit 79f0453

Browse files
authored
Set user to the current scope via sidekiq middleware (#1469)
1 parent 53f0bd9 commit 79f0453

File tree

4 files changed

+130
-3
lines changed

4 files changed

+130
-3
lines changed

sentry-sidekiq/lib/sentry-sidekiq.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ class Railtie < ::Rails::Railtie
2626
Sidekiq.configure_server do |config|
2727
config.error_handlers << Sentry::Sidekiq::ErrorHandler.new
2828
config.server_middleware do |chain|
29-
chain.add Sentry::Sidekiq::SentryContextMiddleware
29+
chain.add Sentry::Sidekiq::SentryContextServerMiddleware
3030
end
3131
end
3232

33+
Sidekiq.configure_client do |config|
34+
config.client_middleware do |chain|
35+
chain.add Sentry::Sidekiq::SentryContextClientMiddleware
36+
end
37+
end

sentry-sidekiq/lib/sentry/sidekiq/sentry_context_middleware.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
module Sentry
44
module Sidekiq
5-
class SentryContextMiddleware
5+
class SentryContextServerMiddleware
66
def call(_worker, job, queue)
77
return yield unless Sentry.initialized?
88

99
context_filter = Sentry::Sidekiq::ContextFilter.new(job)
1010

1111
Sentry.clone_hub_to_current_thread
1212
scope = Sentry.get_current_scope
13+
if (user = job["sentry_user"])
14+
scope.set_user(user)
15+
end
1316
scope.set_tags(queue: queue, jid: job["jid"])
1417
scope.set_contexts(sidekiq: job.merge("queue" => queue))
1518
scope.set_transaction_name(context_filter.transaction_name)
@@ -36,5 +39,15 @@ def finish_transaction(transaction, status)
3639
transaction.finish
3740
end
3841
end
42+
43+
class SentryContextClientMiddleware
44+
def call(_worker_class, job, _queue, _redis_pool)
45+
return yield unless Sentry.initialized?
46+
47+
user = Sentry.get_current_scope.user
48+
job["sentry_user"] = user unless user.empty?
49+
yield
50+
end
51+
end
3952
end
4053
end
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
require "spec_helper"
2+
3+
RSpec.shared_context "sidekiq", shared_context: :metadata do
4+
let(:user) { { "id" => rand(10_000) } }
5+
6+
let(:client) do
7+
Sidekiq::Client.new.tap do |client|
8+
client.middleware do |chain|
9+
chain.add Sentry::Sidekiq::SentryContextClientMiddleware
10+
end
11+
end
12+
end
13+
14+
let(:random_empty_queue) do
15+
Sidekiq::Queue.new(rand(10_000)).tap do |queue|
16+
queue.clear
17+
end
18+
end
19+
end
20+
21+
RSpec.describe Sentry::Sidekiq::SentryContextServerMiddleware do
22+
include_context "sidekiq"
23+
24+
after { Sidekiq::RetrySet.new.clear }
25+
26+
it "sets user from the job to events" do
27+
perform_basic_setup { |config| config.traces_sample_rate = 1.0 }
28+
Sentry.set_user(user)
29+
30+
queue = random_empty_queue
31+
options = { queues: [queue.name] }
32+
processor = Sidekiq::Manager.new(options).workers.first
33+
34+
client.push('queue' => queue.name, 'class' => HappyWorker, 'args' => [])
35+
36+
expect { processor.send(:process_one) }.
37+
to change { Sentry.get_current_client.transport.events.size }.by(1)
38+
39+
event = Sentry.get_current_client.transport.events.first
40+
expect(event).not_to be_nil
41+
expect(event.user).to eq(user)
42+
end
43+
44+
it "sets user from the job to sidekiq event if worker raises an exception" do
45+
perform_basic_setup { |config| config.traces_sample_rate = 0 }
46+
Sentry.set_user(user)
47+
48+
queue = random_empty_queue
49+
options = { queues: [queue.name] }
50+
processor = Sidekiq::Manager.new(options).workers.first
51+
52+
client.push('queue' => queue.name, 'class' => SadWorker, 'args' => [])
53+
54+
expect do
55+
begin; processor.send(:process_one); rescue RuntimeError; end
56+
end.
57+
to change { Sentry.get_current_client.transport.events.size }.by(1)
58+
59+
Sentry.get_current_client.transport.events.each do |event|
60+
expect(event.user).to eq(user)
61+
end
62+
end
63+
64+
it "sets user from the job to sidekiq and error events if worker raises an exception when trace enabled" do
65+
perform_basic_setup { |config| config.traces_sample_rate = 1.0 }
66+
Sentry.set_user(user)
67+
68+
queue = random_empty_queue
69+
options = { queues: [queue.name] }
70+
processor = Sidekiq::Manager.new(options).workers.first
71+
72+
client.push('queue' => queue.name, 'class' => SadWorker, 'args' => [])
73+
74+
# XXX: In ruby 2.4, two events are pushed. In other versions, only one
75+
# event is pushed. Use by_at_least.
76+
expect do
77+
begin; processor.send(:process_one); rescue RuntimeError; end
78+
end.
79+
to change { Sentry.get_current_client.transport.events.size }.by_at_least(1)
80+
81+
Sentry.get_current_client.transport.events.each do |event|
82+
expect(event.user).to eq(user)
83+
end
84+
end
85+
end
86+
87+
RSpec.describe Sentry::Sidekiq::SentryContextClientMiddleware do
88+
include_context "sidekiq"
89+
90+
before { perform_basic_setup }
91+
92+
it "does not user to the job if user is absence in the current scope" do
93+
queue = random_empty_queue
94+
client.push('queue' => queue.name, 'class' => HappyWorker, 'args' => [])
95+
96+
expect(queue.size).to be(1)
97+
expect(queue.first["sentry_user"]).to be_nil
98+
end
99+
100+
it "sets user of the current scope to the job if present" do
101+
queue = random_empty_queue
102+
Sentry.set_user(user)
103+
104+
client.push('queue' => queue.name, 'class' => HappyWorker, 'args' => [])
105+
106+
expect(queue.size).to be(1)
107+
expect(queue.first["sentry_user"]).to eq(user)
108+
end
109+
end

sentry-sidekiq/spec/sentry/sidekiq_spec.rb

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

2525
it "registers error handlers and middlewares" do
2626
expect(Sidekiq.error_handlers).to include(described_class::ErrorHandler)
27-
expect(Sidekiq.server_middleware.entries.first.klass).to eq(described_class::SentryContextMiddleware)
27+
expect(Sidekiq.server_middleware.entries.first.klass).to eq(described_class::SentryContextServerMiddleware)
2828
end
2929

3030
it "captues exception raised in the worker" do

0 commit comments

Comments
 (0)