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 +4 -4
- data/.travis.yml +7 -0
- data/CHANGELOG.md +10 -0
- data/Rakefile +1 -0
- data/gemfiles/sidekiq.gemfile +5 -0
- data/lib/appsignal/hooks/sidekiq.rb +67 -20
- data/lib/appsignal/transaction.rb +7 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +224 -192
- data/spec/support/helpers/dependency_helper.rb +4 -0
- data/spec/support/helpers/transaction_helpers.rb +6 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed63c49d1dfc2fc2760647e86a0721f9a1476d8b
|
4
|
+
data.tar.gz: 5af04584576a18ea0c42e2fb2a2188d0361b826b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 799f054a927e0dd89a7c8775f34b91d271075c25838826589959223be286bbf6ccc8297b0ad97eac00bd1cd6bae52573380ed7b69abd87037ad70ce87552856c
|
7
|
+
data.tar.gz: 719aaed0e8e4e9cc6e398f6ad7a509073e65c19d959b678221e026bc4d15bc478f7fda4541878561bf146c53668c8f8cfc657763a2c54806db2b8214662307af
|
data/.travis.yml
CHANGED
@@ -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"
|
data/CHANGELOG.md
CHANGED
@@ -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,32 +14,78 @@ module Appsignal
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def call(_worker, item, _queue)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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 |
|
41
|
-
item.each do |key,
|
42
|
-
|
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
|
data/lib/appsignal/version.rb
CHANGED
@@ -1,145 +1,101 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
{
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
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
|
49
|
-
let(:
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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 "
|
74
|
-
expect(
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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 "
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
"
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
131
|
-
|
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
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
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
|
-
|
204
|
-
|
205
|
-
|
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
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
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
|
256
|
+
end
|
216
257
|
end
|
217
|
-
end
|
218
258
|
|
219
|
-
|
220
|
-
|
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
|
-
|
229
|
-
|
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
|
-
|
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
|
-
|
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.
|
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-
|
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.
|
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
|