appsignal 2.3.6 → 2.3.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
  SHA1:
3
- metadata.gz: 686ed70481e3668fbca7d42179d37968c9d86ee4
4
- data.tar.gz: 0b3e7528800d36741eedf5b245f5f16291ef1cb5
3
+ metadata.gz: ed63c49d1dfc2fc2760647e86a0721f9a1476d8b
4
+ data.tar.gz: 5af04584576a18ea0c42e2fb2a2188d0361b826b
5
5
  SHA512:
6
- metadata.gz: 5594d88adbffbdd61ea850bf13747156fb7cf864585fd70b98a6f910177277cb361b2e31915327d662159def58d761b190990b30307136485aa45c684e22d371
7
- data.tar.gz: 894261c72b60a1d21e7c27e2ed7ed2e821211173223e21239118f96d8969ecae8ef9ab563a42e44725e6cde979dc081242f3ea11d0328d8f1e78512f75932d45
6
+ metadata.gz: 799f054a927e0dd89a7c8775f34b91d271075c25838826589959223be286bbf6ccc8297b0ad97eac00bd1cd6bae52573380ed7b69abd87037ad70ce87552856c
7
+ data.tar.gz: 719aaed0e8e4e9cc6e398f6ad7a509073e65c19d959b678221e026bc4d15bc478f7fda4541878561bf146c53668c8f8cfc657763a2c54806db2b8214662307af
@@ -30,6 +30,7 @@ gemfile:
30
30
  - "gemfiles/resque.gemfile"
31
31
  - "gemfiles/sequel.gemfile"
32
32
  - "gemfiles/sequel-435.gemfile"
33
+ - "gemfiles/sidekiq.gemfile"
33
34
  - "gemfiles/sinatra.gemfile"
34
35
  - "gemfiles/grape.gemfile"
35
36
  - "gemfiles/webmachine.gemfile"
@@ -41,6 +42,12 @@ matrix:
41
42
  gemfile: "gemfiles/no_dependencies.gemfile"
42
43
  script: "bundle exec rubocop"
43
44
  exclude:
45
+ - rvm: "2.0.0"
46
+ gemfile: "gemfiles/sidekiq.gemfile"
47
+ - rvm: "2.1.8"
48
+ gemfile: "gemfiles/sidekiq.gemfile"
49
+ - rvm: "jruby-19mode"
50
+ gemfile: "gemfiles/sidekiq.gemfile"
44
51
  - rvm: "2.0.0"
45
52
  gemfile: "gemfiles/rails-5.0.gemfile"
46
53
  - rvm: "2.1.8"
@@ -1,3 +1,9 @@
1
+ # 2.3.7
2
+ * Support Sidekiq delayed extension job action names better. Now action names
3
+ are reported as their class and class method name (`MyClass.method`), rather
4
+ than `Sidekiq::Extensions::DelayedClass#perform` for all jobs through that
5
+ extension. PR #348
6
+
1
7
  # 2.3.6
2
8
  * Allow configuration of permissions of working directory. PR #336
3
9
  * Fix locking bug that delayed extension shutdown.
@@ -5,6 +11,10 @@
5
11
  * Log extension start with app revision if present
6
12
  Commit 51d90bb1207affc2c88f7cff5035a2c36acf9784
7
13
 
14
+ # 2.3.5
15
+
16
+ Yanked
17
+
8
18
  # 2.3.4
9
19
  * Fix naming for ActiveJob integration with DelayedJob. PR #345
10
20
 
