appsignal 3.9.3-java → 3.11.0-java
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/.github/workflows/ci.yml +22 -19
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +180 -0
- data/Gemfile +1 -0
- data/README.md +0 -1
- data/Rakefile +1 -1
- data/benchmark.rake +99 -42
- data/build_matrix.yml +10 -12
- data/gemfiles/webmachine1.gemfile +5 -4
- data/lib/appsignal/cli/demo.rb +0 -1
- data/lib/appsignal/config.rb +57 -97
- data/lib/appsignal/demo.rb +15 -20
- data/lib/appsignal/environment.rb +6 -1
- data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
- data/lib/appsignal/event_formatter.rb +3 -2
- data/lib/appsignal/helpers/instrumentation.rb +490 -16
- data/lib/appsignal/hooks/action_cable.rb +21 -16
- data/lib/appsignal/hooks/active_job.rb +15 -14
- data/lib/appsignal/hooks/delayed_job.rb +1 -1
- data/lib/appsignal/hooks/shoryuken.rb +3 -63
- data/lib/appsignal/integrations/action_cable.rb +5 -7
- data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
- data/lib/appsignal/integrations/data_mapper.rb +1 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
- data/lib/appsignal/integrations/dry_monitor.rb +1 -0
- data/lib/appsignal/integrations/excon.rb +1 -0
- data/lib/appsignal/integrations/http.rb +1 -0
- data/lib/appsignal/integrations/net_http.rb +1 -0
- data/lib/appsignal/integrations/object.rb +6 -0
- data/lib/appsignal/integrations/padrino.rb +21 -25
- data/lib/appsignal/integrations/que.rb +13 -20
- data/lib/appsignal/integrations/railtie.rb +1 -1
- data/lib/appsignal/integrations/rake.rb +45 -15
- data/lib/appsignal/integrations/redis.rb +1 -0
- data/lib/appsignal/integrations/redis_client.rb +1 -0
- data/lib/appsignal/integrations/resque.rb +2 -5
- data/lib/appsignal/integrations/shoryuken.rb +75 -0
- data/lib/appsignal/integrations/sidekiq.rb +7 -25
- data/lib/appsignal/integrations/unicorn.rb +1 -0
- data/lib/appsignal/integrations/webmachine.rb +12 -9
- data/lib/appsignal/logger.rb +7 -3
- data/lib/appsignal/probes/helpers.rb +1 -0
- data/lib/appsignal/probes/mri.rb +1 -0
- data/lib/appsignal/probes/sidekiq.rb +1 -0
- data/lib/appsignal/probes.rb +3 -0
- data/lib/appsignal/rack/abstract_middleware.rb +67 -24
- data/lib/appsignal/rack/body_wrapper.rb +143 -0
- data/lib/appsignal/rack/event_handler.rb +39 -8
- data/lib/appsignal/rack/generic_instrumentation.rb +6 -4
- data/lib/appsignal/rack/grape_middleware.rb +3 -2
- data/lib/appsignal/rack/hanami_middleware.rb +1 -1
- data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +1 -3
- data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
- data/lib/appsignal/rack/streaming_listener.rb +14 -59
- data/lib/appsignal/rack.rb +60 -0
- data/lib/appsignal/span.rb +1 -0
- data/lib/appsignal/transaction.rb +353 -104
- data/lib/appsignal/utils/data.rb +0 -1
- data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
- data/lib/appsignal/utils/integration_logger.rb +0 -13
- data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
- data/lib/appsignal/utils/json.rb +0 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
- data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
- data/lib/appsignal/utils.rb +6 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +9 -6
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +139 -43
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
- data/spec/lib/appsignal/hooks/activejob_spec.rb +9 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
- data/spec/lib/appsignal/hooks/rake_spec.rb +100 -17
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
- data/spec/lib/appsignal/integrations/padrino_spec.rb +181 -131
- data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -4
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -2
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -17
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +144 -11
- data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -10
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -17
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +1 -1
- data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +43 -120
- data/spec/lib/appsignal/rack_spec.rb +63 -0
- data/spec/lib/appsignal/transaction_spec.rb +1675 -953
- data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
- data/spec/lib/appsignal_spec.rb +517 -13
- data/spec/support/helpers/transaction_helpers.rb +44 -20
- data/spec/support/matchers/transaction.rb +15 -1
- data/spec/support/mocks/dummy_app.rb +1 -1
- data/spec/support/testing.rb +1 -1
- metadata +12 -4
- data/support/check_versions +0 -22
|
@@ -3,8 +3,11 @@ describe Appsignal::Rack::EventHandler do
|
|
|
3
3
|
let(:env) do
|
|
4
4
|
{
|
|
5
5
|
"HTTP_X_REQUEST_START" => "t=#{queue_start_time.to_i}", # in milliseconds
|
|
6
|
-
"REQUEST_METHOD" => "
|
|
7
|
-
"PATH_INFO" => "/path"
|
|
6
|
+
"REQUEST_METHOD" => "POST",
|
|
7
|
+
"PATH_INFO" => "/path",
|
|
8
|
+
"QUERY_STRING" => "query_param1=value1&query_param2=value2",
|
|
9
|
+
"rack.session" => { "session1" => "value1", "session2" => "value2" },
|
|
10
|
+
"rack.input" => StringIO.new("post_param1=value1&post_param2=value2")
|
|
8
11
|
}
|
|
9
12
|
end
|
|
10
13
|
let(:request) { Rack::Request.new(env) }
|
|
@@ -172,20 +175,93 @@ describe Appsignal::Rack::EventHandler do
|
|
|
172
175
|
expect(last_transaction).to_not be_completed
|
|
173
176
|
end
|
|
174
177
|
|
|
175
|
-
it "
|
|
178
|
+
it "sets params on the transaction" do
|
|
179
|
+
on_start
|
|
180
|
+
on_finish
|
|
181
|
+
|
|
182
|
+
expect(last_transaction).to include_params(
|
|
183
|
+
"query_param1" => "value1",
|
|
184
|
+
"query_param2" => "value2",
|
|
185
|
+
"post_param1" => "value1",
|
|
186
|
+
"post_param2" => "value2"
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "sets headers on the transaction" do
|
|
176
191
|
on_start
|
|
177
192
|
on_finish
|
|
178
193
|
|
|
179
|
-
expect(last_transaction).to_not have_action
|
|
180
194
|
expect(last_transaction).to include_environment(
|
|
181
|
-
"REQUEST_METHOD" => "
|
|
195
|
+
"REQUEST_METHOD" => "POST",
|
|
182
196
|
"PATH_INFO" => "/path"
|
|
183
197
|
)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "sets session data on the transaction" do
|
|
201
|
+
on_start
|
|
202
|
+
on_finish
|
|
203
|
+
|
|
204
|
+
expect(last_transaction).to include_session_data(
|
|
205
|
+
"session1" => "value1",
|
|
206
|
+
"session2" => "value2"
|
|
207
|
+
)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it "sets the queue start time on the transaction" do
|
|
211
|
+
on_start
|
|
212
|
+
on_finish
|
|
213
|
+
|
|
184
214
|
expect(last_transaction).to have_queue_start(queue_start_time)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "completes the transaction" do
|
|
218
|
+
on_start
|
|
219
|
+
on_finish
|
|
220
|
+
|
|
221
|
+
expect(last_transaction).to_not have_action
|
|
185
222
|
expect(last_transaction).to be_completed
|
|
186
223
|
end
|
|
187
224
|
|
|
188
225
|
context "without a response" do
|
|
226
|
+
it "sets params on the transaction" do
|
|
227
|
+
on_start
|
|
228
|
+
on_finish
|
|
229
|
+
|
|
230
|
+
expect(last_transaction).to include_params(
|
|
231
|
+
"query_param1" => "value1",
|
|
232
|
+
"query_param2" => "value2",
|
|
233
|
+
"post_param1" => "value1",
|
|
234
|
+
"post_param2" => "value2"
|
|
235
|
+
)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "sets headers on the transaction" do
|
|
239
|
+
on_start
|
|
240
|
+
on_finish
|
|
241
|
+
|
|
242
|
+
expect(last_transaction).to include_environment(
|
|
243
|
+
"REQUEST_METHOD" => "POST",
|
|
244
|
+
"PATH_INFO" => "/path"
|
|
245
|
+
)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "sets session data on the transaction" do
|
|
249
|
+
on_start
|
|
250
|
+
on_finish
|
|
251
|
+
|
|
252
|
+
expect(last_transaction).to include_session_data(
|
|
253
|
+
"session1" => "value1",
|
|
254
|
+
"session2" => "value2"
|
|
255
|
+
)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "sets the queue start time on the transaction" do
|
|
259
|
+
on_start
|
|
260
|
+
on_finish
|
|
261
|
+
|
|
262
|
+
expect(last_transaction).to have_queue_start(queue_start_time)
|
|
263
|
+
end
|
|
264
|
+
|
|
189
265
|
it "completes the transaction" do
|
|
190
266
|
on_start
|
|
191
267
|
on_finish(request, nil)
|
|
@@ -193,11 +269,6 @@ describe Appsignal::Rack::EventHandler do
|
|
|
193
269
|
# The action is not set on purpose, as we can't set a normalized route
|
|
194
270
|
# It requires the app to set an action name
|
|
195
271
|
expect(last_transaction).to_not have_action
|
|
196
|
-
expect(last_transaction).to include_environment(
|
|
197
|
-
"REQUEST_METHOD" => "GET",
|
|
198
|
-
"PATH_INFO" => "/path"
|
|
199
|
-
)
|
|
200
|
-
expect(last_transaction).to have_queue_start(queue_start_time)
|
|
201
272
|
expect(last_transaction).to be_completed
|
|
202
273
|
end
|
|
203
274
|
|
|
@@ -1,28 +1,81 @@
|
|
|
1
|
-
describe Appsignal::Rack::GenericInstrumentation do
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
describe "Appsignal::Rack::GenericInstrumentation" do
|
|
2
|
+
describe "Appsignal::Rack::GenericInstrumentation constant" do
|
|
3
|
+
let(:err_stream) { std_stream }
|
|
4
|
+
let(:stderr) { err_stream.read }
|
|
5
|
+
before do
|
|
6
|
+
if Appsignal::Rack.const_defined?(:GenericInstrumentation)
|
|
7
|
+
hide_const "Appsignal::Rack::GenericInstrumentation"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "returns the Rack::GenericInstrumentation constant" do
|
|
12
|
+
silence do
|
|
13
|
+
expect(Appsignal::Rack::GenericInstrumentation)
|
|
14
|
+
.to be(Appsignal::Rack::GenericInstrumentationAlias)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
5
17
|
|
|
6
|
-
|
|
7
|
-
|
|
18
|
+
it "prints a deprecation warning to STDERR" do
|
|
19
|
+
capture_std_streams(std_stream, err_stream) do
|
|
20
|
+
Appsignal::Rack::GenericInstrumentation
|
|
21
|
+
end
|
|
8
22
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
23
|
+
expect(stderr).to include(
|
|
24
|
+
"appsignal WARNING: The constant Appsignal::Rack::GenericInstrumentation " \
|
|
25
|
+
"has been deprecated."
|
|
26
|
+
)
|
|
27
|
+
end
|
|
12
28
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
it "logs a warning" do
|
|
30
|
+
logs =
|
|
31
|
+
capture_logs do
|
|
32
|
+
silence do
|
|
33
|
+
Appsignal::Rack::GenericInstrumentation
|
|
34
|
+
end
|
|
35
|
+
end
|
|
16
36
|
|
|
17
|
-
expect(
|
|
37
|
+
expect(logs).to contains_log(
|
|
38
|
+
:warn,
|
|
39
|
+
"The constant Appsignal::Rack::GenericInstrumentation has been deprecated."
|
|
40
|
+
)
|
|
18
41
|
end
|
|
19
42
|
end
|
|
20
43
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
44
|
+
describe "middleware" do
|
|
45
|
+
let(:app) { double(:call => true) }
|
|
46
|
+
let(:env) { Rack::MockRequest.env_for("/some/path") }
|
|
47
|
+
let(:middleware) { Appsignal::Rack::GenericInstrumentation.new(app, {}) }
|
|
48
|
+
|
|
49
|
+
before(:context) { start_agent }
|
|
50
|
+
around { |example| keep_transactions { example.run } }
|
|
51
|
+
|
|
52
|
+
def make_request(env)
|
|
53
|
+
middleware.call(env)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "without an exception" do
|
|
57
|
+
it "reports a process_action.generic event" do
|
|
58
|
+
make_request(env)
|
|
59
|
+
|
|
60
|
+
expect(last_transaction).to include_event("name" => "process_action.generic")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "with action name env" do
|
|
65
|
+
it "reports the appsignal.action env as the action name" do
|
|
66
|
+
env["appsignal.action"] = "MyAction"
|
|
67
|
+
make_request(env)
|
|
68
|
+
|
|
69
|
+
expect(last_transaction).to have_action("MyAction")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context "without action name metadata" do
|
|
74
|
+
it "reports 'unknown' as the action name" do
|
|
75
|
+
make_request(env)
|
|
24
76
|
|
|
25
|
-
|
|
77
|
+
expect(last_transaction).to have_action("unknown")
|
|
78
|
+
end
|
|
26
79
|
end
|
|
27
80
|
end
|
|
28
81
|
end
|
|
@@ -5,7 +5,7 @@ if DependencyHelper.grape_present?
|
|
|
5
5
|
let(:err_stream) { std_stream }
|
|
6
6
|
let(:stderr) { err_stream.read }
|
|
7
7
|
|
|
8
|
-
it "returns the
|
|
8
|
+
it "returns the Rack::GrapeMiddleware constant calling the Grape::Middleware constant" do
|
|
9
9
|
silence { expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware) }
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
describe Appsignal::Rack::InstrumentationMiddleware do
|
|
2
|
+
let(:app) { DummyApp.new }
|
|
3
|
+
let(:env) { Rack::MockRequest.env_for("/some/path") }
|
|
4
|
+
let(:middleware) { described_class.new(app, {}) }
|
|
5
|
+
|
|
6
|
+
before { start_agent }
|
|
7
|
+
around { |example| keep_transactions { example.run } }
|
|
8
|
+
|
|
9
|
+
def make_request(env)
|
|
10
|
+
middleware.call(env)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context "without an exception" do
|
|
14
|
+
it "reports a process_request_middleware.rack event" do
|
|
15
|
+
make_request(env)
|
|
16
|
+
|
|
17
|
+
expect(last_transaction).to include_event("name" => "process_request_middleware.rack")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "with custom action name" do
|
|
22
|
+
let(:app) { DummyApp.new { |_env| Appsignal.set_action("MyAction") } }
|
|
23
|
+
|
|
24
|
+
it "reports the custom action name" do
|
|
25
|
+
make_request(env)
|
|
26
|
+
|
|
27
|
+
expect(last_transaction).to have_action("MyAction")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "without action name metadata" do
|
|
32
|
+
it "reports no action name" do
|
|
33
|
+
make_request(env)
|
|
34
|
+
|
|
35
|
+
expect(last_transaction).to_not have_action
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -114,8 +114,10 @@ if DependencyHelper.rails_present?
|
|
|
114
114
|
make_request
|
|
115
115
|
|
|
116
116
|
expect(last_transaction).to_not include_metadata("method" => anything)
|
|
117
|
-
expect(log_contents(log))
|
|
118
|
-
|
|
117
|
+
expect(log_contents(log)).to contains_log(
|
|
118
|
+
:error,
|
|
119
|
+
"Exception while fetching the HTTP request method: "
|
|
120
|
+
)
|
|
119
121
|
end
|
|
120
122
|
end
|
|
121
123
|
|
|
@@ -1,146 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
let(:env) do
|
|
5
|
-
{
|
|
6
|
-
"rack.input" => StringIO.new,
|
|
7
|
-
"REQUEST_METHOD" => "GET",
|
|
8
|
-
"PATH_INFO" => "/homepage",
|
|
9
|
-
"QUERY_STRING" => "param=something"
|
|
10
|
-
}
|
|
1
|
+
describe "Appsignal::Rack::StreamingListener" do
|
|
2
|
+
def load_middleware
|
|
3
|
+
load "lib/appsignal/rack/streaming_listener.rb"
|
|
11
4
|
end
|
|
12
|
-
let(:app) { DummyApp.new }
|
|
13
|
-
let(:listener) { Appsignal::Rack::StreamingListener.new(app, {}) }
|
|
14
|
-
before(:context) { start_agent }
|
|
15
|
-
around { |example| keep_transactions { example.run } }
|
|
16
5
|
|
|
17
|
-
describe "
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
describe "loading the streaming_listener integrations file" do
|
|
7
|
+
let(:err_stream) { std_stream }
|
|
8
|
+
let(:stderr) { err_stream.read }
|
|
9
|
+
after { Appsignal::Rack.send(:remove_const, :StreamingListener) }
|
|
20
10
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
end.to_not(change { created_transactions.count })
|
|
11
|
+
it "prints a deprecation warning to STDERR" do
|
|
12
|
+
capture_std_streams(std_stream, err_stream) do
|
|
13
|
+
load_middleware
|
|
25
14
|
end
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
16
|
+
expect(stderr).to include(
|
|
17
|
+
"appsignal WARNING: The constant Appsignal::Rack::StreamingListener " \
|
|
18
|
+
"has been deprecated."
|
|
19
|
+
)
|
|
32
20
|
end
|
|
33
21
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
it "creates a transaction" do
|
|
42
|
-
expect do
|
|
43
|
-
listener.call(env)
|
|
44
|
-
end.to(change { created_transactions.count }.by(1))
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it "instruments the call" do
|
|
48
|
-
listener.call(env)
|
|
49
|
-
|
|
50
|
-
expect(last_transaction).to include_event("name" => "process_action.rack")
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "set `appsignal.action` to the action name" do
|
|
54
|
-
env["appsignal.action"] = "Action"
|
|
55
|
-
|
|
56
|
-
listener.call(env)
|
|
57
|
-
|
|
58
|
-
expect(last_transaction).to have_action("Action")
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "adds the path, method and queue start to the transaction" do
|
|
62
|
-
listener.call(env)
|
|
63
|
-
|
|
64
|
-
expect(last_transaction).to include_metadata(
|
|
65
|
-
"path" => "/homepage",
|
|
66
|
-
"method" => "GET"
|
|
67
|
-
)
|
|
68
|
-
expect(last_transaction).to have_queue_start
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
context "with an exception in the instrumentation call" do
|
|
72
|
-
let(:error) { ExampleException.new("error message") }
|
|
73
|
-
let(:app) { DummyApp.new { raise error } }
|
|
74
|
-
|
|
75
|
-
it "adds the exception to the transaction" do
|
|
76
|
-
expect do
|
|
77
|
-
listener.call(env)
|
|
78
|
-
end.to raise_error(error)
|
|
79
|
-
|
|
80
|
-
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
22
|
+
it "logs a warning" do
|
|
23
|
+
logs =
|
|
24
|
+
capture_logs do
|
|
25
|
+
silence do
|
|
26
|
+
load_middleware
|
|
27
|
+
end
|
|
81
28
|
end
|
|
82
|
-
end
|
|
83
29
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
end
|
|
30
|
+
expect(logs).to contains_log(
|
|
31
|
+
:warn,
|
|
32
|
+
"The constant Appsignal::Rack::StreamingListener has been deprecated."
|
|
33
|
+
)
|
|
89
34
|
end
|
|
90
35
|
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
describe Appsignal::StreamWrapper do
|
|
94
|
-
let(:stream) { double }
|
|
95
|
-
let(:transaction) { http_request_transaction }
|
|
96
|
-
let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
|
|
97
|
-
before do
|
|
98
|
-
start_agent
|
|
99
|
-
set_current_transaction(transaction)
|
|
100
|
-
end
|
|
101
|
-
around { |example| keep_transactions { example.run } }
|
|
102
36
|
|
|
103
|
-
describe "
|
|
104
|
-
|
|
105
|
-
|
|
37
|
+
describe "middleware" do
|
|
38
|
+
let(:env) { {} }
|
|
39
|
+
let(:app) { DummyApp.new }
|
|
40
|
+
let(:middleware) { Appsignal::Rack::StreamingListener.new(app, {}) }
|
|
41
|
+
around { |example| keep_transactions { example.run } }
|
|
42
|
+
before(:context) { load_middleware }
|
|
43
|
+
before { start_agent }
|
|
106
44
|
|
|
107
|
-
|
|
45
|
+
def make_request
|
|
46
|
+
middleware.call(env)
|
|
108
47
|
end
|
|
109
48
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
it "records the exception" do
|
|
114
|
-
allow(stream).to receive(:each).and_raise(error)
|
|
49
|
+
it "instruments the call" do
|
|
50
|
+
make_request
|
|
115
51
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
expect(transaction).to have_error("ExampleException", "error message")
|
|
119
|
-
end
|
|
52
|
+
expect(last_transaction).to include_event("name" => "process_streaming_request.rack")
|
|
120
53
|
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
describe "#close" do
|
|
124
|
-
it "closes the original stream and completes the transaction" do
|
|
125
|
-
expect(stream).to receive(:close)
|
|
126
54
|
|
|
127
|
-
|
|
55
|
+
it "set no action by default" do
|
|
56
|
+
make_request
|
|
128
57
|
|
|
129
|
-
expect(
|
|
130
|
-
expect(transaction).to be_completed
|
|
58
|
+
expect(last_transaction).to_not have_action
|
|
131
59
|
end
|
|
132
60
|
|
|
133
|
-
|
|
134
|
-
|
|
61
|
+
it "set `appsignal.action` to the action name" do
|
|
62
|
+
env["appsignal.action"] = "Action"
|
|
135
63
|
|
|
136
|
-
|
|
137
|
-
allow(stream).to receive(:close).and_raise(error)
|
|
64
|
+
make_request
|
|
138
65
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
expect(transaction).to have_error("ExampleException", "error message")
|
|
142
|
-
expect(transaction).to be_completed
|
|
143
|
-
end
|
|
66
|
+
expect(last_transaction).to have_action("Action")
|
|
144
67
|
end
|
|
145
68
|
end
|
|
146
69
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
describe Appsignal::Rack::Utils do
|
|
2
|
+
describe ".queue_start_from" do
|
|
3
|
+
let(:header_time) { fixed_time - 0.4 }
|
|
4
|
+
let(:header_time_value) { (header_time * factor).to_i }
|
|
5
|
+
subject { described_class.queue_start_from(env) }
|
|
6
|
+
|
|
7
|
+
shared_examples "HTTP queue start" do
|
|
8
|
+
context "when env is nil" do
|
|
9
|
+
let(:env) { nil }
|
|
10
|
+
|
|
11
|
+
it { is_expected.to be_nil }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "with no relevant header set" do
|
|
15
|
+
let(:env) { {} }
|
|
16
|
+
|
|
17
|
+
it { is_expected.to be_nil }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "with the HTTP_X_REQUEST_START header set" do
|
|
21
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time_value}" } }
|
|
22
|
+
|
|
23
|
+
it { is_expected.to eq 1_389_783_599_600 }
|
|
24
|
+
|
|
25
|
+
context "with unparsable content" do
|
|
26
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "something" } }
|
|
27
|
+
|
|
28
|
+
it { is_expected.to be_nil }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "with unparsable content at the end" do
|
|
32
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time_value}aaaa" } }
|
|
33
|
+
|
|
34
|
+
it { is_expected.to eq 1_389_783_599_600 }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context "with a really low number" do
|
|
38
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "t=100" } }
|
|
39
|
+
|
|
40
|
+
it { is_expected.to be_nil }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "with the alternate HTTP_X_QUEUE_START header set" do
|
|
44
|
+
let(:env) { { "HTTP_X_QUEUE_START" => "t=#{header_time_value}" } }
|
|
45
|
+
|
|
46
|
+
it { is_expected.to eq 1_389_783_599_600 }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "time in milliseconds" do
|
|
52
|
+
let(:factor) { 1_000 }
|
|
53
|
+
|
|
54
|
+
it_should_behave_like "HTTP queue start"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "time in microseconds" do
|
|
58
|
+
let(:factor) { 1_000_000 }
|
|
59
|
+
|
|
60
|
+
it_should_behave_like "HTTP queue start"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|