appsignal 2.3.6 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|