data/Rakefile CHANGED
@@ -14,6 +14,7 @@ GEMFILES = %w(
14
14
  resque
15
15
  sequel
16
16
  sequel-435
17
+ sidekiq
17
18
  sinatra
18
19
  grape
19
20
  webmachine
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sidekiq'
4
+
5
+ gemspec :path => '../'
@@ -14,32 +14,78 @@ module Appsignal
14
14
  end
15
15
 
16
16
  def call(_worker, item, _queue)
17
- args =
18
- if item["class"] == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
19
- item["args"].first["arguments"]
20
- else
21
- item["args"]
22
- end
23
- params = Appsignal::Utils::ParamsSanitizer.sanitize args,
17
+ job = fetch_sidekiq_job { ::Sidekiq::Job.new(item) }
18
+ job_metadata = call_and_log_on_error(job, &:item)
19
+
20
+ job_action_name = parse_action_name(job)
21
+ params = Appsignal::Utils::ParamsSanitizer.sanitize(
22
+ call_and_log_on_error(job, &:display_args),
24
23
  :filter_parameters => Appsignal.config[:filter_parameters]
24
+ )
25
+
26
+ transaction = Appsignal::Transaction.create(
27
+ SecureRandom.uuid,
28
+ Appsignal::Transaction::BACKGROUND_JOB,
29
+ Appsignal::Transaction::GenericRequest.new(
30
+ :queue_start => call_and_log_on_error(job, &:enqueued_at),
31
+ :queue_time => call_and_log_on_error(job) { |j| j.latency.to_f * 1000 }
32
+ )
33
+ )
34
+
35
+ Appsignal.instrument "perform_job.sidekiq" do
36
+ begin
37
+ yield
38
+ rescue Exception => exception # rubocop:disable Lint/RescueException
39
+ transaction.set_error(exception)
40
+ raise exception
41
+ end
42
+ end
43
+ ensure
44
+ if transaction
45
+ transaction.set_action_if_nil(job_action_name)
46
+ transaction.params = params
47
+ formatted_metadata(job_metadata).each do |key, value|
48
+ transaction.set_metadata key, value
49
+ end
50
+ transaction.set_http_or_background_queue_start
51
+ Appsignal::Transaction.complete_current!
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def fetch_sidekiq_job
58
+ yield
59
+ rescue NameError => e
60
+ Appsignal.logger.error("Problem parsing the Sidekiq job data: #{e.inspect}")
61
+ nil
62
+ end
63
+
64
+ def call_and_log_on_error(job)
65
+ yield job if job
66
+ rescue NameError => e
67
+ Appsignal.logger.error("Problem parsing the Sidekiq job data: #{e.inspect}")
68
+ nil
69
+ end
25
70
 
26
- Appsignal.monitor_transaction(
27
- "perform_job.sidekiq",
28
- :class => item["wrapped"] || item["class"],
29
- :method => "perform",
30
- :metadata => formatted_metadata(item),
31
- :params => params,
32
- :queue_start => item["enqueued_at"],
33
- :queue_time => (Time.now.to_f - item["enqueued_at"].to_f) * 1000
34
- ) do
35
- yield
71
+ def parse_action_name(job)
72
+ # `job.display_class` needs to be called before `job.display_args`,
73
+ # see https://github.com/appsignal/appsignal-ruby/pull/348#issuecomment-333629065
74
+ action_name = call_and_log_on_error(job, &:display_class)
75
+ if action_name =~ /[\.#]+/
76
+ action_name
77
+ else
78
+ # Add `#perform` as default method name for job names without a
79
+ # method name
80
+ "#{action_name}#perform"
36
81
  end
37
82
  end
38
83
 
39
84
  def formatted_metadata(item)
40
- {}.tap do |hsh|
41
- item.each do |key, val|
42
- hsh[key] = truncate(string_or_inspect(val)) unless job_keys.include?(key)
85
+ {}.tap do |hash|
86
+ (item || {}).each do |key, value|
87
+ next if job_keys.include?(key)
88
+ hash[key] = truncate(string_or_inspect(value))
43
89
  end
44
90
  end
45
91
  end
@@ -53,6 +99,7 @@ module Appsignal
53
99
  end
54
100
 
55
101
  def install
102
+ require "sidekiq/api"
56
103
  ::Sidekiq.configure_server do |config|
57
104
  config.server_middleware do |chain|
58
105
  chain.add Appsignal::Hooks::SidekiqPlugin
@@ -54,6 +54,12 @@ module Appsignal
54
54
  rescue => e
55
55
  Appsignal.logger.error("Failed to complete transaction ##{current.transaction_id}. #{e.message}")
56
56
  ensure
57
+ clear_current_transaction!
58
+ end
59
+
60
+ # Remove current transaction from current Thread.
61
+ # @api private
62
+ def clear_current_transaction!
57
63
  Thread.current[:appsignal_transaction] = nil
58
64
  end
59
65
 
@@ -312,6 +318,7 @@ module Appsignal
312
318
  finish_event(name, title, body, body_format)
313
319
  end
314
320
 
321
+ # @api private
315
322
  def to_h
316
323
  JSON.parse(@ext.to_json)
317
324
  end
@@ -1,5 +1,5 @@
1
1
  require "yaml"
2
2
 
3
3
  module Appsignal
4
- VERSION = "2.3.6".freeze
4
+ VERSION = "2.3.7".freeze
5
5
  end
@@ -1,145 +1,101 @@
1
- describe Appsignal::Hooks::SidekiqPlugin do
2
- let(:worker) { double }
3
- let(:queue) { double }
4
- let(:current_transaction) { background_job_transaction }
5
- let(:args) { ["Model", 1] }
6
- let(:item) do
7
- {
8
- "class" => "TestClass",
9
- "retry_count" => 0,
10
- "queue" => "default",
11
- "enqueued_at" => Time.parse("01-01-2001 10:00:00UTC"),
12
- "args" => args,
13
- "extra" => "data"
14
- }
15
- end
16
- let(:plugin) { Appsignal::Hooks::SidekiqPlugin.new }
1
+ if DependencyHelper.sidekiq_present?
2
+ describe Appsignal::Hooks::SidekiqPlugin, :with_sidekiq_error => false do
3
+ let(:namespace) { Appsignal::Transaction::BACKGROUND_JOB }
4
+ let(:worker) { anything }
5
+ let(:queue) { anything }
6
+ let(:args) { ["Model", 1] }
7
+ let(:job_class) { "TestClass" }
8
+ let(:item) do
9
+ {
10
+ "class" => job_class,
11
+ "retry_count" => 0,
12
+ "queue" => "default",
13
+ "enqueued_at" => Time.parse("01-01-2001 10:00:00UTC").to_f,
14
+ "args" => args,
15
+ "extra" => "data"
16
+ }
17
+ end
18
+ let(:plugin) { Appsignal::Hooks::SidekiqPlugin.new }
19
+ let(:test_store) { {} }
17
20
 
18
- before do
19
- allow(Appsignal::Transaction).to receive(:current).and_return(current_transaction)
20
- start_agent
21
- end
21
+ before :with_sidekiq_error => false do
22
+ # Stub calls to extension, because that would remove the transaction
23
+ # from the extension.
24
+ allow_any_instance_of(Appsignal::Extension::Transaction).to receive(:finish).and_return(true)
25
+ allow_any_instance_of(Appsignal::Extension::Transaction).to receive(:complete)
22
26
 
23
- context "with a performance call" do
24
- after do
25
- Timecop.freeze(Time.parse("01-01-2001 10:01:00UTC")) do
26
- Appsignal::Hooks::SidekiqPlugin.new.call(worker, item, queue) do
27
- # nothing
28
- end
27
+ # Stub removal of current transaction from current thread so we can fetch
28
+ # it later.
29
+ expect(Appsignal::Transaction).to receive(:clear_current_transaction!).at_least(:once) do
30
+ transaction = Thread.current[:appsignal_transaction]
31
+ test_store[:transaction] = transaction if transaction
29
32
  end
30
33
  end
31
-
32
- it "wraps it in a transaction with the correct params" do
33
- expect(Appsignal).to receive(:monitor_transaction).with(
34
- "perform_job.sidekiq",
35
- :class => "TestClass",
36
- :method => "perform",
37
- :metadata => {
38
- "retry_count" => "0",
39
- "queue" => "default",
40
- "extra" => "data"
41
- },
42
- :params => ["Model", 1],
43
- :queue_start => Time.parse("01-01-2001 10:00:00UTC"),
44
- :queue_time => 60_000.to_f
45
- )
34
+ before do
35
+ start_agent
46
36
  end
37
+ after { clear_current_transaction! }
47
38
 
48
- context "with more complex arguments" do
49
- let(:default_params) do
50
- {
51
- :class => "TestClass",
52
- :method => "perform",
53
- :metadata => {
54
- "retry_count" => "0",
55
- "queue" => "default",
56
- "extra" => "data"
57
- },
58
- :params => {
59
- :foo => "Foo",
60
- :bar => "Bar"
61
- },
62
- :queue_start => Time.parse("01-01-2001 10:00:00UTC"),
63
- :queue_time => 60_000.to_f
64
- }
65
- end
66
- let(:args) do
67
- {
68
- :foo => "Foo",
69
- :bar => "Bar"
70
- }
39
+ context "when there's a problem with calling the Sidekiq::Job class", :with_sidekiq_error => true do
40
+ let(:log) { StringIO.new }
41
+ before do
42
+ Appsignal.logger = Logger.new(log)
43
+ expect(::Sidekiq::Job).to receive(:new).and_raise(NameError, "woops")
44
+ perform_job
71
45
  end
72
46
 
73
- it "adds the more complex arguments" do
74
- expect(Appsignal).to receive(:monitor_transaction).with(
75
- "perform_job.sidekiq",
76
- default_params.merge(
77
- :params => {
78
- :foo => "Foo",
79
- :bar => "Bar"
80
- }
81
- )
47
+ it "does not record a transaction and logs an error" do
48
+ expect(transaction).to be_nil
49
+ log.rewind
50
+ expect(log.read).to include(
51
+ "ERROR",
52
+ "Problem parsing the Sidekiq job data: #<NameError: woops>"
82
53
  )
83
54
  end
84
-
85
- context "with parameter filtering" do
86
- before do
87
- Appsignal.config = project_fixture_config("production")
88
- Appsignal.config[:filter_parameters] = ["foo"]
89
- end
90
-
91
- it "filters selected arguments" do
92
- expect(Appsignal).to receive(:monitor_transaction).with(
93
- "perform_job.sidekiq",
94
- default_params.merge(
95
- :params => {
96
- :foo => "[FILTERED]",
97
- :bar => "Bar"
98
- }
99
- )
100
- )
101
- end
102
- end
103
55
  end
104
56
 
105
- context "when wrapped by ActiveJob" do
106
- let(:item) do
107
- {
108
- "class" => "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper",
109
- "wrapped" => "TestClass",
110
- "queue" => "default",
111
- "args" => [{
112
- "job_class" => "TestJob",
113
- "job_id" => "23e79d48-6966-40d0-b2d4-f7938463a263",
114
- "queue_name" => "default",
115
- "arguments" => args
116
- }],
117
- "retry" => true,
118
- "jid" => "efb140489485999d32b5504c",
119
- "created_at" => Time.parse("01-01-2001 10:00:00UTC").to_f,
120
- "enqueued_at" => Time.parse("01-01-2001 10:00:00UTC").to_f
121
- }
122
- end
123
- let(:default_params) do
124
- {
125
- :class => "TestClass",
126
- :method => "perform",
127
- :metadata => {
128
- "queue" => "default"
57
+ context "with a performance call" do
58
+ it "creates a transaction with performance events" do
59
+ perform_job
60
+
61
+ transaction_hash = transaction.to_h
62
+ expect(transaction_hash).to include(
63
+ "id" => kind_of(String),
64
+ "action" => "TestClass#perform",
65
+ "error" => nil,
66
+ "namespace" => namespace,
67
+ "metadata" => {
68
+ "extra" => "data",
69
+ "queue" => "default",
70
+ "retry_count" => "0"
129
71
  },
130
- :queue_start => Time.parse("01-01-2001 10:00:00UTC").to_f,
131
- :queue_time => 60_000.to_f
132
- }
72
+ "sample_data" => {
73
+ "environment" => {},
74
+ "params" => args,
75
+ "tags" => {}
76
+ }
77
+ )
78
+ # TODO: Not available in transaction.to_h yet.
79
+ # https://github.com/appsignal/appsignal-agent/issues/293
80
+ expect(transaction.request.env).to eq(
81
+ :queue_start => Time.parse("01-01-2001 10:00:00UTC"),
82
+ :queue_time => 60_000.0
83
+ )
84
+ expect_transaction_to_have_sidekiq_event(transaction_hash)
133
85
  end
134
86
 
135
- it "wraps it in a transaction with the correct params" do
136
- expect(Appsignal).to receive(:monitor_transaction).with(
137
- "perform_job.sidekiq",
138
- default_params.merge(:params => ["Model", 1])
139
- )
87
+ context "when receiving class.method instead of class#method" do
88
+ let(:job_class) { "ActionMailer.deliver_message" }
89
+
90
+ it "uses the class method action name for the action" do
91
+ perform_job
92
+
93
+ transaction_hash = transaction.to_h
94
+ expect(transaction_hash["action"]).to eq("ActionMailer.deliver_message")
95
+ end
140
96
  end
141
97
 
142
- context "with more complex arguments" do
98
+ context "with more complex job arguments" do
143
99
  let(:args) do
144
100
  {
145
101
  :foo => "Foo",
@@ -148,14 +104,14 @@ describe Appsignal::Hooks::SidekiqPlugin do
148
104
  end
149
105
 
150
106
  it "adds the more complex arguments" do
151
- expect(Appsignal).to receive(:monitor_transaction).with(
152
- "perform_job.sidekiq",
153
- default_params.merge(
154
- :params => {
155
- :foo => "Foo",
156
- :bar => "Bar"
157
- }
158
- )
107
+ perform_job
108
+
109
+ transaction_hash = transaction.to_h
110
+ expect(transaction_hash["sample_data"]).to include(
111
+ "params" => {
112
+ "foo" => "Foo",
113
+ "bar" => "Bar"
114
+ }
159
115
  )
160
116
  end
161
117
 
@@ -166,90 +122,166 @@ describe Appsignal::Hooks::SidekiqPlugin do
166
122
  end
167
123
 
168
124
  it "filters selected arguments" do
169
- expect(Appsignal).to receive(:monitor_transaction).with(
170
- "perform_job.sidekiq",
171
- default_params.merge(
172
- :params => {
173
- :foo => "[FILTERED]",
174
- :bar => "Bar"
125
+ perform_job
126
+
127
+ transaction_hash = transaction.to_h
128
+ expect(transaction_hash["sample_data"]).to include(
129
+ "params" => {
130
+ "foo" => "[FILTERED]",
131
+ "bar" => "Bar"
132
+ }
133
+ )
134
+ end
135
+ end
136
+ end
137
+
138
+ context "when job is wrapped by ActiveJob" do
139
+ let(:item) do
140
+ {
141
+ "class" => "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper",
142
+ "wrapped" => "TestClass",
143
+ "queue" => "default",
144
+ "args" => [{
145
+ "job_class" => "TestJob",
146
+ "job_id" => "23e79d48-6966-40d0-b2d4-f7938463a263",
147
+ "queue_name" => "default",
148
+ "arguments" => args
149
+ }],
150
+ "retry" => true,
151
+ "jid" => "efb140489485999d32b5504c",
152
+ "created_at" => Time.parse("01-01-2001 10:00:00UTC"),
153
+ "enqueued_at" => Time.parse("01-01-2001 10:00:00UTC").to_f
154
+ }
155
+ end
156
+
157
+ it "creates a transaction with performance events" do
158
+ perform_job
159
+
160
+ transaction_hash = transaction.to_h
161
+ expect(transaction_hash).to include(
162
+ "id" => kind_of(String),
163
+ "action" => "TestClass#perform",
164
+ "error" => nil,
165
+ "namespace" => namespace,
166
+ "metadata" => {
167
+ "queue" => "default"
168
+ },
169
+ "sample_data" => {
170
+ "environment" => {},
171
+ "params" => args,
172
+ "tags" => {}
173
+ }
174
+ )
175
+ # TODO: Not available in transaction.to_h yet.
176
+ # https://github.com/appsignal/appsignal-agent/issues/293
177
+ expect(transaction.request.env).to eq(
178
+ :queue_start => Time.parse("01-01-2001 10:00:00UTC"),
179
+ :queue_time => 60_000.0
180
+ )
181
+ expect_transaction_to_have_sidekiq_event(transaction_hash)
182
+ end
183
+
184
+ context "with more complex arguments" do
185
+ let(:args) do
186
+ {
187
+ :foo => "Foo",
188
+ :bar => "Bar"
189
+ }
190
+ end
191
+
192
+ it "adds the more complex arguments" do
193
+ perform_job
194
+
195
+ transaction_hash = transaction.to_h
196
+ expect(transaction_hash["sample_data"]).to include(
197
+ "params" => {
198
+ "foo" => "Foo",
199
+ "bar" => "Bar"
200
+ }
201
+ )
202
+ end
203
+
204
+ context "with parameter filtering" do
205
+ before do
206
+ Appsignal.config = project_fixture_config("production")
207
+ Appsignal.config[:filter_parameters] = ["foo"]
208
+ end
209
+
210
+ it "filters selected arguments" do
211
+ perform_job
212
+
213
+ transaction_hash = transaction.to_h
214
+ expect(transaction_hash["sample_data"]).to include(
215
+ "params" => {
216
+ "foo" => "[FILTERED]",
217
+ "bar" => "Bar"
175
218
  }
176
219
  )
177
- )
220
+ end
178
221
  end
179
222
  end
180
223
  end
181
224
  end
182
- end
183
225
 
184
- context "with an erroring call" do
185
- let(:error) { VerySpecificError }
186
- let(:transaction) do
187
- Appsignal::Transaction.new(
188
- SecureRandom.uuid,
189
- Appsignal::Transaction::BACKGROUND_JOB,
190
- Appsignal::Transaction::GenericRequest.new({})
191
- )
192
- end
193
- before do
194
- allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
195
- expect(Appsignal::Transaction).to receive(:create)
196
- .with(
197
- kind_of(String),
198
- Appsignal::Transaction::BACKGROUND_JOB,
199
- kind_of(Appsignal::Transaction::GenericRequest)
200
- ).and_return(transaction)
201
- end
226
+ context "with an erroring job" do
227
+ let(:error) { VerySpecificError }
228
+ before do
229
+ expect do
230
+ Timecop.freeze(Time.parse("01-01-2001 10:01:00UTC")) do
231
+ plugin.call(worker, item, queue) do
232
+ raise error, "uh oh"
233
+ end
234
+ end
235
+ end.to raise_error(error)
236
+ end
202
237
 
203
- it "adds the error to the transaction" do
204
- expect(transaction).to receive(:set_error).with(error)
205
- expect(transaction).to receive(:complete)
238
+ it "adds the error to the transaction" do
239
+ transaction_hash = transaction.to_h
240
+ # TODO: backtrace should be an Array of Strings
241
+ # https://github.com/appsignal/appsignal-agent/issues/294
242
+ expect(transaction_hash["error"]).to include(
243
+ "name" => "VerySpecificError",
244
+ "message" => "uh oh",
245
+ "backtrace" => kind_of(String)
246
+ )
247
+ expect_transaction_to_have_sidekiq_event(transaction_hash)
248
+ end
206
249
  end
207
250
 
208
- after do
209
- expect do
210
- Timecop.freeze(Time.parse("01-01-2001 10:01:00UTC")) do
211
- Appsignal::Hooks::SidekiqPlugin.new.call(worker, item, queue) do
212
- raise error
213
- end
251
+ def perform_job
252
+ Timecop.freeze(Time.parse("01-01-2001 10:01:00UTC")) do
253
+ plugin.call(worker, item, queue) do
254
+ # nothing
214
255
  end
215
- end.to raise_error(error)
256
+ end
216
257
  end
217
- end
218
258
 
219
- # TODO: Don't test (what are basically) private methods
220
- describe "#formatted_data" do
221
- let(:item) do
222
- {
223
- "foo" => "bar",
224
- "class" => "TestClass"
225
- }
259
+ def transaction
260
+ test_store[:transaction]
226
261
  end
227
262
 
228
- it "only adds items to the hash that do not appear in JOB_KEYS" do
229
- expect(plugin.formatted_metadata(item)).to eq("foo" => "bar")
263
+ def expect_transaction_to_have_sidekiq_event(transaction_hash)
264
+ events = transaction_hash["events"]
265
+ expect(events.count).to eq(1)
266
+ expect(events.first).to include(
267
+ "name" => "perform_job.sidekiq",
268
+ "title" => "",
269
+ "count" => 1,
270
+ "body" => "",
271
+ "body_format" => Appsignal::EventFormatter::DEFAULT
272
+ )
230
273
  end
231
274
  end
232
275
  end
233
276
 
234
277
  describe Appsignal::Hooks::SidekiqHook do
235
- context "with sidekiq" do
236
- before :context do
237
- module Sidekiq
238
- def self.configure_server
239
- end
240
- end
241
- Appsignal::Hooks::SidekiqHook.new.install
242
- end
243
- after(:context) { Object.send(:remove_const, :Sidekiq) }
244
-
278
+ if DependencyHelper.sidekiq_present?
245
279
  describe "#dependencies_present?" do
246
280
  subject { described_class.new.dependencies_present? }
247
281
 
248
282
  it { is_expected.to be_truthy }
249
283
  end
250
- end
251
-
252
- context "without sidekiq" do
284
+ else
253
285
  describe "#dependencies_present?" do
254
286
  subject { described_class.new.dependencies_present? }
255
287
 
@@ -63,6 +63,10 @@ module DependencyHelper
63
63
  Gem.loaded_specs["capistrano"].version >= Gem::Version.new("3.0")
64
64
  end
65
65
 
66
+ def sidekiq_present?
67
+ dependency_present? "sidekiq"
68
+ end
69
+
66
70
  def dependency_present?(dependency_file)
67
71
  Gem.loaded_specs.key? dependency_file
68
72
  end
@@ -28,4 +28,10 @@ module TransactionHelpers
28
28
  }.merge(args))
29
29
  )
30
30
  end
31
+
32
+ # Use when {Appsignal::Transaction.clear_current_transaction!} is stubbed to
33
+ # clear the current transaction on the current thread.
34
+ def clear_current_transaction!
35
+ Thread.current[:appsignal_transaction] = nil
36
+ end
31
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appsignal
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.6
4
+ version: 2.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Beekman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-09-26 00:00:00.000000000 Z
12
+ date: 2017-10-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -163,6 +163,7 @@ files:
163
163
  - gemfiles/resque.gemfile
164
164
  - gemfiles/sequel-435.gemfile
165
165
  - gemfiles/sequel.gemfile
166
+ - gemfiles/sidekiq.gemfile
166
167
  - gemfiles/sinatra.gemfile
167
168
  - gemfiles/webmachine.gemfile
168
169
  - lib/appsignal.rb
@@ -352,7 +353,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
352
353
  version: '0'
353
354
  requirements: []
354
355
  rubyforge_project:
355
- rubygems_version: 2.6.13
356
+ rubygems_version: 2.5.2.1
356
357
  signing_key:
357
358
  specification_version: 4
358
359
  summary: Logs performance and exception data from your app to appsignal.com