appsignal 2.11.2 → 2.11.3
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/.semaphore/semaphore.yml +1 -1
- data/CHANGELOG.md +3 -0
- data/build_matrix.yml +1 -1
- data/lib/appsignal/hooks/shoryuken.rb +43 -4
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +151 -104
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 140c8dc48aa610503d589cbadbd8080234498628f73570eb9dec1fe40d43e7c6
|
4
|
+
data.tar.gz: 9d3bda2c23f46391752218d6a08290e19ffe59a9cdabd3d89841f208a5a4499c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1496d2e2ab87742b5ede043d513a290aa95679445c7dd5a1f041c90bb2e05fc983e558733b974a60ed880c1db3ac9faabfc431ed4c3e1cf68fad150dd5cd4e61
|
7
|
+
data.tar.gz: 62052287406db0bb8e95c6e9130886f9db8f7e9822b9d835a9faec3090facd4990addf13b99f107a26e777a37354bbe8ea795c392917cfe2c0884772000b0b3c
|
data/.semaphore/semaphore.yml
CHANGED
@@ -31,7 +31,7 @@ global_job_config:
|
|
31
31
|
prologue:
|
32
32
|
commands:
|
33
33
|
- checkout
|
34
|
-
-
|
34
|
+
- rm -f $HOME/.rbenv/plugins/rbenv-gem-rehash/etc/rbenv.d/exec/~gem-rehash.bash
|
35
35
|
- sem-version ruby $RUBY_VERSION
|
36
36
|
- "./support/check_versions"
|
37
37
|
- cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
|
data/CHANGELOG.md
CHANGED
data/build_matrix.yml
CHANGED
@@ -32,7 +32,7 @@ semaphore: # Default `.semaphore/semaphore.yml` contents
|
|
32
32
|
prologue:
|
33
33
|
commands:
|
34
34
|
- checkout
|
35
|
-
-
|
35
|
+
- rm -f $HOME/.rbenv/plugins/rbenv-gem-rehash/etc/rbenv.d/exec/~gem-rehash.bash
|
36
36
|
- sem-version ruby $RUBY_VERSION
|
37
37
|
- ./support/check_versions
|
38
38
|
- cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
|
@@ -5,21 +5,60 @@ module Appsignal
|
|
5
5
|
# @api private
|
6
6
|
class ShoryukenMiddleware
|
7
7
|
def call(worker_instance, queue, sqs_msg, body)
|
8
|
-
|
8
|
+
batch = sqs_msg.is_a?(Array)
|
9
|
+
attributes =
|
10
|
+
if batch
|
11
|
+
# We can't instrument batched message separately, the `yield` will
|
12
|
+
# perform all the batched messages.
|
13
|
+
# To provide somewhat useful metadata, Get first message based on
|
14
|
+
# SentTimestamp, and use its attributes as metadata for the
|
15
|
+
# transaction. We can't combine them all because then they would
|
16
|
+
# overwrite each other and the last message (in an sorted order)
|
17
|
+
# would be used as the source of the metadata. With the
|
18
|
+
# oldest/first message at least some useful information is stored
|
19
|
+
# such as the first received time and the number of retries for the
|
20
|
+
# first message. The newer message should have lower values and
|
21
|
+
# timestamps in their metadata.
|
22
|
+
first_msg = sqs_msg.min do |a, b|
|
23
|
+
a.attributes["SentTimestamp"].to_i <=> b.attributes["SentTimestamp"].to_i
|
24
|
+
end
|
25
|
+
# Add batch => true metadata so people can recognize when a
|
26
|
+
# transaction is about a batch of messages.
|
27
|
+
first_msg.attributes.merge(:batch => true)
|
28
|
+
else
|
29
|
+
sqs_msg.attributes.merge(:message_id => sqs_msg.message_id)
|
30
|
+
end
|
31
|
+
metadata = { :queue => queue }.merge(attributes)
|
9
32
|
options = {
|
10
33
|
:class => worker_instance.class.name,
|
11
34
|
:method => "perform",
|
12
35
|
:metadata => metadata
|
13
36
|
}
|
14
37
|
|
15
|
-
args =
|
38
|
+
args =
|
39
|
+
if batch
|
40
|
+
bodies = {}
|
41
|
+
sqs_msg.each_with_index do |msg, index|
|
42
|
+
# Store all separate bodies on a hash with the key being the
|
43
|
+
# message_id
|
44
|
+
bodies[msg.message_id] = body[index]
|
45
|
+
end
|
46
|
+
bodies
|
47
|
+
else
|
48
|
+
case body
|
49
|
+
when Hash
|
50
|
+
body
|
51
|
+
else
|
52
|
+
{ :params => body }
|
53
|
+
end
|
54
|
+
end
|
16
55
|
options[:params] = Appsignal::Utils::HashSanitizer.sanitize(
|
17
56
|
args,
|
18
57
|
Appsignal.config[:filter_parameters]
|
19
58
|
)
|
20
59
|
|
21
|
-
if
|
22
|
-
options[:queue_start] = Time.at(
|
60
|
+
if attributes.key?("SentTimestamp")
|
61
|
+
options[:queue_start] = Time.at(attributes["SentTimestamp"].to_i / 1000)
|
23
62
|
end
|
24
63
|
|
25
64
|
Appsignal.monitor_transaction("perform_job.shoryuken", options) do
|
data/lib/appsignal/version.rb
CHANGED
@@ -1,55 +1,73 @@
|
|
1
1
|
describe Appsignal::Hooks::ShoryukenMiddleware do
|
2
|
-
let(:current_transaction) { background_job_transaction }
|
3
|
-
|
4
2
|
class DemoShoryukenWorker
|
5
3
|
end
|
6
4
|
|
5
|
+
let(:time) { "2010-01-01 10:01:00UTC" }
|
7
6
|
let(:worker_instance) { DemoShoryukenWorker.new }
|
8
|
-
let(:queue) {
|
9
|
-
let(:sqs_msg) { double(:attributes => {}) }
|
7
|
+
let(:queue) { "some-funky-queue-name" }
|
8
|
+
let(:sqs_msg) { double(:message_id => "msg1", :attributes => {}) }
|
10
9
|
let(:body) { {} }
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
before(:context) { start_agent }
|
11
|
+
around { |example| keep_transactions { example.run } }
|
12
|
+
|
13
|
+
def perform_job(&block)
|
14
|
+
block ||= lambda {}
|
15
|
+
Timecop.freeze(Time.parse(time)) do
|
16
|
+
Appsignal::Hooks::ShoryukenMiddleware.new.call(
|
17
|
+
worker_instance,
|
18
|
+
queue,
|
19
|
+
sqs_msg,
|
20
|
+
body,
|
21
|
+
&block
|
22
|
+
)
|
23
|
+
end
|
15
24
|
end
|
16
25
|
|
17
26
|
context "with a performance call" do
|
18
|
-
let(:
|
27
|
+
let(:sent_timestamp) { Time.parse("1976-11-18 0:00:00UTC").to_i * 1000 }
|
19
28
|
let(:sqs_msg) do
|
20
|
-
double(:attributes => { "SentTimestamp" =>
|
29
|
+
double(:message_id => "msg1", :attributes => { "SentTimestamp" => sent_timestamp })
|
21
30
|
end
|
22
31
|
|
23
32
|
context "with complex argument" do
|
24
|
-
let(:body)
|
25
|
-
{
|
26
|
-
:foo => "Foo",
|
27
|
-
:bar => "Bar"
|
28
|
-
}
|
29
|
-
end
|
30
|
-
after do
|
31
|
-
Timecop.freeze(Time.parse("01-01-2001 10:01:00UTC")) do
|
32
|
-
Appsignal::Hooks::ShoryukenMiddleware.new.call(worker_instance, queue, sqs_msg, body) do
|
33
|
-
# nothing
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
33
|
+
let(:body) { { :foo => "Foo", :bar => "Bar" } }
|
37
34
|
|
38
35
|
it "wraps the job in a transaction with the correct params" do
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
},
|
51
|
-
:queue_start => Time.parse("1976-11-18 0:00:00UTC").utc
|
36
|
+
allow_any_instance_of(Appsignal::Transaction).to receive(:set_queue_start).and_call_original
|
37
|
+
expect { perform_job }.to change { created_transactions.length }.by(1)
|
38
|
+
|
39
|
+
transaction = last_transaction
|
40
|
+
expect(transaction).to be_completed
|
41
|
+
transaction_hash = transaction.to_h
|
42
|
+
expect(transaction_hash).to include(
|
43
|
+
"action" => "DemoShoryukenWorker#perform",
|
44
|
+
"id" => kind_of(String), # AppSignal generated id
|
45
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB,
|
46
|
+
"error" => nil
|
52
47
|
)
|
48
|
+
expect(transaction_hash["events"].first).to include(
|
49
|
+
"allocation_count" => kind_of(Integer),
|
50
|
+
"body" => "",
|
51
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
52
|
+
"child_allocation_count" => kind_of(Integer),
|
53
|
+
"child_duration" => kind_of(Float),
|
54
|
+
"child_gc_duration" => kind_of(Float),
|
55
|
+
"count" => 1,
|
56
|
+
"gc_duration" => kind_of(Float),
|
57
|
+
"start" => kind_of(Float),
|
58
|
+
"duration" => kind_of(Float),
|
59
|
+
"name" => "perform_job.shoryuken",
|
60
|
+
"title" => ""
|
61
|
+
)
|
62
|
+
expect(transaction_hash["sample_data"]).to include(
|
63
|
+
"params" => { "foo" => "Foo", "bar" => "Bar" },
|
64
|
+
"metadata" => {
|
65
|
+
"message_id" => "msg1",
|
66
|
+
"queue" => queue,
|
67
|
+
"SentTimestamp" => sent_timestamp
|
68
|
+
}
|
69
|
+
)
|
70
|
+
expect(transaction).to have_received(:set_queue_start).with(sent_timestamp)
|
53
71
|
end
|
54
72
|
|
55
73
|
context "with parameter filtering" do
|
@@ -57,21 +75,16 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
|
|
57
75
|
Appsignal.config = project_fixture_config("production")
|
58
76
|
Appsignal.config[:filter_parameters] = ["foo"]
|
59
77
|
end
|
78
|
+
after do
|
79
|
+
Appsignal.config[:filter_parameters] = []
|
80
|
+
end
|
60
81
|
|
61
82
|
it "filters selected arguments" do
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
:queue => "some-funky-queue-name",
|
68
|
-
"SentTimestamp" => 217_123_200_000
|
69
|
-
},
|
70
|
-
:params => {
|
71
|
-
:foo => "[FILTERED]",
|
72
|
-
:bar => "Bar"
|
73
|
-
},
|
74
|
-
:queue_start => Time.parse("1976-11-18 0:00:00UTC").utc
|
83
|
+
perform_job
|
84
|
+
|
85
|
+
transaction_hash = last_transaction.to_h
|
86
|
+
expect(transaction_hash["sample_data"]).to include(
|
87
|
+
"params" => { "foo" => "[FILTERED]", "bar" => "Bar" }
|
75
88
|
)
|
76
89
|
end
|
77
90
|
end
|
@@ -81,23 +94,12 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
|
|
81
94
|
let(:body) { "foo bar" }
|
82
95
|
|
83
96
|
it "handles string arguments" do
|
84
|
-
|
85
|
-
"perform_job.shoryuken",
|
86
|
-
:class => "DemoShoryukenWorker",
|
87
|
-
:method => "perform",
|
88
|
-
:metadata => {
|
89
|
-
:queue => "some-funky-queue-name",
|
90
|
-
"SentTimestamp" => 217_123_200_000
|
91
|
-
},
|
92
|
-
:params => { :params => body },
|
93
|
-
:queue_start => Time.parse("1976-11-18 0:00:00UTC").utc
|
94
|
-
)
|
97
|
+
perform_job
|
95
98
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
99
|
+
transaction_hash = last_transaction.to_h
|
100
|
+
expect(transaction_hash["sample_data"]).to include(
|
101
|
+
"params" => { "params" => body }
|
102
|
+
)
|
101
103
|
end
|
102
104
|
end
|
103
105
|
|
@@ -105,58 +107,103 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
|
|
105
107
|
let(:body) { 1 }
|
106
108
|
|
107
109
|
it "handles primitive types as arguments" do
|
108
|
-
|
109
|
-
"perform_job.shoryuken",
|
110
|
-
:class => "DemoShoryukenWorker",
|
111
|
-
:method => "perform",
|
112
|
-
:metadata => {
|
113
|
-
:queue => "some-funky-queue-name",
|
114
|
-
"SentTimestamp" => 217_123_200_000
|
115
|
-
},
|
116
|
-
:params => { :params => body },
|
117
|
-
:queue_start => Time.parse("1976-11-18 0:00:00UTC").utc
|
118
|
-
)
|
110
|
+
perform_job
|
119
111
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
112
|
+
transaction_hash = last_transaction.to_h
|
113
|
+
expect(transaction_hash["sample_data"]).to include(
|
114
|
+
"params" => { "params" => body }
|
115
|
+
)
|
125
116
|
end
|
126
117
|
end
|
127
118
|
end
|
128
119
|
|
129
120
|
context "with exception" do
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
121
|
+
it "sets the exception on the transaction" do
|
122
|
+
expect do
|
123
|
+
expect do
|
124
|
+
perform_job { raise ExampleException, "error message" }
|
125
|
+
end.to raise_error(ExampleException)
|
126
|
+
end.to change { created_transactions.length }.by(1)
|
127
|
+
|
128
|
+
transaction = last_transaction
|
129
|
+
expect(transaction).to be_completed
|
130
|
+
transaction_hash = transaction.to_h
|
131
|
+
expect(transaction_hash).to include(
|
132
|
+
"action" => "DemoShoryukenWorker#perform",
|
133
|
+
"id" => kind_of(String), # AppSignal generated id
|
134
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB,
|
135
|
+
"error" => {
|
136
|
+
"name" => "ExampleException",
|
137
|
+
"message" => "error message",
|
138
|
+
"backtrace" => kind_of(String)
|
139
|
+
}
|
135
140
|
)
|
136
141
|
end
|
142
|
+
end
|
137
143
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
144
|
+
context "with batched jobs" do
|
145
|
+
let(:sqs_msg) do
|
146
|
+
[
|
147
|
+
double(
|
148
|
+
:message_id => "msg2",
|
149
|
+
:attributes => { "SentTimestamp" => (Time.parse("1976-11-18 01:00:00UTC").to_i * 1000).to_s }
|
150
|
+
),
|
151
|
+
double(
|
152
|
+
:message_id => "msg1",
|
153
|
+
:attributes => { "SentTimestamp" => sent_timestamp.to_s }
|
154
|
+
)
|
155
|
+
]
|
146
156
|
end
|
147
|
-
|
148
|
-
|
149
|
-
|
157
|
+
let(:body) do
|
158
|
+
[
|
159
|
+
"foo bar",
|
160
|
+
{ :id => "123", :foo => "Foo", :bar => "Bar" }
|
161
|
+
]
|
150
162
|
end
|
163
|
+
let(:sent_timestamp) { Time.parse("1976-11-18 01:00:00UTC").to_i * 1000 }
|
151
164
|
|
152
|
-
|
165
|
+
it "creates a transaction for the batch" do
|
166
|
+
allow_any_instance_of(Appsignal::Transaction).to receive(:set_queue_start).and_call_original
|
153
167
|
expect do
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
168
|
+
perform_job {}
|
169
|
+
end.to change { created_transactions.length }.by(1)
|
170
|
+
|
171
|
+
transaction = last_transaction
|
172
|
+
expect(transaction).to be_completed
|
173
|
+
transaction_hash = transaction.to_h
|
174
|
+
expect(transaction_hash).to include(
|
175
|
+
"action" => "DemoShoryukenWorker#perform",
|
176
|
+
"id" => kind_of(String), # AppSignal generated id
|
177
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB,
|
178
|
+
"error" => nil
|
179
|
+
)
|
180
|
+
expect(transaction_hash["events"].first).to include(
|
181
|
+
"allocation_count" => kind_of(Integer),
|
182
|
+
"body" => "",
|
183
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
184
|
+
"child_allocation_count" => kind_of(Integer),
|
185
|
+
"child_duration" => kind_of(Float),
|
186
|
+
"child_gc_duration" => kind_of(Float),
|
187
|
+
"count" => 1,
|
188
|
+
"gc_duration" => kind_of(Float),
|
189
|
+
"start" => kind_of(Float),
|
190
|
+
"duration" => kind_of(Float),
|
191
|
+
"name" => "perform_job.shoryuken",
|
192
|
+
"title" => ""
|
193
|
+
)
|
194
|
+
expect(transaction_hash["sample_data"]).to include(
|
195
|
+
"params" => {
|
196
|
+
"msg2" => "foo bar",
|
197
|
+
"msg1" => { "id" => "123", "foo" => "Foo", "bar" => "Bar" }
|
198
|
+
},
|
199
|
+
"metadata" => {
|
200
|
+
"batch" => true,
|
201
|
+
"queue" => "some-funky-queue-name",
|
202
|
+
"SentTimestamp" => sent_timestamp.to_s # Earliest/oldest timestamp from messages
|
203
|
+
}
|
204
|
+
)
|
205
|
+
# Queue time based on earliest/oldest timestamp from messages
|
206
|
+
expect(transaction).to have_received(:set_queue_start).with(sent_timestamp)
|
160
207
|
end
|
161
208
|
end
|
162
209
|
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.11.
|
4
|
+
version: 2.11.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-01-
|
13
|
+
date: 2021-01-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -415,7 +415,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
415
415
|
- !ruby/object:Gem::Version
|
416
416
|
version: '0'
|
417
417
|
requirements: []
|
418
|
-
rubygems_version: 3.
|
418
|
+
rubygems_version: 3.2.5
|
419
419
|
signing_key:
|
420
420
|
specification_version: 4
|
421
421
|
summary: Logs performance and exception data from your app to appsignal.com
|