appsignal 3.13.0-java → 4.0.0.beta.1-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 +499 -487
- data/CHANGELOG.md +113 -0
- data/Rakefile +31 -7
- data/benchmark.rake +4 -6
- data/build_matrix.yml +45 -39
- data/ext/agent.rb +27 -27
- data/ext/appsignal_extension.c +25 -0
- data/gemfiles/rails-7.2.gemfile +11 -0
- data/lib/appsignal/check_in/cron.rb +2 -15
- data/lib/appsignal/cli/diagnose.rb +37 -28
- data/lib/appsignal/cli/install.rb +5 -1
- data/lib/appsignal/config.rb +57 -119
- data/lib/appsignal/demo.rb +2 -2
- data/lib/appsignal/extension/jruby.rb +14 -0
- data/lib/appsignal/helpers/instrumentation.rb +139 -417
- data/lib/appsignal/helpers/metrics.rb +0 -16
- data/lib/appsignal/hooks/action_cable.rb +8 -8
- data/lib/appsignal/hooks/active_job.rb +2 -2
- data/lib/appsignal/hooks/at_exit.rb +37 -0
- data/lib/appsignal/hooks.rb +1 -16
- data/lib/appsignal/integrations/action_cable.rb +2 -2
- data/lib/appsignal/integrations/capistrano/appsignal.cap +2 -4
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +1 -4
- data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -3
- data/lib/appsignal/integrations/que.rb +2 -2
- data/lib/appsignal/integrations/railtie.rb +26 -59
- data/lib/appsignal/integrations/rake.rb +2 -2
- data/lib/appsignal/integrations/resque.rb +2 -2
- data/lib/appsignal/integrations/shoryuken.rb +4 -4
- data/lib/appsignal/integrations/sidekiq.rb +3 -3
- data/lib/appsignal/integrations/webmachine.rb +2 -2
- data/lib/appsignal/loaders.rb +1 -1
- data/lib/appsignal/probes.rb +0 -9
- data/lib/appsignal/rack/abstract_middleware.rb +4 -26
- data/lib/appsignal/rack/event_handler.rb +4 -4
- data/lib/appsignal/rack/rails_instrumentation.rb +1 -1
- data/lib/appsignal/rack.rb +0 -25
- data/lib/appsignal/sample_data.rb +95 -0
- data/lib/appsignal/transaction.rb +235 -361
- data/lib/appsignal/utils/rails_helper.rb +4 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +19 -71
- data/spec/lib/appsignal/auth_check_spec.rb +1 -1
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/capistrano3_spec.rb +53 -13
- data/spec/lib/appsignal/check_in_spec.rb +1 -207
- data/spec/lib/appsignal/cli/demo_spec.rb +7 -27
- data/spec/lib/appsignal/cli/diagnose_spec.rb +145 -110
- data/spec/lib/appsignal/config_spec.rb +304 -379
- data/spec/lib/appsignal/extension_install_failure_spec.rb +5 -1
- data/spec/lib/appsignal/extension_spec.rb +5 -1
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -2
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +1 -0
- data/spec/lib/appsignal/hooks/activejob_spec.rb +7 -12
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +72 -0
- data/spec/lib/appsignal/hooks/gvl_spec.rb +10 -5
- data/spec/lib/appsignal/hooks/http_spec.rb +3 -3
- data/spec/lib/appsignal/hooks/net_http_spec.rb +3 -3
- data/spec/lib/appsignal/hooks/rake_spec.rb +6 -9
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -10
- data/spec/lib/appsignal/hooks/redis_spec.rb +4 -7
- data/spec/lib/appsignal/hooks/resque_spec.rb +3 -5
- data/spec/lib/appsignal/hooks_spec.rb +0 -41
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +29 -20
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +4 -9
- data/spec/lib/appsignal/integrations/railtie_spec.rb +179 -157
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +3 -5
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +48 -62
- data/spec/lib/appsignal/loaders/hanami_spec.rb +6 -9
- data/spec/lib/appsignal/loaders/padrino_spec.rb +6 -10
- data/spec/lib/appsignal/loaders/sinatra_spec.rb +6 -9
- data/spec/lib/appsignal/loaders_spec.rb +8 -1
- data/spec/lib/appsignal/marker_spec.rb +1 -1
- data/spec/lib/appsignal/probes_spec.rb +4 -83
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +4 -63
- data/spec/lib/appsignal/rack/event_handler_spec.rb +18 -15
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +3 -11
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +4 -5
- data/spec/lib/appsignal/sample_data_spec.rb +174 -0
- data/spec/lib/appsignal/transaction_spec.rb +791 -1031
- data/spec/lib/appsignal/transmitter_spec.rb +6 -8
- data/spec/lib/appsignal_spec.rb +294 -643
- data/spec/spec_helper.rb +1 -3
- data/spec/support/fixtures/projects/valid/config/appsignal.yml +4 -7
- data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +16 -0
- data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +56 -0
- data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +5 -0
- data/spec/support/helpers/api_request_helper.rb +3 -2
- data/spec/support/helpers/config_helpers.rb +41 -11
- data/spec/support/helpers/dependency_helper.rb +8 -0
- data/spec/support/helpers/log_helpers.rb +1 -0
- data/spec/support/helpers/rails_helper.rb +6 -6
- data/spec/support/helpers/transaction_helpers.rb +2 -24
- data/spec/support/matchers/transaction.rb +3 -3
- data/spec/support/mocks/appsignal_mock.rb +3 -3
- data/spec/support/mocks/mock_probe.rb +2 -0
- data/spec/support/testing.rb +2 -2
- metadata +12 -22
- data/gemfiles/que_beta.gemfile +0 -5
- data/lib/appsignal/helpers/heartbeat.rb +0 -20
- data/lib/appsignal/integrations/grape.rb +0 -35
- data/lib/appsignal/integrations/hanami.rb +0 -13
- data/lib/appsignal/integrations/padrino.rb +0 -13
- data/lib/appsignal/integrations/sinatra.rb +0 -13
- data/lib/appsignal/rack/generic_instrumentation.rb +0 -22
- data/lib/appsignal/rack/streaming_listener.rb +0 -28
- data/spec/lib/appsignal/integrations/grape_spec.rb +0 -36
- data/spec/lib/appsignal/integrations/hanami_spec.rb +0 -17
- data/spec/lib/appsignal/integrations/padrino_spec.rb +0 -15
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -15
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +0 -81
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +0 -69
- data/spec/support/fixtures/projects/valid/config/environments/development.rb +0 -0
- data/spec/support/fixtures/projects/valid/config/environments/production.rb +0 -0
- data/spec/support/fixtures/projects/valid/config/environments/test.rb +0 -0
- data/spec/support/rails/my_app.rb +0 -6
- /data/spec/support/fixtures/projects/{valid/config/application.rb → valid_with_rails_app/log/.gitkeep} +0 -0
@@ -1,8 +1,9 @@
|
|
1
1
|
describe Appsignal::Transaction do
|
2
|
+
let(:options) { {} }
|
2
3
|
let(:time) { Time.at(fixed_time) }
|
3
4
|
|
4
5
|
before do
|
5
|
-
start_agent
|
6
|
+
start_agent(:options => options)
|
6
7
|
Timecop.freeze(time)
|
7
8
|
end
|
8
9
|
after { Timecop.return }
|
@@ -32,86 +33,13 @@ describe Appsignal::Transaction do
|
|
32
33
|
transaction = create_transaction
|
33
34
|
expect(transaction).to eq current_transaction
|
34
35
|
end
|
36
|
+
end
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
transaction_id = "mock-id"
|
39
|
-
namespace = "my_namespace"
|
40
|
-
transaction = legacy_create_transaction(
|
41
|
-
:id => transaction_id,
|
42
|
-
:namespace => namespace
|
43
|
-
)
|
44
|
-
expect(transaction).to be_a(Appsignal::Transaction)
|
45
|
-
|
46
|
-
expect(transaction).to have_id(transaction_id)
|
47
|
-
expect(transaction.transaction_id).to eq(transaction_id)
|
48
|
-
|
49
|
-
expect(transaction).to have_namespace(namespace)
|
50
|
-
expect(transaction.namespace).to eq(namespace)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "logs deprecation warnings" do
|
54
|
-
logs =
|
55
|
-
capture_logs do
|
56
|
-
legacy_create_transaction(
|
57
|
-
:id => "mock-id",
|
58
|
-
:namespace => "my_namespace",
|
59
|
-
:request => Appsignal::Transaction::InternalGenericRequest.new({}),
|
60
|
-
:options => { :force => true }
|
61
|
-
)
|
62
|
-
end
|
63
|
-
|
64
|
-
expect(logs).to contains_log(
|
65
|
-
:warn,
|
66
|
-
"Appsignal::Transaction.create: " \
|
67
|
-
"A new Transaction is created using the transaction ID argument."
|
68
|
-
)
|
69
|
-
expect(logs).to contains_log(
|
70
|
-
:warn,
|
71
|
-
"Appsignal::Transaction.create: " \
|
72
|
-
"A Transaction is created using the namespace argument."
|
73
|
-
)
|
74
|
-
expect(logs).to contains_log(
|
75
|
-
:warn,
|
76
|
-
"Appsignal::Transaction.create: " \
|
77
|
-
"A Transaction is created using the request argument."
|
78
|
-
)
|
79
|
-
expect(logs).to contains_log(
|
80
|
-
:warn,
|
81
|
-
"Appsignal::Transaction.create: " \
|
82
|
-
"A Transaction is created using the `:force => true` option argument. "
|
83
|
-
)
|
84
|
-
end
|
85
|
-
|
86
|
-
it "prints deprecation warnings" do
|
87
|
-
err_stream = std_stream
|
88
|
-
capture_std_streams(std_stream, err_stream) do
|
89
|
-
legacy_create_transaction(
|
90
|
-
:id => "mock-id",
|
91
|
-
:namespace => "my_namespace",
|
92
|
-
:request => Appsignal::Transaction::InternalGenericRequest.new({}),
|
93
|
-
:options => { :force => true }
|
94
|
-
)
|
95
|
-
end
|
38
|
+
context "when an explicit extension transaction is passed in the initialiser" do
|
39
|
+
let(:ext) { "some_ext" }
|
96
40
|
|
97
|
-
|
98
|
-
|
99
|
-
"appsignal WARNING: Appsignal::Transaction.create: " \
|
100
|
-
"A new Transaction is created using the transaction ID argument."
|
101
|
-
)
|
102
|
-
expect(stderr).to include(
|
103
|
-
"appsignal WARNING: Appsignal::Transaction.create: " \
|
104
|
-
"A Transaction is created using the namespace argument."
|
105
|
-
)
|
106
|
-
expect(stderr).to include(
|
107
|
-
"appsignal WARNING: Appsignal::Transaction.create: " \
|
108
|
-
"A Transaction is created using the request argument."
|
109
|
-
)
|
110
|
-
expect(stderr).to include(
|
111
|
-
"appsignal WARNING: Appsignal::Transaction.create: " \
|
112
|
-
"A Transaction is created using the `:force => true` option argument. "
|
113
|
-
)
|
114
|
-
end
|
41
|
+
it "assigns the extension transaction to the transaction" do
|
42
|
+
expect(new_transaction(:ext => ext).ext).to be(ext)
|
115
43
|
end
|
116
44
|
end
|
117
45
|
|
@@ -137,28 +65,9 @@ describe Appsignal::Transaction do
|
|
137
65
|
logs = capture_logs { create_transaction }
|
138
66
|
|
139
67
|
expect(logs).to contains_log :warn,
|
140
|
-
"Trying to start new transaction
|
141
|
-
"
|
142
|
-
"
|
143
|
-
end
|
144
|
-
|
145
|
-
context "with option :force => true" do
|
146
|
-
it "returns the newly created (and current) transaction" do
|
147
|
-
original_transaction = create_transaction
|
148
|
-
|
149
|
-
expect(original_transaction).to be_a(Appsignal::Transaction)
|
150
|
-
expect(current_transaction).to have_id("transaction_id_1")
|
151
|
-
|
152
|
-
new_transaction = legacy_create_transaction(
|
153
|
-
:id => "transaction_id_2",
|
154
|
-
:options => { :force => true }
|
155
|
-
)
|
156
|
-
|
157
|
-
expect(new_transaction).to be_a(Appsignal::Transaction)
|
158
|
-
expect(new_transaction).to_not eq(original_transaction)
|
159
|
-
expect(new_transaction).to have_id("transaction_id_2")
|
160
|
-
expect(current_transaction).to eq(new_transaction)
|
161
|
-
end
|
68
|
+
"Trying to start new transaction, but a transaction with id " \
|
69
|
+
"'transaction_id_1' is already running. " \
|
70
|
+
"Using transaction 'transaction_id_1'."
|
162
71
|
end
|
163
72
|
end
|
164
73
|
end
|
@@ -252,7 +161,7 @@ describe Appsignal::Transaction do
|
|
252
161
|
|
253
162
|
context "when transaction is being sampled" do
|
254
163
|
it "samples data" do
|
255
|
-
transaction.
|
164
|
+
transaction.add_tags(:foo => "bar")
|
256
165
|
keep_transactions { transaction.complete }
|
257
166
|
expect(transaction).to include_tags("foo" => "bar")
|
258
167
|
end
|
@@ -299,6 +208,306 @@ describe Appsignal::Transaction do
|
|
299
208
|
end
|
300
209
|
end
|
301
210
|
end
|
211
|
+
|
212
|
+
context "when a transaction has errors" do
|
213
|
+
let(:error) do
|
214
|
+
e = ExampleStandardError.new("test message")
|
215
|
+
allow(e).to receive(:backtrace).and_return(["line 1"])
|
216
|
+
e
|
217
|
+
end
|
218
|
+
|
219
|
+
let(:other_error) do
|
220
|
+
e = ExampleStandardError.new("other test message")
|
221
|
+
allow(e).to receive(:backtrace).and_return(["line 2"])
|
222
|
+
e
|
223
|
+
end
|
224
|
+
|
225
|
+
context "when an error is already set on the transaction" do
|
226
|
+
it "reports errors as duplicate transactions" do
|
227
|
+
transaction.set_error(error)
|
228
|
+
transaction.add_error(other_error)
|
229
|
+
|
230
|
+
expect do
|
231
|
+
transaction.complete
|
232
|
+
end.to change { created_transactions.count }.from(1).to(2)
|
233
|
+
|
234
|
+
original_transaction, duplicate_transaction = created_transactions
|
235
|
+
|
236
|
+
expect(original_transaction).to have_error(
|
237
|
+
"ExampleStandardError",
|
238
|
+
"test message",
|
239
|
+
["line 1"]
|
240
|
+
)
|
241
|
+
expect(original_transaction).to be_completed
|
242
|
+
|
243
|
+
expect(duplicate_transaction).to have_error(
|
244
|
+
"ExampleStandardError",
|
245
|
+
"other test message",
|
246
|
+
["line 2"]
|
247
|
+
)
|
248
|
+
expect(duplicate_transaction).to be_completed
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context "when no error is set on the transaction" do
|
253
|
+
it "reports the first error in the original transaction" do
|
254
|
+
transaction.add_error(error)
|
255
|
+
transaction.add_error(other_error)
|
256
|
+
|
257
|
+
expect do
|
258
|
+
transaction.complete
|
259
|
+
end.to change { created_transactions.count }.from(1).to(2)
|
260
|
+
|
261
|
+
original_transaction, duplicate_transaction = created_transactions
|
262
|
+
|
263
|
+
expect(original_transaction).to have_error(
|
264
|
+
"ExampleStandardError",
|
265
|
+
"test message",
|
266
|
+
["line 1"]
|
267
|
+
)
|
268
|
+
expect(original_transaction).to be_completed
|
269
|
+
|
270
|
+
expect(duplicate_transaction).to have_error(
|
271
|
+
"ExampleStandardError",
|
272
|
+
"other test message",
|
273
|
+
["line 2"]
|
274
|
+
)
|
275
|
+
expect(duplicate_transaction).to be_completed
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
it "stores the last reported errors" do
|
280
|
+
transaction.add_error(error)
|
281
|
+
transaction.add_error(other_error)
|
282
|
+
transaction.complete
|
283
|
+
|
284
|
+
expect(Appsignal::Transaction.last_errors).to contain_exactly(error, other_error)
|
285
|
+
end
|
286
|
+
|
287
|
+
describe "metadata" do
|
288
|
+
let(:tags) { { "tag" => "value" } }
|
289
|
+
let(:params) { { "param" => "value" } }
|
290
|
+
let(:headers) { { "REQUEST_METHOD" => "value" } }
|
291
|
+
let(:session_data) { { "session_data" => "value" } }
|
292
|
+
let(:custom_data) { { "custom_data" => "value" } }
|
293
|
+
before do
|
294
|
+
transaction.set_namespace("My namespace")
|
295
|
+
transaction.set_action("My action")
|
296
|
+
transaction.set_metadata("path", "/some/path")
|
297
|
+
transaction.set_metadata("method", "GET")
|
298
|
+
transaction.add_tags(tags)
|
299
|
+
transaction.add_params(params)
|
300
|
+
transaction.add_headers(headers)
|
301
|
+
transaction.add_session_data(session_data)
|
302
|
+
transaction.add_custom_data(custom_data)
|
303
|
+
transaction.add_breadcrumb("category", "action", "message", { "meta" => "data" })
|
304
|
+
|
305
|
+
transaction.start_event
|
306
|
+
transaction.finish_event("name", "title", "body", 1)
|
307
|
+
|
308
|
+
transaction.add_error(error)
|
309
|
+
transaction.add_error(other_error)
|
310
|
+
|
311
|
+
transaction.complete
|
312
|
+
end
|
313
|
+
|
314
|
+
it "copies the transaction metadata and sample data on the duplicate transaction" do
|
315
|
+
original_transaction, duplicate_transaction = created_transactions
|
316
|
+
|
317
|
+
duplicate_hash = duplicate_transaction.to_h.tap do |h|
|
318
|
+
h.delete("id")
|
319
|
+
h.delete("error")
|
320
|
+
end
|
321
|
+
original_hash = original_transaction.to_h.tap do |h|
|
322
|
+
h.delete("id")
|
323
|
+
h.delete("error")
|
324
|
+
end
|
325
|
+
expect(duplicate_hash).to eq(original_hash)
|
326
|
+
end
|
327
|
+
|
328
|
+
it "the duplicate transaction has a different transaction id" do
|
329
|
+
original_transaction, duplicate_transaction = created_transactions
|
330
|
+
|
331
|
+
expect(original_transaction.transaction_id)
|
332
|
+
.to_not eq(duplicate_transaction.transaction_id)
|
333
|
+
end
|
334
|
+
|
335
|
+
it "the duplicate transaction has a different extension transaction than the original" do
|
336
|
+
original_transaction, duplicate_transaction = created_transactions
|
337
|
+
|
338
|
+
expect(original_transaction.ext).to_not eq(duplicate_transaction.ext)
|
339
|
+
end
|
340
|
+
|
341
|
+
it "sets is_duplicate set to true on the duplicate transaction" do
|
342
|
+
original_transaction, duplicate_transaction = created_transactions
|
343
|
+
|
344
|
+
expect(original_transaction.is_duplicate).to be(false)
|
345
|
+
expect(duplicate_transaction.is_duplicate).to be(true)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
it "merges sample data from the original transaction in the duplicate transaction" do
|
350
|
+
transaction.add_tags("root" => "tag")
|
351
|
+
transaction.add_params("root" => "param")
|
352
|
+
transaction.add_session_data("root" => "session")
|
353
|
+
transaction.add_headers("REQUEST_METHOD" => "root")
|
354
|
+
transaction.add_custom_data("root" => "custom")
|
355
|
+
transaction.add_breadcrumb("root", "breadcrumb")
|
356
|
+
Appsignal.report_error(error) do |t|
|
357
|
+
t.add_tags("original" => "tag")
|
358
|
+
t.add_params("original" => "param")
|
359
|
+
t.add_session_data("original" => "session")
|
360
|
+
t.add_headers("REQUEST_PATH" => "/original")
|
361
|
+
t.add_custom_data("original" => "custom")
|
362
|
+
t.add_breadcrumb("original", "breadcrumb")
|
363
|
+
end
|
364
|
+
Appsignal.report_error(other_error) do |t|
|
365
|
+
t.add_tags("duplicate" => "tag")
|
366
|
+
t.add_params("duplicate" => "param")
|
367
|
+
t.add_session_data("duplicate" => "session")
|
368
|
+
t.add_headers("HTTP_ACCEPT" => "duplicate")
|
369
|
+
t.add_custom_data("duplicate" => "custom")
|
370
|
+
t.add_breadcrumb("duplicate", "breadcrumb")
|
371
|
+
end
|
372
|
+
transaction.add_tags("root2" => "tag")
|
373
|
+
transaction.add_params("root2" => "param")
|
374
|
+
transaction.add_session_data("root2" => "session")
|
375
|
+
transaction.add_headers("PATH_INFO" => "/root2")
|
376
|
+
transaction.add_custom_data("root2" => "custom")
|
377
|
+
transaction.add_breadcrumb("root2", "breadcrumb")
|
378
|
+
transaction.complete
|
379
|
+
|
380
|
+
original_transaction, duplicate_transaction = created_transactions
|
381
|
+
# Original
|
382
|
+
expect(original_transaction).to include_tags(
|
383
|
+
"root" => "tag",
|
384
|
+
"original" => "tag",
|
385
|
+
"root2" => "tag"
|
386
|
+
)
|
387
|
+
expect(original_transaction).to_not include_tags("duplicate" => anything)
|
388
|
+
expect(original_transaction).to include_params(
|
389
|
+
"root" => "param",
|
390
|
+
"original" => "param",
|
391
|
+
"root2" => "param"
|
392
|
+
)
|
393
|
+
expect(original_transaction).to_not include_params("duplicate" => anything)
|
394
|
+
expect(original_transaction).to include_session_data(
|
395
|
+
"root" => "session",
|
396
|
+
"original" => "session",
|
397
|
+
"root2" => "session"
|
398
|
+
)
|
399
|
+
expect(original_transaction).to_not include_session_data("duplicate" => anything)
|
400
|
+
expect(original_transaction).to include_environment(
|
401
|
+
"REQUEST_METHOD" => "root",
|
402
|
+
"REQUEST_PATH" => "/original",
|
403
|
+
"PATH_INFO" => "/root2"
|
404
|
+
)
|
405
|
+
expect(original_transaction).to_not include_environment("HTTP_ACCEPT" => anything)
|
406
|
+
expect(original_transaction).to include_custom_data(
|
407
|
+
"root" => "custom",
|
408
|
+
"original" => "custom",
|
409
|
+
"root2" => "custom"
|
410
|
+
)
|
411
|
+
expect(original_transaction).to_not include_custom_data("duplicate" => anything)
|
412
|
+
expect(original_transaction).to include_breadcrumb("breadcrumb", "root")
|
413
|
+
expect(original_transaction).to include_breadcrumb("breadcrumb", "original")
|
414
|
+
expect(original_transaction).to include_breadcrumb("breadcrumb", "root2")
|
415
|
+
expect(original_transaction).to_not include_breadcrumb("breadcrumb", "duplicate")
|
416
|
+
|
417
|
+
# Duplicate
|
418
|
+
expect(duplicate_transaction).to include_tags(
|
419
|
+
"root" => "tag",
|
420
|
+
"duplicate" => "tag",
|
421
|
+
"root2" => "tag"
|
422
|
+
)
|
423
|
+
expect(duplicate_transaction).to_not include_tags("original" => anything)
|
424
|
+
expect(duplicate_transaction).to include_params(
|
425
|
+
"root" => "param",
|
426
|
+
"duplicate" => "param",
|
427
|
+
"root2" => "param"
|
428
|
+
)
|
429
|
+
expect(duplicate_transaction).to_not include_params("original" => anything)
|
430
|
+
expect(duplicate_transaction).to include_session_data(
|
431
|
+
"root" => "session",
|
432
|
+
"duplicate" => "session",
|
433
|
+
"root2" => "session"
|
434
|
+
)
|
435
|
+
expect(duplicate_transaction).to_not include_session_data("original" => anything)
|
436
|
+
expect(duplicate_transaction).to include_environment(
|
437
|
+
"PATH_INFO" => "/root2",
|
438
|
+
"HTTP_ACCEPT" => "duplicate",
|
439
|
+
"REQUEST_METHOD" => "root"
|
440
|
+
)
|
441
|
+
expect(duplicate_transaction).to_not include_environment("REQUEST_PATH" => anything)
|
442
|
+
expect(duplicate_transaction).to include_custom_data(
|
443
|
+
"root" => "custom",
|
444
|
+
"duplicate" => "custom",
|
445
|
+
"root2" => "custom"
|
446
|
+
)
|
447
|
+
expect(duplicate_transaction).to_not include_custom_data("original" => anything)
|
448
|
+
expect(duplicate_transaction).to include_breadcrumb("breadcrumb", "root")
|
449
|
+
expect(duplicate_transaction).to include_breadcrumb("breadcrumb", "duplicate")
|
450
|
+
expect(duplicate_transaction).to include_breadcrumb("breadcrumb", "root2")
|
451
|
+
expect(duplicate_transaction).to_not include_breadcrumb("breadcrumb", "original")
|
452
|
+
end
|
453
|
+
|
454
|
+
it "overrides sample data from the original transaction in the duplicate transaction" do
|
455
|
+
transaction.add_tags("changeme" => "tag")
|
456
|
+
transaction.add_params("changeme" => "param")
|
457
|
+
transaction.add_session_data("changeme" => "session")
|
458
|
+
transaction.add_headers("REQUEST_METHOD" => "root")
|
459
|
+
transaction.add_custom_data("changeme" => "custom")
|
460
|
+
Appsignal.report_error(error)
|
461
|
+
Appsignal.report_error(other_error) do |t|
|
462
|
+
t.add_tags("changeme" => "duplicate_tag")
|
463
|
+
t.add_params("changeme" => "duplicate_param")
|
464
|
+
t.add_session_data("changeme" => "duplicate_session")
|
465
|
+
t.add_headers("REQUEST_METHOD" => "duplicate")
|
466
|
+
t.add_custom_data("changeme" => "duplicate_custom")
|
467
|
+
end
|
468
|
+
transaction.add_tags("changeme" => "changed_tag")
|
469
|
+
transaction.add_params("changeme" => "changed_param")
|
470
|
+
transaction.add_session_data("changeme" => "changed_session")
|
471
|
+
transaction.add_headers("REQUEST_METHOD" => "changed")
|
472
|
+
transaction.add_custom_data("changeme" => "changed_custom")
|
473
|
+
transaction.complete
|
474
|
+
|
475
|
+
original_transaction, duplicate_transaction = created_transactions
|
476
|
+
# Original
|
477
|
+
expect(original_transaction).to include_tags(
|
478
|
+
"changeme" => "changed_tag"
|
479
|
+
)
|
480
|
+
expect(original_transaction).to include_params(
|
481
|
+
"changeme" => "changed_param"
|
482
|
+
)
|
483
|
+
expect(original_transaction).to include_session_data(
|
484
|
+
"changeme" => "changed_session"
|
485
|
+
)
|
486
|
+
expect(original_transaction).to include_environment(
|
487
|
+
"REQUEST_METHOD" => "changed"
|
488
|
+
)
|
489
|
+
expect(original_transaction).to include_custom_data(
|
490
|
+
"changeme" => "changed_custom"
|
491
|
+
)
|
492
|
+
|
493
|
+
# Duplicate
|
494
|
+
expect(duplicate_transaction).to include_tags(
|
495
|
+
"changeme" => "duplicate_tag"
|
496
|
+
)
|
497
|
+
expect(duplicate_transaction).to include_params(
|
498
|
+
"changeme" => "duplicate_param"
|
499
|
+
)
|
500
|
+
expect(duplicate_transaction).to include_session_data(
|
501
|
+
"changeme" => "duplicate_session"
|
502
|
+
)
|
503
|
+
expect(duplicate_transaction).to include_environment(
|
504
|
+
"REQUEST_METHOD" => "duplicate"
|
505
|
+
)
|
506
|
+
expect(duplicate_transaction).to include_custom_data(
|
507
|
+
"changeme" => "duplicate_custom"
|
508
|
+
)
|
509
|
+
end
|
510
|
+
end
|
302
511
|
end
|
303
512
|
|
304
513
|
context "pausing" do
|
@@ -363,49 +572,9 @@ describe Appsignal::Transaction do
|
|
363
572
|
end
|
364
573
|
end
|
365
574
|
|
366
|
-
context "transaction id" do
|
367
|
-
before do
|
368
|
-
allow(SecureRandom).to receive(:uuid).and_return("mock_transaction_id")
|
369
|
-
end
|
370
|
-
|
371
|
-
it "sets the transaction id" do
|
372
|
-
expect(transaction).to have_id("mock_transaction_id")
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
575
|
it "sets the namespace to http_request" do
|
377
576
|
expect(transaction.namespace).to eq "http_request"
|
378
577
|
end
|
379
|
-
|
380
|
-
it "sets the request" do
|
381
|
-
expect(transaction.request).to be_a(Appsignal::Transaction::InternalGenericRequest)
|
382
|
-
end
|
383
|
-
|
384
|
-
it "sets the request not to paused" do
|
385
|
-
expect(transaction.paused?).to be_falsy
|
386
|
-
end
|
387
|
-
|
388
|
-
it "sets no tags by default" do
|
389
|
-
expect(transaction.tags).to be_empty
|
390
|
-
end
|
391
|
-
|
392
|
-
describe "#options" do
|
393
|
-
let(:options) { transaction.options }
|
394
|
-
|
395
|
-
it "sets the default :params_method" do
|
396
|
-
expect(options[:params_method]).to eq :params
|
397
|
-
end
|
398
|
-
|
399
|
-
context "with overridden options" do
|
400
|
-
let(:transaction) do
|
401
|
-
legacy_new_transaction(:options => { :params_method => :filtered_params })
|
402
|
-
end
|
403
|
-
|
404
|
-
it "sets the overridden :params_method" do
|
405
|
-
expect(options[:params_method]).to eq :filtered_params
|
406
|
-
end
|
407
|
-
end
|
408
|
-
end
|
409
578
|
end
|
410
579
|
|
411
580
|
describe "#store" do
|
@@ -423,174 +592,122 @@ describe Appsignal::Transaction do
|
|
423
592
|
end
|
424
593
|
end
|
425
594
|
|
426
|
-
describe "#
|
595
|
+
describe "#add_params" do
|
427
596
|
let(:transaction) { new_transaction }
|
428
|
-
let(:params) { transaction.params }
|
429
|
-
|
430
|
-
context "with custom params set on transaction" do
|
431
|
-
before { transaction.set_params(:foo => "bar") }
|
432
|
-
|
433
|
-
it "returns custom parameters" do
|
434
|
-
expect(params).to eq(:foo => "bar")
|
435
|
-
end
|
436
|
-
|
437
|
-
context "when params is a callable object" do
|
438
|
-
it "calls the params object and sets the return value as parametesr" do
|
439
|
-
transaction.set_params { { "param1" => "value1" } }
|
440
|
-
|
441
|
-
expect(params).to eq("param1" => "value1")
|
442
|
-
end
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
|
-
context "without custom params set on transaction" do
|
447
|
-
let(:transaction) do
|
448
|
-
legacy_new_transaction(
|
449
|
-
:request => legacy_request(
|
450
|
-
:params => {
|
451
|
-
"action" => "show",
|
452
|
-
"controller" => "blog_posts",
|
453
|
-
"id" => "1"
|
454
|
-
|
455
|
-
}
|
456
|
-
)
|
457
|
-
)
|
458
|
-
end
|
459
597
|
|
460
|
-
|
461
|
-
|
462
|
-
"action" => "show",
|
463
|
-
"controller" => "blog_posts",
|
464
|
-
"id" => "1"
|
465
|
-
)
|
466
|
-
end
|
598
|
+
it "has a #set_params alias" do
|
599
|
+
expect(transaction.method(:add_params)).to eq(transaction.method(:set_params))
|
467
600
|
end
|
468
|
-
end
|
469
601
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
it "sets params on the transaction" do
|
474
|
-
params = { "foo" => "bar" }
|
475
|
-
silence { transaction.params = params }
|
602
|
+
it "adds the params to the transaction" do
|
603
|
+
params = { "key" => "value" }
|
604
|
+
transaction.add_params(params)
|
476
605
|
|
477
606
|
transaction._sample
|
478
|
-
expect(transaction.params).to eq(params)
|
479
607
|
expect(transaction).to include_params(params)
|
480
608
|
end
|
481
609
|
|
482
|
-
it "
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
end
|
610
|
+
it "merges the params on the transaction" do
|
611
|
+
transaction.add_params("abc" => "value")
|
612
|
+
transaction.add_params("def" => "value")
|
613
|
+
transaction.add_params { { "xyz" => "value" } }
|
487
614
|
|
488
|
-
|
489
|
-
|
490
|
-
"
|
491
|
-
|
615
|
+
transaction._sample
|
616
|
+
expect(transaction).to include_params(
|
617
|
+
"abc" => "value",
|
618
|
+
"def" => "value",
|
619
|
+
"xyz" => "value"
|
492
620
|
)
|
493
621
|
end
|
494
|
-
end
|
495
|
-
|
496
|
-
describe "#set_params" do
|
497
|
-
let(:transaction) { new_transaction }
|
498
622
|
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
transaction.set_params(params)
|
623
|
+
it "adds the params to the transaction with a block" do
|
624
|
+
params = { "key" => "value" }
|
625
|
+
transaction.add_params { params }
|
503
626
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
end
|
627
|
+
transaction._sample
|
628
|
+
expect(transaction).to include_params(params)
|
629
|
+
end
|
508
630
|
|
509
|
-
|
510
|
-
|
511
|
-
|
631
|
+
it "adds the params block value when both an argument and block are given" do
|
632
|
+
arg_params = { "argument" => "value" }
|
633
|
+
block_params = { "block" => "value" }
|
634
|
+
transaction.add_params(arg_params) { block_params }
|
512
635
|
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
end
|
636
|
+
transaction._sample
|
637
|
+
expect(transaction).to include_params(block_params)
|
638
|
+
end
|
517
639
|
|
518
|
-
|
519
|
-
|
520
|
-
block_params = { "block" => "value" }
|
521
|
-
transaction.set_params(arg_params) { block_params }
|
640
|
+
it "logs an error if an error occurred storing the params" do
|
641
|
+
transaction.add_params { raise "uh oh" }
|
522
642
|
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
643
|
+
logs = capture_logs { transaction._sample }
|
644
|
+
expect(logs).to contains_log(
|
645
|
+
:error,
|
646
|
+
"Exception while fetching params: RuntimeError: uh oh"
|
647
|
+
)
|
648
|
+
end
|
527
649
|
|
528
|
-
|
529
|
-
|
650
|
+
it "does not update the params on the transaction if the given value is nil" do
|
651
|
+
params = { "key" => "value" }
|
652
|
+
transaction.add_params(params)
|
653
|
+
transaction.add_params(nil)
|
530
654
|
|
531
|
-
|
532
|
-
|
533
|
-
:error,
|
534
|
-
"Exception while fetching params: RuntimeError: uh oh"
|
535
|
-
)
|
536
|
-
end
|
655
|
+
transaction._sample
|
656
|
+
expect(transaction).to include_params(params)
|
537
657
|
end
|
538
658
|
|
539
|
-
context "
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
transaction.
|
659
|
+
context "with AppSignal filtering" do
|
660
|
+
let(:options) { { :filter_parameters => %w[foo] } }
|
661
|
+
|
662
|
+
it "returns sanitized custom params" do
|
663
|
+
transaction.add_params("foo" => "value", "baz" => "bat")
|
544
664
|
|
545
665
|
transaction._sample
|
546
|
-
expect(transaction
|
547
|
-
expect(transaction).to include_params(params)
|
666
|
+
expect(transaction).to include_params("foo" => "[FILTERED]", "baz" => "bat")
|
548
667
|
end
|
549
668
|
end
|
550
669
|
end
|
551
670
|
|
552
|
-
describe "#
|
671
|
+
describe "#add_params_if_nil" do
|
553
672
|
let(:transaction) { new_transaction }
|
554
673
|
|
674
|
+
it "has a #set_params_if_nil alias" do
|
675
|
+
expect(transaction.method(:add_params_if_nil)).to eq(transaction.method(:set_params_if_nil))
|
676
|
+
end
|
677
|
+
|
555
678
|
context "when the params are not set" do
|
556
|
-
it "
|
679
|
+
it "adds the params to the transaction" do
|
557
680
|
params = { "key" => "value" }
|
558
|
-
transaction.
|
681
|
+
transaction.add_params_if_nil(params)
|
559
682
|
|
560
683
|
transaction._sample
|
561
|
-
expect(transaction.params).to eq(params)
|
562
684
|
expect(transaction).to include_params(params)
|
563
685
|
end
|
564
686
|
|
565
|
-
it "
|
687
|
+
it "adds the params to the transaction with a block" do
|
566
688
|
params = { "key" => "value" }
|
567
|
-
transaction.
|
689
|
+
transaction.add_params_if_nil { params }
|
568
690
|
|
569
691
|
transaction._sample
|
570
|
-
expect(transaction.params).to eq(params)
|
571
692
|
expect(transaction).to include_params(params)
|
572
693
|
end
|
573
694
|
|
574
|
-
it "
|
695
|
+
it "adds the params block value when both an argument and block are given" do
|
575
696
|
arg_params = { "argument" => "value" }
|
576
697
|
block_params = { "block" => "value" }
|
577
|
-
transaction.
|
698
|
+
transaction.add_params_if_nil(arg_params) { block_params }
|
578
699
|
|
579
700
|
transaction._sample
|
580
|
-
expect(transaction
|
581
|
-
expect(transaction).to include_params(arg_params)
|
701
|
+
expect(transaction).to include_params(block_params)
|
582
702
|
end
|
583
703
|
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
transaction.set_params_if_nil(nil)
|
704
|
+
it "does not update the params on the transaction if the given value is nil" do
|
705
|
+
params = { "key" => "value" }
|
706
|
+
transaction.add_params(params)
|
707
|
+
transaction.add_params_if_nil(nil)
|
589
708
|
|
590
|
-
|
591
|
-
|
592
|
-
expect(transaction).to include_params(params)
|
593
|
-
end
|
709
|
+
transaction._sample
|
710
|
+
expect(transaction).to include_params(params)
|
594
711
|
end
|
595
712
|
end
|
596
713
|
|
@@ -598,144 +715,156 @@ describe Appsignal::Transaction do
|
|
598
715
|
it "does not update the params on the transaction" do
|
599
716
|
preset_params = { "other" => "params" }
|
600
717
|
params = { "key" => "value" }
|
601
|
-
transaction.
|
602
|
-
transaction.
|
718
|
+
transaction.add_params(preset_params)
|
719
|
+
transaction.add_params_if_nil(params)
|
603
720
|
|
604
721
|
transaction._sample
|
605
|
-
expect(transaction.params).to eq(preset_params)
|
606
722
|
expect(transaction).to include_params(preset_params)
|
607
723
|
end
|
608
724
|
|
609
725
|
it "does not update the params with a block on the transaction" do
|
610
726
|
preset_params = { "other" => "params" }
|
611
727
|
params = { "key" => "value" }
|
612
|
-
transaction.
|
613
|
-
transaction.
|
728
|
+
transaction.add_params(preset_params)
|
729
|
+
transaction.add_params_if_nil { params }
|
614
730
|
|
615
731
|
transaction._sample
|
616
|
-
expect(transaction.params).to eq(preset_params)
|
617
732
|
expect(transaction).to include_params(preset_params)
|
618
733
|
end
|
619
734
|
end
|
620
735
|
end
|
621
736
|
|
622
|
-
describe "#
|
737
|
+
describe "#add_session_data" do
|
623
738
|
let(:transaction) { new_transaction }
|
624
739
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
transaction.set_session_data(data)
|
740
|
+
it "has a #set_session_data alias" do
|
741
|
+
expect(transaction.method(:add_session_data)).to eq(transaction.method(:set_session_data))
|
742
|
+
end
|
629
743
|
|
630
|
-
|
631
|
-
|
632
|
-
|
744
|
+
it "adds the session data to the transaction" do
|
745
|
+
data = { "key" => "value" }
|
746
|
+
transaction.add_session_data(data)
|
633
747
|
|
634
|
-
|
635
|
-
|
636
|
-
|
748
|
+
transaction._sample
|
749
|
+
expect(transaction).to include_session_data(data)
|
750
|
+
end
|
637
751
|
|
638
|
-
|
639
|
-
|
640
|
-
|
752
|
+
it "merges the session data on the transaction" do
|
753
|
+
transaction.add_session_data("abc" => "value")
|
754
|
+
transaction.add_session_data("def" => "value")
|
755
|
+
transaction.add_session_data { { "xyz" => "value" } }
|
641
756
|
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
757
|
+
transaction._sample
|
758
|
+
expect(transaction).to include_session_data(
|
759
|
+
"abc" => "value",
|
760
|
+
"def" => "value",
|
761
|
+
"xyz" => "value"
|
762
|
+
)
|
763
|
+
end
|
646
764
|
|
647
|
-
|
648
|
-
|
649
|
-
|
765
|
+
it "adds the session data to the transaction with a block" do
|
766
|
+
data = { "key" => "value" }
|
767
|
+
transaction.add_session_data { data }
|
650
768
|
|
651
|
-
|
652
|
-
|
653
|
-
|
769
|
+
transaction._sample
|
770
|
+
expect(transaction).to include_session_data(data)
|
771
|
+
end
|
654
772
|
|
655
|
-
|
656
|
-
|
657
|
-
|
773
|
+
it "adds the session data block value when both an argument and block are given" do
|
774
|
+
arg_data = { "argument" => "value" }
|
775
|
+
block_data = { "block" => "value" }
|
776
|
+
transaction.add_session_data(arg_data) { block_data }
|
658
777
|
|
659
|
-
|
660
|
-
|
778
|
+
transaction._sample
|
779
|
+
expect(transaction).to include_session_data(block_data)
|
780
|
+
end
|
661
781
|
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
782
|
+
it "logs an error if an error occurred storing the session data" do
|
783
|
+
transaction.add_session_data { raise "uh oh" }
|
784
|
+
|
785
|
+
logs = capture_logs { transaction._sample }
|
786
|
+
expect(logs).to contains_log(
|
787
|
+
:error,
|
788
|
+
"Exception while fetching session data: RuntimeError: uh oh"
|
789
|
+
)
|
668
790
|
end
|
669
791
|
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
792
|
+
it "does not update the session data on the transaction if the given value is nil" do
|
793
|
+
data = { "key" => "value" }
|
794
|
+
transaction.add_session_data(data)
|
795
|
+
transaction.add_session_data(nil)
|
796
|
+
|
797
|
+
transaction._sample
|
798
|
+
expect(transaction).to include_session_data(data)
|
799
|
+
end
|
800
|
+
|
801
|
+
context "with filter_session_data" do
|
802
|
+
let(:options) { { :filter_session_data => ["filtered_key"] } }
|
803
|
+
|
804
|
+
it "does not include filtered out session data" do
|
805
|
+
transaction.add_session_data("data" => "value1", "filtered_key" => "filtered_value")
|
675
806
|
|
676
807
|
transaction._sample
|
677
|
-
expect(transaction).to include_session_data(data)
|
808
|
+
expect(transaction).to include_session_data("data" => "value1")
|
678
809
|
end
|
679
810
|
end
|
680
811
|
end
|
681
812
|
|
682
|
-
describe "#
|
813
|
+
describe "#add_session_data_if_nil" do
|
683
814
|
let(:transaction) { new_transaction }
|
684
815
|
|
685
|
-
context "when the
|
686
|
-
it "sets the
|
816
|
+
context "when the session data is not set" do
|
817
|
+
it "sets the session data on the transaction" do
|
687
818
|
data = { "key" => "value" }
|
688
|
-
transaction.
|
819
|
+
transaction.add_session_data_if_nil(data)
|
689
820
|
|
690
821
|
transaction._sample
|
691
822
|
expect(transaction).to include_session_data(data)
|
692
823
|
end
|
693
824
|
|
694
|
-
it "updates the
|
825
|
+
it "updates the session data on the transaction with a block" do
|
695
826
|
data = { "key" => "value" }
|
696
|
-
transaction.
|
827
|
+
transaction.add_session_data_if_nil { data }
|
697
828
|
|
698
829
|
transaction._sample
|
699
830
|
expect(transaction).to include_session_data(data)
|
700
831
|
end
|
701
832
|
|
702
|
-
it "updates with the
|
833
|
+
it "updates with the session data block when both an argument and block are given" do
|
703
834
|
arg_data = { "argument" => "value" }
|
704
835
|
block_data = { "block" => "value" }
|
705
|
-
transaction.
|
836
|
+
transaction.add_session_data_if_nil(arg_data) { block_data }
|
706
837
|
|
707
838
|
transaction._sample
|
708
|
-
expect(transaction).to include_session_data(
|
839
|
+
expect(transaction).to include_session_data(block_data)
|
709
840
|
end
|
710
841
|
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
transaction.set_session_data_if_nil(nil)
|
842
|
+
it "does not update the session data on the transaction if the given value is nil" do
|
843
|
+
data = { "key" => "value" }
|
844
|
+
transaction.add_session_data(data)
|
845
|
+
transaction.add_session_data_if_nil(nil)
|
716
846
|
|
717
|
-
|
718
|
-
|
719
|
-
end
|
847
|
+
transaction._sample
|
848
|
+
expect(transaction).to include_session_data(data)
|
720
849
|
end
|
721
850
|
end
|
722
851
|
|
723
|
-
context "when the
|
724
|
-
it "does not update the
|
852
|
+
context "when the session data are set" do
|
853
|
+
it "does not update the session data on the transaction" do
|
725
854
|
preset_data = { "other" => "data" }
|
726
855
|
data = { "key" => "value" }
|
727
|
-
transaction.
|
728
|
-
transaction.
|
856
|
+
transaction.add_session_data(preset_data)
|
857
|
+
transaction.add_session_data_if_nil(data)
|
729
858
|
|
730
859
|
transaction._sample
|
731
860
|
expect(transaction).to include_session_data(preset_data)
|
732
861
|
end
|
733
862
|
|
734
|
-
it "does not update the
|
863
|
+
it "does not update the session data with a block on the transaction" do
|
735
864
|
preset_data = { "other" => "data" }
|
736
865
|
data = { "key" => "value" }
|
737
|
-
transaction.
|
738
|
-
transaction.
|
866
|
+
transaction.add_session_data(preset_data)
|
867
|
+
transaction.add_session_data_if_nil { data }
|
739
868
|
|
740
869
|
transaction._sample
|
741
870
|
expect(transaction).to include_session_data(preset_data)
|
@@ -743,123 +872,141 @@ describe Appsignal::Transaction do
|
|
743
872
|
end
|
744
873
|
end
|
745
874
|
|
746
|
-
describe "#
|
875
|
+
describe "#add_headers" do
|
747
876
|
let(:transaction) { new_transaction }
|
748
877
|
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
transaction.set_headers(headers)
|
878
|
+
it "has a #set_headers alias" do
|
879
|
+
expect(transaction.method(:add_headers)).to eq(transaction.method(:set_headers))
|
880
|
+
end
|
753
881
|
|
754
|
-
|
755
|
-
|
756
|
-
|
882
|
+
it "adds the headers to the transaction" do
|
883
|
+
headers = { "PATH_INFO" => "value" }
|
884
|
+
transaction.add_headers(headers)
|
757
885
|
|
758
|
-
|
759
|
-
|
760
|
-
|
886
|
+
transaction._sample
|
887
|
+
expect(transaction).to include_environment(headers)
|
888
|
+
end
|
761
889
|
|
762
|
-
|
763
|
-
|
764
|
-
|
890
|
+
it "merges the headers on the transaction" do
|
891
|
+
transaction.add_headers("PATH_INFO" => "value")
|
892
|
+
transaction.add_headers("REQUEST_METHOD" => "value")
|
893
|
+
transaction.add_headers { { "HTTP_ACCEPT" => "value" } }
|
765
894
|
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
895
|
+
transaction._sample
|
896
|
+
expect(transaction).to include_environment(
|
897
|
+
"PATH_INFO" => "value",
|
898
|
+
"REQUEST_METHOD" => "value",
|
899
|
+
"HTTP_ACCEPT" => "value"
|
900
|
+
)
|
901
|
+
end
|
770
902
|
|
771
|
-
|
772
|
-
|
773
|
-
|
903
|
+
it "adds the headers to the transaction with a block" do
|
904
|
+
headers = { "PATH_INFO" => "value" }
|
905
|
+
transaction.add_headers { headers }
|
774
906
|
|
775
|
-
|
776
|
-
|
777
|
-
|
907
|
+
transaction._sample
|
908
|
+
expect(transaction).to include_environment(headers)
|
909
|
+
end
|
778
910
|
|
779
|
-
|
780
|
-
|
781
|
-
|
911
|
+
it "adds the headers block value when both an argument and block are given" do
|
912
|
+
arg_data = { "PATH_INFO" => "/arg-path" }
|
913
|
+
block_data = { "PATH_INFO" => "/block-path" }
|
914
|
+
transaction.add_headers(arg_data) { block_data }
|
915
|
+
|
916
|
+
transaction._sample
|
917
|
+
expect(transaction).to include_environment(block_data)
|
918
|
+
end
|
782
919
|
|
783
|
-
|
784
|
-
|
920
|
+
it "logs an error if an error occurred storing the headers" do
|
921
|
+
transaction.add_headers { raise "uh oh" }
|
785
922
|
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
end
|
923
|
+
logs = capture_logs { transaction._sample }
|
924
|
+
expect(logs).to contains_log(
|
925
|
+
:error,
|
926
|
+
"Exception while fetching headers: RuntimeError: uh oh"
|
927
|
+
)
|
792
928
|
end
|
793
929
|
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
930
|
+
it "does not update the headers on the transaction if the given value is nil" do
|
931
|
+
headers = { "PATH_INFO" => "value" }
|
932
|
+
transaction.add_headers(headers)
|
933
|
+
transaction.add_headers(nil)
|
934
|
+
|
935
|
+
transaction._sample
|
936
|
+
expect(transaction).to include_environment(headers)
|
937
|
+
end
|
938
|
+
|
939
|
+
context "with request_headers options" do
|
940
|
+
let(:options) { { :request_headers => ["MY_HEADER"] } }
|
941
|
+
|
942
|
+
it "does not include filtered out headers" do
|
943
|
+
transaction.add_headers("MY_HEADER" => "value1", "filtered_key" => "filtered_value")
|
799
944
|
|
800
945
|
transaction._sample
|
801
|
-
expect(transaction).to include_environment(
|
946
|
+
expect(transaction).to include_environment("MY_HEADER" => "value1")
|
802
947
|
end
|
803
948
|
end
|
804
949
|
end
|
805
950
|
|
806
|
-
describe "#
|
951
|
+
describe "#add_headers_if_nil" do
|
807
952
|
let(:transaction) { new_transaction }
|
808
953
|
|
809
|
-
|
810
|
-
|
954
|
+
it "has a #set_headers_if_nil alias" do
|
955
|
+
expect(transaction.method(:add_headers_if_nil)).to eq(transaction.method(:set_headers_if_nil))
|
956
|
+
end
|
957
|
+
|
958
|
+
context "when the headers are not set" do
|
959
|
+
it "adds the headers to the transaction" do
|
811
960
|
headers = { "PATH_INFO" => "value" }
|
812
|
-
transaction.
|
961
|
+
transaction.add_headers_if_nil(headers)
|
813
962
|
|
814
963
|
transaction._sample
|
815
964
|
expect(transaction).to include_environment(headers)
|
816
965
|
end
|
817
966
|
|
818
|
-
it "
|
967
|
+
it "adds the headers to the transaction with a block" do
|
819
968
|
headers = { "PATH_INFO" => "value" }
|
820
|
-
transaction.
|
969
|
+
transaction.add_headers_if_nil { headers }
|
821
970
|
|
822
971
|
transaction._sample
|
823
972
|
expect(transaction).to include_environment(headers)
|
824
973
|
end
|
825
974
|
|
826
|
-
it "
|
975
|
+
it "adds the headers block value when both an argument and block are given" do
|
827
976
|
arg_data = { "PATH_INFO" => "/arg-path" }
|
828
977
|
block_data = { "PATH_INFO" => "/block-path" }
|
829
|
-
transaction.
|
978
|
+
transaction.add_headers_if_nil(arg_data) { block_data }
|
830
979
|
|
831
980
|
transaction._sample
|
832
|
-
expect(transaction).to include_environment(
|
981
|
+
expect(transaction).to include_environment(block_data)
|
833
982
|
end
|
834
983
|
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
transaction.set_headers_if_nil(nil)
|
984
|
+
it "does not update the headers on the transaction if the given value is nil" do
|
985
|
+
headers = { "PATH_INFO" => "value" }
|
986
|
+
transaction.add_headers(headers)
|
987
|
+
transaction.add_headers_if_nil(nil)
|
840
988
|
|
841
|
-
|
842
|
-
|
843
|
-
end
|
989
|
+
transaction._sample
|
990
|
+
expect(transaction).to include_environment(headers)
|
844
991
|
end
|
845
992
|
end
|
846
993
|
|
847
|
-
context "when the
|
848
|
-
it "does not update the
|
994
|
+
context "when the headers are set" do
|
995
|
+
it "does not update the headers on the transaction" do
|
849
996
|
preset_headers = { "PATH_INFO" => "/first-path" }
|
850
997
|
headers = { "PATH_INFO" => "/other-path" }
|
851
|
-
transaction.
|
852
|
-
transaction.
|
998
|
+
transaction.add_headers(preset_headers)
|
999
|
+
transaction.add_headers_if_nil(headers)
|
853
1000
|
|
854
1001
|
transaction._sample
|
855
1002
|
expect(transaction).to include_environment(preset_headers)
|
856
1003
|
end
|
857
1004
|
|
858
|
-
it "does not update the
|
1005
|
+
it "does not update the headers with a block on the transaction" do
|
859
1006
|
preset_headers = { "PATH_INFO" => "/first-path" }
|
860
1007
|
headers = { "PATH_INFO" => "/other-path" }
|
861
|
-
transaction.
|
862
|
-
transaction.
|
1008
|
+
transaction.add_headers(preset_headers)
|
1009
|
+
transaction.add_headers_if_nil { headers }
|
863
1010
|
|
864
1011
|
transaction._sample
|
865
1012
|
expect(transaction).to include_environment(preset_headers)
|
@@ -867,12 +1014,12 @@ describe Appsignal::Transaction do
|
|
867
1014
|
end
|
868
1015
|
end
|
869
1016
|
|
870
|
-
describe "#
|
1017
|
+
describe "#add_tags" do
|
871
1018
|
let(:transaction) { new_transaction }
|
872
1019
|
let(:long_string) { "a" * 10_001 }
|
873
1020
|
|
874
1021
|
it "stores tags on the transaction" do
|
875
|
-
transaction.
|
1022
|
+
transaction.add_tags(
|
876
1023
|
:valid_key => "valid_value",
|
877
1024
|
"valid_string_key" => "valid_value",
|
878
1025
|
:both_symbols => :valid_value,
|
@@ -900,8 +1047,8 @@ describe Appsignal::Transaction do
|
|
900
1047
|
end
|
901
1048
|
|
902
1049
|
it "merges the tags when called multiple times" do
|
903
|
-
transaction.
|
904
|
-
transaction.
|
1050
|
+
transaction.add_tags(:key1 => "value1")
|
1051
|
+
transaction.add_tags(:key2 => "value2")
|
905
1052
|
transaction._sample
|
906
1053
|
|
907
1054
|
expect(transaction).to include_tags(
|
@@ -911,11 +1058,15 @@ describe Appsignal::Transaction do
|
|
911
1058
|
end
|
912
1059
|
end
|
913
1060
|
|
914
|
-
describe "#
|
1061
|
+
describe "#add_custom_data" do
|
915
1062
|
let(:transaction) { new_transaction }
|
916
1063
|
|
917
|
-
it "
|
918
|
-
transaction.set_custom_data
|
1064
|
+
it "has a #add_custom_data alias" do
|
1065
|
+
expect(transaction.method(:add_custom_data)).to eq(transaction.method(:set_custom_data))
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
it "adds a custom Hash data to the transaction" do
|
1069
|
+
transaction.add_custom_data(
|
919
1070
|
:user => {
|
920
1071
|
:id => 123,
|
921
1072
|
:locale => "abc"
|
@@ -939,8 +1090,8 @@ describe Appsignal::Transaction do
|
|
939
1090
|
)
|
940
1091
|
end
|
941
1092
|
|
942
|
-
it "
|
943
|
-
transaction.
|
1093
|
+
it "adds a custom Array data to the transaction" do
|
1094
|
+
transaction.add_custom_data([
|
944
1095
|
[123, "abc"],
|
945
1096
|
["appsignal", "enterprise"]
|
946
1097
|
])
|
@@ -955,39 +1106,42 @@ describe Appsignal::Transaction do
|
|
955
1106
|
it "does not store non Hash or Array custom data" do
|
956
1107
|
logs =
|
957
1108
|
capture_logs do
|
958
|
-
transaction.
|
1109
|
+
transaction.add_custom_data("abc")
|
959
1110
|
transaction._sample
|
960
1111
|
expect(transaction).to_not include_custom_data
|
961
1112
|
|
962
|
-
transaction.
|
1113
|
+
transaction.add_custom_data(123)
|
963
1114
|
transaction._sample
|
964
1115
|
expect(transaction).to_not include_custom_data
|
965
1116
|
|
966
|
-
transaction.
|
1117
|
+
transaction.add_custom_data(Object.new)
|
967
1118
|
transaction._sample
|
968
1119
|
expect(transaction).to_not include_custom_data
|
969
1120
|
end
|
970
1121
|
|
971
1122
|
expect(logs).to contains_log(
|
972
1123
|
:error,
|
973
|
-
|
1124
|
+
%(Sample data 'custom_data': Unsupported data type 'String' received: "abc")
|
974
1125
|
)
|
975
1126
|
expect(logs).to contains_log(
|
976
1127
|
:error,
|
977
|
-
|
1128
|
+
%(Sample data 'custom_data': Unsupported data type 'Integer' received: 123)
|
978
1129
|
)
|
979
1130
|
expect(logs).to contains_log(
|
980
1131
|
:error,
|
981
|
-
|
1132
|
+
%(Sample data 'custom_data': Unsupported data type 'Object' received: #<Object:)
|
982
1133
|
)
|
983
1134
|
end
|
984
1135
|
|
985
|
-
it "
|
986
|
-
transaction.
|
987
|
-
transaction.
|
1136
|
+
it "merges the custom data if called multiple times" do
|
1137
|
+
transaction.add_custom_data("abc" => "value")
|
1138
|
+
transaction.add_custom_data("def" => "value")
|
988
1139
|
|
989
1140
|
transaction._sample
|
990
|
-
expect(transaction).to include_custom_data(
|
1141
|
+
expect(transaction).to include_custom_data(
|
1142
|
+
"abc" => "value",
|
1143
|
+
"def" => "value"
|
1144
|
+
)
|
991
1145
|
end
|
992
1146
|
end
|
993
1147
|
|
@@ -1150,42 +1304,6 @@ describe Appsignal::Transaction do
|
|
1150
1304
|
end
|
1151
1305
|
end
|
1152
1306
|
|
1153
|
-
describe "#set_http_or_background_action" do
|
1154
|
-
let(:transaction) { new_transaction }
|
1155
|
-
|
1156
|
-
context "for a hash with controller and action" do
|
1157
|
-
it "sets the action" do
|
1158
|
-
transaction.set_http_or_background_action(
|
1159
|
-
:controller => "HomeController",
|
1160
|
-
:action => "show"
|
1161
|
-
)
|
1162
|
-
expect(transaction).to have_action("HomeController#show")
|
1163
|
-
end
|
1164
|
-
end
|
1165
|
-
|
1166
|
-
context "for a hash with just action" do
|
1167
|
-
it "sets the action" do
|
1168
|
-
transaction.set_http_or_background_action(:action => "show")
|
1169
|
-
expect(transaction).to have_action("show")
|
1170
|
-
end
|
1171
|
-
end
|
1172
|
-
|
1173
|
-
context "for a hash with class and method" do
|
1174
|
-
it "sets the action" do
|
1175
|
-
transaction.set_http_or_background_action(:class => "Worker", :method => "perform")
|
1176
|
-
expect(transaction).to have_action("Worker#perform")
|
1177
|
-
end
|
1178
|
-
end
|
1179
|
-
|
1180
|
-
context "when action is already set" do
|
1181
|
-
it "does not overwrite the set action" do
|
1182
|
-
transaction.set_action("MyCustomAction#perform")
|
1183
|
-
transaction.set_http_or_background_action(:class => "Worker", :method => "perform")
|
1184
|
-
expect(transaction).to have_action("MyCustomAction#perform")
|
1185
|
-
end
|
1186
|
-
end
|
1187
|
-
end
|
1188
|
-
|
1189
1307
|
describe "#set_queue_start" do
|
1190
1308
|
let(:transaction) { new_transaction }
|
1191
1309
|
|
@@ -1210,75 +1328,6 @@ describe Appsignal::Transaction do
|
|
1210
1328
|
end
|
1211
1329
|
end
|
1212
1330
|
|
1213
|
-
describe "#set_http_or_background_queue_start" do
|
1214
|
-
let(:transaction) { legacy_new_transaction(:request => legacy_request(env)) }
|
1215
|
-
let(:err_stream) { std_stream }
|
1216
|
-
let(:stderr) { err_stream.read }
|
1217
|
-
let(:header_factor) { 1_000 }
|
1218
|
-
let(:env_queue_start) { fixed_time + 20 } # in seconds
|
1219
|
-
|
1220
|
-
def set_http_or_background_queue_start
|
1221
|
-
capture_std_streams(std_stream, err_stream) do
|
1222
|
-
transaction.set_http_or_background_queue_start
|
1223
|
-
end
|
1224
|
-
end
|
1225
|
-
|
1226
|
-
context "when a queue time is found in a request header" do
|
1227
|
-
let(:header_time) { ((fixed_time + 10) * header_factor).to_i } # in milliseconds
|
1228
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time}" } }
|
1229
|
-
|
1230
|
-
it "sets the http header value in milliseconds on the transaction" do
|
1231
|
-
set_http_or_background_queue_start
|
1232
|
-
|
1233
|
-
expect(transaction).to have_queue_start(1_389_783_610_000)
|
1234
|
-
end
|
1235
|
-
|
1236
|
-
it "logs a deprecation message" do
|
1237
|
-
logs = capture_logs { set_http_or_background_queue_start }
|
1238
|
-
|
1239
|
-
expect(logs).to contains_log(
|
1240
|
-
:warn,
|
1241
|
-
"The Appsignal::Transaction#set_http_or_background_queue_start " \
|
1242
|
-
"method has been deprecated."
|
1243
|
-
)
|
1244
|
-
end
|
1245
|
-
|
1246
|
-
it "prints a deprecation message" do
|
1247
|
-
set_http_or_background_queue_start
|
1248
|
-
|
1249
|
-
expect(stderr).to include(
|
1250
|
-
"The Appsignal::Transaction#set_http_or_background_queue_start " \
|
1251
|
-
"method has been deprecated."
|
1252
|
-
)
|
1253
|
-
end
|
1254
|
-
|
1255
|
-
context "when a :queue_start key is found in the transaction environment" do
|
1256
|
-
let(:env) do
|
1257
|
-
{
|
1258
|
-
"HTTP_X_REQUEST_START" => "t=#{header_time}",
|
1259
|
-
:queue_start => env_queue_start
|
1260
|
-
}
|
1261
|
-
end
|
1262
|
-
|
1263
|
-
it "sets the http header value in milliseconds on the transaction" do
|
1264
|
-
set_http_or_background_queue_start
|
1265
|
-
|
1266
|
-
expect(transaction).to have_queue_start(1_389_783_610_000)
|
1267
|
-
end
|
1268
|
-
end
|
1269
|
-
end
|
1270
|
-
|
1271
|
-
context "when a :queue_start key is found in the transaction environment" do
|
1272
|
-
let(:env) { { :queue_start => env_queue_start } } # in seconds
|
1273
|
-
|
1274
|
-
it "sets the :queue_start value in milliseconds on the transaction" do
|
1275
|
-
set_http_or_background_queue_start
|
1276
|
-
|
1277
|
-
expect(transaction).to have_queue_start(1_389_783_620_000)
|
1278
|
-
end
|
1279
|
-
end
|
1280
|
-
end
|
1281
|
-
|
1282
1331
|
describe "#set_metadata" do
|
1283
1332
|
let(:transaction) { new_transaction }
|
1284
1333
|
|
@@ -1289,8 +1338,7 @@ describe Appsignal::Transaction do
|
|
1289
1338
|
end
|
1290
1339
|
|
1291
1340
|
context "when filter_metadata includes metadata key" do
|
1292
|
-
|
1293
|
-
after { Appsignal.config[:filter_metadata] = [] }
|
1341
|
+
let(:options) { { :filter_metadata => ["filter_key"] } }
|
1294
1342
|
|
1295
1343
|
it "does not set the metadata on the transaction" do
|
1296
1344
|
transaction.set_metadata(:filter_key, "filtered value")
|
@@ -1363,14 +1411,22 @@ describe Appsignal::Transaction do
|
|
1363
1411
|
expect(transaction).to_not include_params
|
1364
1412
|
end
|
1365
1413
|
|
1366
|
-
expect(logs).to contains_log
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
expect(logs).to contains_log
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1414
|
+
expect(logs).to contains_log(
|
1415
|
+
:error,
|
1416
|
+
%(Sample data 'params': Unsupported data type 'String' received: "some string")
|
1417
|
+
)
|
1418
|
+
expect(logs).to contains_log(
|
1419
|
+
:error,
|
1420
|
+
%(Sample data 'params': Unsupported data type 'Integer' received: 123)
|
1421
|
+
)
|
1422
|
+
expect(logs).to contains_log(
|
1423
|
+
:error,
|
1424
|
+
%(Sample data 'params': Unsupported data type 'Class' received: #<Class)
|
1425
|
+
)
|
1426
|
+
expect(logs).to contains_log(
|
1427
|
+
:error,
|
1428
|
+
%(Sample data 'params': Unsupported data type 'Set' received: #<Set: {"some value"}>)
|
1429
|
+
)
|
1374
1430
|
end
|
1375
1431
|
|
1376
1432
|
it "does not store data that can't be converted to JSON" do
|
@@ -1400,7 +1456,8 @@ describe Appsignal::Transaction do
|
|
1400
1456
|
|
1401
1457
|
it "updates the sample data on the transaction" do
|
1402
1458
|
silence do
|
1403
|
-
transaction.
|
1459
|
+
transaction.send(
|
1460
|
+
:set_sample_data,
|
1404
1461
|
"params",
|
1405
1462
|
:controller => "blog_posts",
|
1406
1463
|
:action => "show",
|
@@ -1419,7 +1476,7 @@ describe Appsignal::Transaction do
|
|
1419
1476
|
it "does not update the sample data on the transaction" do
|
1420
1477
|
logs =
|
1421
1478
|
capture_logs do
|
1422
|
-
silence { transaction.set_sample_data
|
1479
|
+
silence { transaction.send(:set_sample_data, "params", "string") }
|
1423
1480
|
end
|
1424
1481
|
|
1425
1482
|
expect(transaction.to_h["sample_data"]).to eq({})
|
@@ -1437,7 +1494,7 @@ describe Appsignal::Transaction do
|
|
1437
1494
|
end
|
1438
1495
|
logs =
|
1439
1496
|
capture_logs do
|
1440
|
-
silence { transaction.set_sample_data
|
1497
|
+
silence { transaction.send(:set_sample_data, "params", klass.new => 1) }
|
1441
1498
|
end
|
1442
1499
|
|
1443
1500
|
expect(transaction).to_not include_params
|
@@ -1447,91 +1504,202 @@ describe Appsignal::Transaction do
|
|
1447
1504
|
end
|
1448
1505
|
end
|
1449
1506
|
|
1450
|
-
describe "#
|
1451
|
-
let(:transaction) {
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
"SERVER_PORT" => "80",
|
1458
|
-
"PATH_INFO" => "/blog",
|
1459
|
-
"rack.session" => { "session" => "value" },
|
1460
|
-
:params => {
|
1461
|
-
"controller" => "blog_posts",
|
1462
|
-
"action" => "show",
|
1463
|
-
"id" => "1"
|
1464
|
-
}
|
1465
|
-
).merge(
|
1466
|
-
:metadata => { "metadata" => "value" }
|
1467
|
-
)
|
1507
|
+
describe "#add_error" do
|
1508
|
+
let(:transaction) { create_transaction }
|
1509
|
+
|
1510
|
+
let(:error) do
|
1511
|
+
e = ExampleStandardError.new("test message")
|
1512
|
+
allow(e).to receive(:backtrace).and_return(["line 1"])
|
1513
|
+
e
|
1468
1514
|
end
|
1469
1515
|
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1516
|
+
context "when error argument is not an error" do
|
1517
|
+
let(:error) { Object.new }
|
1518
|
+
|
1519
|
+
it "does not add the error" do
|
1520
|
+
logs = capture_logs { transaction.add_error(error) }
|
1474
1521
|
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
expect(transaction).to include_params(
|
1483
|
-
"controller" => "blog_posts",
|
1484
|
-
"action" => "show",
|
1485
|
-
"id" => "1"
|
1486
|
-
)
|
1487
|
-
expect(transaction).to include_sample_metadata("metadata" => "value")
|
1488
|
-
expect(transaction).to include_tags("tag" => "value")
|
1489
|
-
expect(transaction).to include_breadcrumb(
|
1490
|
-
"action",
|
1491
|
-
"category",
|
1492
|
-
"message",
|
1493
|
-
{ "key" => "value" },
|
1494
|
-
kind_of(Integer)
|
1495
|
-
)
|
1522
|
+
expect(transaction).to_not have_error
|
1523
|
+
expect(logs).to contains_log(
|
1524
|
+
:error,
|
1525
|
+
"Appsignal::Transaction#add_error: Cannot add error. " \
|
1526
|
+
"The given value is not an exception: #{error.inspect}"
|
1527
|
+
)
|
1528
|
+
end
|
1496
1529
|
end
|
1497
|
-
end
|
1498
1530
|
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
let(:error) { ExampleStandardError.new("test message") }
|
1531
|
+
context "when AppSignal is not active" do
|
1532
|
+
it "does not add the error" do
|
1533
|
+
allow(Appsignal).to receive(:active?).and_return(false)
|
1503
1534
|
|
1504
|
-
|
1505
|
-
|
1535
|
+
transaction.add_error(error)
|
1536
|
+
|
1537
|
+
expect(transaction).to_not have_error
|
1538
|
+
end
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
context "when a block is given" do
|
1542
|
+
it "stores the block in the error blocks" do
|
1543
|
+
block = proc { "block" }
|
1544
|
+
|
1545
|
+
transaction.add_error(error, &block)
|
1546
|
+
|
1547
|
+
expect(transaction.error_blocks).to eq({
|
1548
|
+
error => [block]
|
1549
|
+
})
|
1550
|
+
end
|
1506
1551
|
end
|
1507
1552
|
|
1508
|
-
|
1509
|
-
|
1553
|
+
context "when no error is set in the transaction" do
|
1554
|
+
it "sets the error on the transaction" do
|
1555
|
+
transaction.add_error(error)
|
1556
|
+
|
1557
|
+
expect(transaction).to have_error(
|
1558
|
+
"ExampleStandardError",
|
1559
|
+
"test message",
|
1560
|
+
["line 1"]
|
1561
|
+
)
|
1562
|
+
end
|
1510
1563
|
|
1511
|
-
|
1564
|
+
it "does store the error in the errors" do
|
1565
|
+
transaction.add_error(error)
|
1512
1566
|
|
1513
|
-
|
1567
|
+
expect(transaction.error_blocks).to eq({ error => [] })
|
1568
|
+
end
|
1514
1569
|
end
|
1515
1570
|
|
1516
|
-
context "when error
|
1517
|
-
let(:
|
1571
|
+
context "when an error is already set in the transaction" do
|
1572
|
+
let(:other_error) do
|
1573
|
+
e = ExampleStandardError.new("other test message")
|
1574
|
+
allow(e).to receive(:backtrace).and_return(["line 2"])
|
1575
|
+
e
|
1576
|
+
end
|
1518
1577
|
|
1519
|
-
|
1520
|
-
|
1578
|
+
before { transaction.set_error(other_error) }
|
1579
|
+
|
1580
|
+
it "stores an error in the errors" do
|
1581
|
+
transaction.add_error(error)
|
1582
|
+
|
1583
|
+
expect(transaction.error_blocks).to eq({
|
1584
|
+
other_error => [],
|
1585
|
+
error => []
|
1586
|
+
})
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
it "does not set the error on the extension" do
|
1590
|
+
transaction.add_error(error)
|
1591
|
+
|
1592
|
+
expect(transaction).to have_error(
|
1593
|
+
"ExampleStandardError",
|
1594
|
+
"other test message",
|
1595
|
+
["line 2"]
|
1596
|
+
)
|
1597
|
+
end
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
context "when the error has already been added" do
|
1601
|
+
before { transaction.add_error(error) }
|
1602
|
+
|
1603
|
+
it "does not add the error to the errors" do
|
1604
|
+
expect(transaction.error_blocks).to eq({ error => [] })
|
1605
|
+
|
1606
|
+
transaction.add_error(error)
|
1607
|
+
|
1608
|
+
expect(transaction.error_blocks).to eq({ error => [] })
|
1609
|
+
end
|
1610
|
+
|
1611
|
+
context "when a block is given" do
|
1612
|
+
it "adds the block to the error blocks" do
|
1613
|
+
block = proc { "block" }
|
1614
|
+
|
1615
|
+
transaction.add_error(error, &block)
|
1616
|
+
|
1617
|
+
expect(transaction.error_blocks).to eq({ error => [block] })
|
1618
|
+
end
|
1619
|
+
end
|
1620
|
+
end
|
1621
|
+
|
1622
|
+
context "when the errors is at the limit" do
|
1623
|
+
let(:seen_error) { ExampleStandardError.new("error 0") }
|
1624
|
+
|
1625
|
+
before do
|
1626
|
+
transaction.add_error(seen_error)
|
1627
|
+
|
1628
|
+
9.times do |i|
|
1629
|
+
transaction.add_error(ExampleStandardError.new("error #{i}"))
|
1630
|
+
end
|
1631
|
+
end
|
1632
|
+
|
1633
|
+
it "does not add a new error to the errors" do
|
1634
|
+
expect(transaction).to have_error("ExampleStandardError", "error 0", [])
|
1635
|
+
expect(transaction.error_blocks.length).to eq(10)
|
1636
|
+
expected_error_blocks = transaction.error_blocks.dup
|
1637
|
+
|
1638
|
+
transaction.add_error(error)
|
1639
|
+
|
1640
|
+
expect(transaction).to have_error("ExampleStandardError", "error 0", [])
|
1641
|
+
expect(transaction.error_blocks).to eq(expected_error_blocks)
|
1642
|
+
end
|
1643
|
+
|
1644
|
+
it "logs a debug message" do
|
1645
|
+
logs = capture_logs { transaction.add_error(error) }
|
1521
1646
|
|
1522
|
-
expect(transaction).to_not have_error
|
1523
1647
|
expect(logs).to contains_log(
|
1524
|
-
:
|
1525
|
-
"Appsignal::Transaction#
|
1526
|
-
"
|
1648
|
+
:warn,
|
1649
|
+
"Appsignal::Transaction#add_error: Transaction has more than 10 distinct errors. " \
|
1650
|
+
"Only the first 10 distinct errors will be reported."
|
1527
1651
|
)
|
1528
1652
|
end
|
1653
|
+
|
1654
|
+
context "when the error has already been added" do
|
1655
|
+
it "does not add the error to the errors" do
|
1656
|
+
expect(transaction.error_blocks.length).to eq(10)
|
1657
|
+
|
1658
|
+
transaction.add_error(seen_error)
|
1659
|
+
|
1660
|
+
expect(transaction.error_blocks.length).to eq(10)
|
1661
|
+
end
|
1662
|
+
|
1663
|
+
it "does add the block to the error blocks" do
|
1664
|
+
block = proc { "block" }
|
1665
|
+
|
1666
|
+
transaction.add_error(seen_error, &block)
|
1667
|
+
|
1668
|
+
expect(transaction.error_blocks[seen_error]).to eq([block])
|
1669
|
+
end
|
1670
|
+
|
1671
|
+
it "does not log a debug message" do
|
1672
|
+
logs = capture_logs { transaction.add_error(seen_error) }
|
1673
|
+
|
1674
|
+
expect(logs).to_not contains_log(
|
1675
|
+
:warn,
|
1676
|
+
"Appsignal::Transaction#add_error: Transaction has more than 10 distinct errors. " \
|
1677
|
+
"Only the first 10 distinct errors will be reported."
|
1678
|
+
)
|
1679
|
+
end
|
1680
|
+
end
|
1681
|
+
end
|
1682
|
+
end
|
1683
|
+
|
1684
|
+
describe "#_set_error" do
|
1685
|
+
let(:transaction) { new_transaction }
|
1686
|
+
let(:env) { http_request_env_with_data }
|
1687
|
+
let(:error) { ExampleStandardError.new("test message") }
|
1688
|
+
|
1689
|
+
it "responds to add_exception for backwards compatibility" do
|
1690
|
+
expect(transaction).to respond_to(:add_exception)
|
1691
|
+
end
|
1692
|
+
|
1693
|
+
it "does not add the error to the errors" do
|
1694
|
+
transaction.send(:_set_error, error)
|
1695
|
+
|
1696
|
+
expect(transaction.error_blocks).to be_empty
|
1529
1697
|
end
|
1530
1698
|
|
1531
1699
|
context "for a http request" do
|
1532
1700
|
it "sets an error on the transaction" do
|
1533
1701
|
allow(error).to receive(:backtrace).and_return(["line 1"])
|
1534
|
-
transaction.
|
1702
|
+
transaction.send(:_set_error, error)
|
1535
1703
|
|
1536
1704
|
expect(transaction).to have_error(
|
1537
1705
|
"ExampleStandardError",
|
@@ -1542,10 +1710,10 @@ describe Appsignal::Transaction do
|
|
1542
1710
|
end
|
1543
1711
|
|
1544
1712
|
context "when the error has no causes" do
|
1545
|
-
it "
|
1546
|
-
transaction.
|
1713
|
+
it "should set an empty causes array as sample data" do
|
1714
|
+
transaction.send(:_set_error, error)
|
1547
1715
|
|
1548
|
-
expect(transaction).
|
1716
|
+
expect(transaction).to include_error_causes([])
|
1549
1717
|
end
|
1550
1718
|
end
|
1551
1719
|
|
@@ -1560,8 +1728,12 @@ describe Appsignal::Transaction do
|
|
1560
1728
|
e
|
1561
1729
|
end
|
1562
1730
|
|
1731
|
+
let(:error_without_cause) do
|
1732
|
+
ExampleStandardError.new("error without cause")
|
1733
|
+
end
|
1734
|
+
|
1563
1735
|
it "sends the causes information as sample data" do
|
1564
|
-
transaction.
|
1736
|
+
transaction.send(:_set_error, error)
|
1565
1737
|
|
1566
1738
|
expect(transaction).to have_error(
|
1567
1739
|
"ExampleStandardError",
|
@@ -1581,6 +1753,19 @@ describe Appsignal::Transaction do
|
|
1581
1753
|
]
|
1582
1754
|
)
|
1583
1755
|
end
|
1756
|
+
|
1757
|
+
it "does not keep error causes from previously set errors" do
|
1758
|
+
transaction.send(:_set_error, error)
|
1759
|
+
transaction.send(:_set_error, error_without_cause)
|
1760
|
+
|
1761
|
+
expect(transaction).to have_error(
|
1762
|
+
"ExampleStandardError",
|
1763
|
+
"error without cause",
|
1764
|
+
[]
|
1765
|
+
)
|
1766
|
+
|
1767
|
+
expect(transaction).to include_error_causes([])
|
1768
|
+
end
|
1584
1769
|
end
|
1585
1770
|
|
1586
1771
|
context "when the error has too many causes" do
|
@@ -1607,7 +1792,7 @@ describe Appsignal::Transaction do
|
|
1607
1792
|
end
|
1608
1793
|
expected_error_causes.last["is_root_cause"] = false
|
1609
1794
|
|
1610
|
-
logs = capture_logs { transaction.
|
1795
|
+
logs = capture_logs { transaction.send(:_set_error, error) }
|
1611
1796
|
|
1612
1797
|
expect(transaction).to have_error(
|
1613
1798
|
"ExampleStandardError",
|
@@ -1617,7 +1802,7 @@ describe Appsignal::Transaction do
|
|
1617
1802
|
expect(transaction).to include_error_causes(expected_error_causes)
|
1618
1803
|
expect(logs).to contains_log(
|
1619
1804
|
:debug,
|
1620
|
-
"Appsignal::Transaction#
|
1805
|
+
"Appsignal::Transaction#add_error: Error has more " \
|
1621
1806
|
"than 10 error causes. Only the first 10 " \
|
1622
1807
|
"will be reported."
|
1623
1808
|
)
|
@@ -1633,11 +1818,11 @@ describe Appsignal::Transaction do
|
|
1633
1818
|
end
|
1634
1819
|
|
1635
1820
|
it "does not raise an error" do
|
1636
|
-
transaction.
|
1821
|
+
transaction.send(:_set_error, error)
|
1637
1822
|
end
|
1638
1823
|
|
1639
1824
|
it "sets an error on the transaction without an error message" do
|
1640
|
-
transaction.
|
1825
|
+
transaction.send(:_set_error, error)
|
1641
1826
|
|
1642
1827
|
expect(transaction).to have_error(
|
1643
1828
|
"ExampleStandardError",
|
@@ -1780,433 +1965,8 @@ describe Appsignal::Transaction do
|
|
1780
1965
|
end
|
1781
1966
|
end
|
1782
1967
|
|
1783
|
-
context "GenericRequest" do
|
1784
|
-
let(:env) { {} }
|
1785
|
-
subject { Appsignal::Transaction::GenericRequest.new(env) }
|
1786
|
-
|
1787
|
-
it "prints a deprecation warning on use" do
|
1788
|
-
err_stream = std_stream
|
1789
|
-
capture_std_streams(std_stream, err_stream) { subject }
|
1790
|
-
|
1791
|
-
expect(err_stream.read).to include(
|
1792
|
-
"appsignal WARNING: The use of Appsignal::Transaction::GenericRequest is deprecated."
|
1793
|
-
)
|
1794
|
-
end
|
1795
|
-
|
1796
|
-
it "logs a deprecation warning on use" do
|
1797
|
-
logs = capture_logs { silence { subject } }
|
1798
|
-
|
1799
|
-
expect(logs).to contains_log(
|
1800
|
-
:warn,
|
1801
|
-
"The use of Appsignal::Transaction::GenericRequest is deprecated."
|
1802
|
-
)
|
1803
|
-
end
|
1804
|
-
|
1805
|
-
it "initializes with an empty env" do
|
1806
|
-
expect(subject.env).to be_empty
|
1807
|
-
end
|
1808
|
-
|
1809
|
-
context "when given an env" do
|
1810
|
-
let(:env) do
|
1811
|
-
{
|
1812
|
-
:params => { :id => 1 },
|
1813
|
-
:queue_start => 10
|
1814
|
-
}
|
1815
|
-
end
|
1816
|
-
|
1817
|
-
it "sets the given env" do
|
1818
|
-
expect(subject.env).to eq env
|
1819
|
-
end
|
1820
|
-
|
1821
|
-
it "sets the params present in the env" do
|
1822
|
-
expect(subject.params).to eq(:id => 1)
|
1823
|
-
end
|
1824
|
-
end
|
1825
|
-
end
|
1826
|
-
|
1827
1968
|
# private
|
1828
1969
|
|
1829
|
-
describe "#background_queue_start" do
|
1830
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
1831
|
-
let(:request) { rack_request(env) }
|
1832
|
-
let(:env) { {} }
|
1833
|
-
subject { transaction.send(:background_queue_start) }
|
1834
|
-
|
1835
|
-
context "when request is nil" do
|
1836
|
-
let(:request) { nil }
|
1837
|
-
|
1838
|
-
it { is_expected.to eq nil }
|
1839
|
-
end
|
1840
|
-
|
1841
|
-
context "when env is nil" do
|
1842
|
-
before { expect(request).to receive(:env).and_return(nil) }
|
1843
|
-
|
1844
|
-
it { is_expected.to eq nil }
|
1845
|
-
end
|
1846
|
-
|
1847
|
-
context "when queue start is nil" do
|
1848
|
-
it { is_expected.to eq nil }
|
1849
|
-
end
|
1850
|
-
|
1851
|
-
context "when queue start is set" do
|
1852
|
-
before do
|
1853
|
-
env[:queue_start] = fixed_time
|
1854
|
-
end
|
1855
|
-
|
1856
|
-
it { is_expected.to eq 1_389_783_600_000 }
|
1857
|
-
end
|
1858
|
-
end
|
1859
|
-
|
1860
|
-
describe "#http_queue_start" do
|
1861
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
1862
|
-
let(:request) { rack_request(env) }
|
1863
|
-
let(:env) { {} }
|
1864
|
-
let(:slightly_earlier_time) { fixed_time - 0.4 }
|
1865
|
-
let(:slightly_earlier_time_value) { (slightly_earlier_time * factor).to_i }
|
1866
|
-
subject { transaction.send(:http_queue_start) }
|
1867
|
-
|
1868
|
-
shared_examples "http queue start" do
|
1869
|
-
context "when request is nil" do
|
1870
|
-
let(:request) { nil }
|
1871
|
-
|
1872
|
-
it { is_expected.to be_nil }
|
1873
|
-
end
|
1874
|
-
|
1875
|
-
context "when env is nil" do
|
1876
|
-
before { expect(request).to receive(:env).and_return(nil) }
|
1877
|
-
|
1878
|
-
it { is_expected.to be_nil }
|
1879
|
-
end
|
1880
|
-
|
1881
|
-
context "with no relevant header set" do
|
1882
|
-
let(:env) { {} }
|
1883
|
-
|
1884
|
-
it { is_expected.to be_nil }
|
1885
|
-
end
|
1886
|
-
|
1887
|
-
context "with the HTTP_X_REQUEST_START header set" do
|
1888
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{slightly_earlier_time_value}" } }
|
1889
|
-
|
1890
|
-
it { is_expected.to eq 1_389_783_599_600 }
|
1891
|
-
|
1892
|
-
context "with unparsable content" do
|
1893
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "something" } }
|
1894
|
-
|
1895
|
-
it { is_expected.to be_nil }
|
1896
|
-
end
|
1897
|
-
|
1898
|
-
context "with unparsable content at the end" do
|
1899
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{slightly_earlier_time_value}aaaa" } }
|
1900
|
-
|
1901
|
-
it { is_expected.to eq 1_389_783_599_600 }
|
1902
|
-
end
|
1903
|
-
|
1904
|
-
context "with a really low number" do
|
1905
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "t=100" } }
|
1906
|
-
|
1907
|
-
it { is_expected.to be_nil }
|
1908
|
-
end
|
1909
|
-
|
1910
|
-
context "with the alternate HTTP_X_QUEUE_START header set" do
|
1911
|
-
let(:env) { { "HTTP_X_QUEUE_START" => "t=#{slightly_earlier_time_value}" } }
|
1912
|
-
|
1913
|
-
it { is_expected.to eq 1_389_783_599_600 }
|
1914
|
-
end
|
1915
|
-
end
|
1916
|
-
end
|
1917
|
-
|
1918
|
-
context "time in milliseconds" do
|
1919
|
-
let(:factor) { 1_000 }
|
1920
|
-
|
1921
|
-
it_should_behave_like "http queue start"
|
1922
|
-
end
|
1923
|
-
|
1924
|
-
context "time in microseconds" do
|
1925
|
-
let(:factor) { 1_000_000 }
|
1926
|
-
|
1927
|
-
it_should_behave_like "http queue start"
|
1928
|
-
end
|
1929
|
-
end
|
1930
|
-
|
1931
|
-
describe "#sanitized_params" do
|
1932
|
-
let(:transaction) { new_transaction }
|
1933
|
-
subject { transaction.send(:sanitized_params) }
|
1934
|
-
|
1935
|
-
context "with params" do
|
1936
|
-
before do
|
1937
|
-
transaction.set_params(:foo => "bar", :baz => :bat)
|
1938
|
-
end
|
1939
|
-
|
1940
|
-
it "returns params" do
|
1941
|
-
is_expected.to eq(:foo => "bar", :baz => :bat)
|
1942
|
-
end
|
1943
|
-
|
1944
|
-
context "with AppSignal filtering" do
|
1945
|
-
before { Appsignal.config.config_hash[:filter_parameters] = %w[foo] }
|
1946
|
-
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
1947
|
-
|
1948
|
-
it "returns sanitized custom params" do
|
1949
|
-
expect(subject).to eq(:foo => "[FILTERED]", :baz => :bat)
|
1950
|
-
end
|
1951
|
-
end
|
1952
|
-
end
|
1953
|
-
|
1954
|
-
context "params from request" do
|
1955
|
-
let(:transaction) { legacy_new_transaction(:request => request, :options => options) }
|
1956
|
-
let(:options) { {} }
|
1957
|
-
let(:request) { rack_request(env) }
|
1958
|
-
let(:env) { {} }
|
1959
|
-
|
1960
|
-
context "without request params" do
|
1961
|
-
before { allow(transaction.request).to receive(:params).and_return(nil) }
|
1962
|
-
|
1963
|
-
it { is_expected.to be_nil }
|
1964
|
-
end
|
1965
|
-
|
1966
|
-
context "when request params crashes" do
|
1967
|
-
before { expect(request).to receive(:params).and_raise(NoMethodError) }
|
1968
|
-
|
1969
|
-
it { is_expected.to be_nil }
|
1970
|
-
end
|
1971
|
-
|
1972
|
-
context "when request params method does not exist" do
|
1973
|
-
let(:options) { { :params_method => :nonsense } }
|
1974
|
-
|
1975
|
-
it { is_expected.to be_nil }
|
1976
|
-
end
|
1977
|
-
|
1978
|
-
context "when not sending params" do
|
1979
|
-
before { Appsignal.config.config_hash[:send_params] = false }
|
1980
|
-
after { Appsignal.config.config_hash[:send_params] = true }
|
1981
|
-
|
1982
|
-
it { is_expected.to be_nil }
|
1983
|
-
end
|
1984
|
-
|
1985
|
-
context "with an array" do
|
1986
|
-
let(:request) { legacy_request(:params => %w[arg1 arg2]) }
|
1987
|
-
|
1988
|
-
it { is_expected.to eq %w[arg1 arg2] }
|
1989
|
-
|
1990
|
-
context "with AppSignal filtering" do
|
1991
|
-
before { Appsignal.config.config_hash[:filter_parameters] = %w[foo] }
|
1992
|
-
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
1993
|
-
|
1994
|
-
it { is_expected.to eq %w[arg1 arg2] }
|
1995
|
-
end
|
1996
|
-
end
|
1997
|
-
|
1998
|
-
context "with env" do
|
1999
|
-
context "with sanitization" do
|
2000
|
-
let(:request) { legacy_request(:params => { :foo => :bar }) }
|
2001
|
-
|
2002
|
-
it "should call the params sanitizer" do
|
2003
|
-
expect(subject).to eq(:foo => :bar)
|
2004
|
-
end
|
2005
|
-
end
|
2006
|
-
|
2007
|
-
context "with AppSignal filtering" do
|
2008
|
-
let(:request) { legacy_request(:params => { :foo => :bar, :baz => :bat }) }
|
2009
|
-
before { Appsignal.config.config_hash[:filter_parameters] = %w[foo] }
|
2010
|
-
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
2011
|
-
|
2012
|
-
it "should call the params sanitizer with filtering" do
|
2013
|
-
expect(subject).to eq(:foo => "[FILTERED]", :baz => :bat)
|
2014
|
-
end
|
2015
|
-
end
|
2016
|
-
end
|
2017
|
-
end
|
2018
|
-
end
|
2019
|
-
|
2020
|
-
describe "#sanitized_environment" do
|
2021
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
2022
|
-
let(:request) { rack_request(env) }
|
2023
|
-
let(:env) { {} }
|
2024
|
-
let(:allowlisted_keys) { Appsignal.config[:request_headers] }
|
2025
|
-
subject { transaction.send(:sanitized_environment) }
|
2026
|
-
|
2027
|
-
context "when request is nil" do
|
2028
|
-
let(:request) { nil }
|
2029
|
-
|
2030
|
-
it { is_expected.to be_nil }
|
2031
|
-
end
|
2032
|
-
|
2033
|
-
context "when env is nil" do
|
2034
|
-
before { expect(request).to receive(:env).and_return(nil) }
|
2035
|
-
|
2036
|
-
it { is_expected.to be_nil }
|
2037
|
-
end
|
2038
|
-
|
2039
|
-
context "when env is present" do
|
2040
|
-
let(:env) do
|
2041
|
-
{}.tap do |hash|
|
2042
|
-
allowlisted_keys.each { |o| hash[o] = 1 } # use all allowlisted keys
|
2043
|
-
hash[allowlisted_keys] = nil # don't add if nil
|
2044
|
-
hash[:not_allowlisted] = "I will be sanitized"
|
2045
|
-
end
|
2046
|
-
end
|
2047
|
-
|
2048
|
-
it "only sets allowlisted keys" do
|
2049
|
-
expect(subject.keys).to match_array(allowlisted_keys)
|
2050
|
-
end
|
2051
|
-
|
2052
|
-
context "with configured request_headers" do
|
2053
|
-
before do
|
2054
|
-
Appsignal.config.config_hash[:request_headers] = %w[CONTENT_LENGTH]
|
2055
|
-
end
|
2056
|
-
|
2057
|
-
it "only sets allowlisted keys" do
|
2058
|
-
expect(subject.keys).to match_array(%w[CONTENT_LENGTH])
|
2059
|
-
end
|
2060
|
-
end
|
2061
|
-
end
|
2062
|
-
end
|
2063
|
-
|
2064
|
-
describe "#sanitized_session_data" do
|
2065
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
2066
|
-
let(:request) { rack_request(env) }
|
2067
|
-
let(:env) { {} }
|
2068
|
-
subject { transaction.send(:sanitized_session_data) }
|
2069
|
-
|
2070
|
-
context "when request is nil" do
|
2071
|
-
let(:request) { nil }
|
2072
|
-
|
2073
|
-
it { is_expected.to be_nil }
|
2074
|
-
end
|
2075
|
-
|
2076
|
-
context "when session is nil" do
|
2077
|
-
before { expect(transaction.request).to receive(:session).and_return(nil) }
|
2078
|
-
|
2079
|
-
it { is_expected.to be_nil }
|
2080
|
-
end
|
2081
|
-
|
2082
|
-
context "when session is empty" do
|
2083
|
-
before { expect(transaction.request).to receive(:session).and_return({}) }
|
2084
|
-
|
2085
|
-
it { is_expected.to eq({}) }
|
2086
|
-
end
|
2087
|
-
|
2088
|
-
context "when request class does not have a session method" do
|
2089
|
-
let(:request) { Appsignal::Transaction::GenericRequest.new({}) }
|
2090
|
-
|
2091
|
-
it { is_expected.to be_nil }
|
2092
|
-
end
|
2093
|
-
|
2094
|
-
context "with a session" do
|
2095
|
-
let(:session_data_filter) { [] }
|
2096
|
-
before { Appsignal.config[:filter_session_data] = session_data_filter }
|
2097
|
-
after { Appsignal.config[:filter_session_data] = [] }
|
2098
|
-
|
2099
|
-
context "with generic session object" do
|
2100
|
-
before do
|
2101
|
-
expect(transaction).to respond_to(:request)
|
2102
|
-
allow(transaction).to receive_message_chain(
|
2103
|
-
:request,
|
2104
|
-
:session => { :foo => :bar, :abc => :def }
|
2105
|
-
)
|
2106
|
-
allow(transaction).to receive_message_chain(:request, :fullpath => :bar)
|
2107
|
-
end
|
2108
|
-
|
2109
|
-
context "without session filtering" do
|
2110
|
-
it "keeps the session data intact" do
|
2111
|
-
expect(subject).to eq(:foo => :bar, :abc => :def)
|
2112
|
-
end
|
2113
|
-
end
|
2114
|
-
|
2115
|
-
context "with session filtering" do
|
2116
|
-
let(:session_data_filter) { %w[foo] }
|
2117
|
-
|
2118
|
-
it "filters the session data" do
|
2119
|
-
expect(subject).to eq(:foo => "[FILTERED]", :abc => :def)
|
2120
|
-
end
|
2121
|
-
end
|
2122
|
-
end
|
2123
|
-
|
2124
|
-
if defined? ActionDispatch::Request::Session
|
2125
|
-
context "with ActionDispatch::Request::Session" do
|
2126
|
-
let(:action_dispatch_session) do
|
2127
|
-
store = Class.new do
|
2128
|
-
def load_session(_env)
|
2129
|
-
[1, { :foo => :bar, :abc => :def }]
|
2130
|
-
end
|
2131
|
-
|
2132
|
-
def session_exists?(_env)
|
2133
|
-
true
|
2134
|
-
end
|
2135
|
-
end.new
|
2136
|
-
ActionDispatch::Request::Session.create(store,
|
2137
|
-
ActionDispatch::Request.new("rack.input" => StringIO.new), {})
|
2138
|
-
end
|
2139
|
-
before do
|
2140
|
-
expect(transaction).to respond_to(:request)
|
2141
|
-
allow(transaction).to receive_message_chain(
|
2142
|
-
:request,
|
2143
|
-
:session => action_dispatch_session
|
2144
|
-
)
|
2145
|
-
allow(transaction).to receive_message_chain(:request, :fullpath => :bar)
|
2146
|
-
end
|
2147
|
-
|
2148
|
-
context "without session filtering" do
|
2149
|
-
it "keeps the session data intact" do
|
2150
|
-
expect(subject).to eq("foo" => :bar, "abc" => :def)
|
2151
|
-
end
|
2152
|
-
end
|
2153
|
-
|
2154
|
-
context "with session filtering" do
|
2155
|
-
let(:session_data_filter) { %w[foo] }
|
2156
|
-
|
2157
|
-
it "filters the session data" do
|
2158
|
-
expect(subject).to eq("foo" => "[FILTERED]", "abc" => :def)
|
2159
|
-
end
|
2160
|
-
end
|
2161
|
-
end
|
2162
|
-
end
|
2163
|
-
|
2164
|
-
context "when not sending session data" do
|
2165
|
-
before { Appsignal.config[:send_session_data] = false }
|
2166
|
-
|
2167
|
-
it "does not set any session data on the transaction" do
|
2168
|
-
expect(subject).to be_nil
|
2169
|
-
end
|
2170
|
-
end
|
2171
|
-
end
|
2172
|
-
end
|
2173
|
-
|
2174
|
-
describe "#sanitized_metadata" do
|
2175
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
2176
|
-
let(:request) { rack_request(env) }
|
2177
|
-
let(:env) { {} }
|
2178
|
-
subject { transaction.send(:sanitized_metadata) }
|
2179
|
-
|
2180
|
-
context "when request is nil" do
|
2181
|
-
let(:request) { nil }
|
2182
|
-
|
2183
|
-
it { is_expected.to be_nil }
|
2184
|
-
end
|
2185
|
-
|
2186
|
-
context "when env is nil" do
|
2187
|
-
before { expect(request).to receive(:env).and_return(nil) }
|
2188
|
-
|
2189
|
-
it { is_expected.to be_nil }
|
2190
|
-
end
|
2191
|
-
|
2192
|
-
context "when env is present" do
|
2193
|
-
let(:env) { { :metadata => { "key" => "value" } } }
|
2194
|
-
|
2195
|
-
it do
|
2196
|
-
is_expected.to eq("key" => "value")
|
2197
|
-
end
|
2198
|
-
|
2199
|
-
context "with filter_metadata option set" do
|
2200
|
-
before { Appsignal.config[:filter_metadata] = ["key"] }
|
2201
|
-
after { Appsignal.config[:filter_metadata] = [] }
|
2202
|
-
|
2203
|
-
it "filters out keys listed in the filter_metadata option" do
|
2204
|
-
expect(subject.keys).to_not include("key")
|
2205
|
-
end
|
2206
|
-
end
|
2207
|
-
end
|
2208
|
-
end
|
2209
|
-
|
2210
1970
|
describe "#cleaned_backtrace" do
|
2211
1971
|
let(:transaction) { new_transaction }
|
2212
1972
|
subject { transaction.send(:cleaned_backtrace, ["line 1", "line 2"]) }
|
@@ -2313,13 +2073,13 @@ describe Appsignal::Transaction do
|
|
2313
2073
|
describe Appsignal::Transaction::NilTransaction do
|
2314
2074
|
subject { Appsignal::Transaction::NilTransaction.new }
|
2315
2075
|
|
2316
|
-
it "
|
2076
|
+
it "has method stubs" do
|
2317
2077
|
subject.complete
|
2318
2078
|
subject.pause!
|
2319
2079
|
subject.resume!
|
2320
2080
|
subject.paused?
|
2321
2081
|
subject.store(:key)
|
2322
|
-
subject.
|
2082
|
+
subject.add_tags(:tag => 1)
|
2323
2083
|
subject.set_action("action")
|
2324
2084
|
subject.set_http_or_background_action
|
2325
2085
|
subject.set_queue_start(1)
|