appsignal 3.9.2-java → 3.9.3-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 +3135 -0
- data/.rubocop.yml +28 -20
- data/.rubocop_todo.yml +7 -33
- data/CHANGELOG.md +38 -0
- data/Rakefile +79 -64
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +109 -179
- data/ext/base.rb +1 -1
- data/gemfiles/hanami-2.1.gemfile +7 -0
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +1 -1
- data/lib/appsignal/demo.rb +0 -1
- data/lib/appsignal/environment.rb +5 -1
- data/lib/appsignal/extension/jruby.rb +1 -1
- data/lib/appsignal/helpers/instrumentation.rb +1 -1
- data/lib/appsignal/integrations/grape.rb +19 -47
- data/lib/appsignal/integrations/hanami.rb +8 -7
- data/lib/appsignal/integrations/padrino.rb +46 -43
- data/lib/appsignal/integrations/railtie.rb +0 -3
- data/lib/appsignal/integrations/sinatra.rb +0 -1
- data/lib/appsignal/probes/gvl.rb +24 -2
- data/lib/appsignal/probes/sidekiq.rb +1 -1
- data/lib/appsignal/probes.rb +1 -1
- data/lib/appsignal/rack/abstract_middleware.rb +62 -28
- data/lib/appsignal/rack/event_handler.rb +12 -3
- data/lib/appsignal/rack/grape_middleware.rb +40 -0
- data/lib/appsignal/rack/hanami_middleware.rb +1 -11
- data/lib/appsignal/rack/rails_instrumentation.rb +14 -55
- data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
- data/lib/appsignal/utils.rb +1 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +34 -33
- data/spec/.rubocop.yml +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
- data/spec/lib/appsignal/cli/install_spec.rb +3 -3
- data/spec/lib/appsignal/config_spec.rb +7 -5
- data/spec/lib/appsignal/demo_spec.rb +38 -41
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
- data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
- data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
- data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
- data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
- data/spec/lib/appsignal/hooks/rake_spec.rb +9 -19
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
- data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
- data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
- data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
- data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
- data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
- data/spec/lib/appsignal/integrations/padrino_spec.rb +47 -70
- data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
- data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -1
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +28 -39
- data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
- data/spec/lib/appsignal/probes_spec.rb +7 -4
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +215 -106
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -12
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +68 -86
- data/spec/lib/appsignal/transaction_spec.rb +76 -90
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
- data/spec/lib/appsignal_spec.rb +363 -342
- data/spec/support/helpers/dependency_helper.rb +6 -1
- data/spec/support/helpers/std_streams_helper.rb +1 -1
- data/spec/support/helpers/transaction_helpers.rb +8 -0
- data/spec/support/matchers/transaction.rb +185 -0
- data/spec/support/mocks/dummy_app.rb +20 -0
- data/spec/support/shared_examples/instrument.rb +17 -12
- data/spec/support/testing.rb +18 -9
- metadata +15 -10
- data/.semaphore/semaphore.yml +0 -2347
- data/script/lint_git +0 -22
- data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
- data/spec/support/matchers/be_completed.rb +0 -5
- /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
data/spec/lib/appsignal_spec.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
describe Appsignal do
|
|
2
2
|
include EnvironmentMetadataHelper
|
|
3
|
+
around { |example| keep_transactions { example.run } }
|
|
3
4
|
|
|
4
5
|
before do
|
|
5
6
|
# Make sure we have a clean state because we want to test
|
|
@@ -21,21 +22,30 @@ describe Appsignal do
|
|
|
21
22
|
|
|
22
23
|
describe ".start" do
|
|
23
24
|
context "with no config set beforehand" do
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
let(:stdout_stream) { std_stream }
|
|
26
|
+
let(:stdout) { stdout_stream.read }
|
|
27
|
+
let(:stderr_stream) { std_stream }
|
|
28
|
+
let(:stderr) { stderr_stream.read }
|
|
29
|
+
before { ENV["APPSIGNAL_LOG"] = "stdout" }
|
|
30
|
+
|
|
31
|
+
it "does nothing when config is not set and there is no valid config in the env" do
|
|
29
32
|
expect(Appsignal::Extension).to_not receive(:start)
|
|
30
|
-
Appsignal.start
|
|
33
|
+
capture_std_streams(stdout_stream, stderr_stream) { Appsignal.start }
|
|
34
|
+
|
|
35
|
+
expect(stdout).to contains_log(
|
|
36
|
+
:error,
|
|
37
|
+
"appsignal: Not starting, no valid config for this environment"
|
|
38
|
+
)
|
|
31
39
|
end
|
|
32
40
|
|
|
33
41
|
it "should create a config from the env" do
|
|
34
42
|
ENV["APPSIGNAL_PUSH_API_KEY"] = "something"
|
|
35
43
|
expect(Appsignal::Extension).to receive(:start)
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
capture_std_streams(stdout_stream, stderr_stream) { Appsignal.start }
|
|
45
|
+
|
|
38
46
|
expect(Appsignal.config[:push_api_key]).to eq("something")
|
|
47
|
+
expect(stderr).to_not include("[ERROR]")
|
|
48
|
+
expect(stdout).to_not include("[ERROR]")
|
|
39
49
|
end
|
|
40
50
|
end
|
|
41
51
|
|
|
@@ -129,7 +139,7 @@ describe Appsignal do
|
|
|
129
139
|
|
|
130
140
|
describe ".forked" do
|
|
131
141
|
context "when not active" do
|
|
132
|
-
it "
|
|
142
|
+
it "does nothing" do
|
|
133
143
|
expect(Appsignal::Extension).to_not receive(:start)
|
|
134
144
|
|
|
135
145
|
Appsignal.forked
|
|
@@ -141,8 +151,8 @@ describe Appsignal do
|
|
|
141
151
|
Appsignal.config = project_fixture_config
|
|
142
152
|
end
|
|
143
153
|
|
|
144
|
-
it "
|
|
145
|
-
expect(Appsignal).to receive(:
|
|
154
|
+
it "starts the logger and extension" do
|
|
155
|
+
expect(Appsignal).to receive(:_start_logger)
|
|
146
156
|
expect(Appsignal::Extension).to receive(:start)
|
|
147
157
|
|
|
148
158
|
Appsignal.forked
|
|
@@ -222,28 +232,26 @@ describe Appsignal do
|
|
|
222
232
|
end
|
|
223
233
|
|
|
224
234
|
context "not active" do
|
|
225
|
-
|
|
226
|
-
let(:log_stream) { StringIO.new }
|
|
227
|
-
let(:log) { log_contents(log_stream) }
|
|
228
|
-
before do
|
|
229
|
-
Appsignal.config = project_fixture_config("not_active")
|
|
230
|
-
Appsignal.start
|
|
231
|
-
Appsignal.start_logger
|
|
232
|
-
Appsignal.internal_logger = test_logger(log_stream)
|
|
233
|
-
end
|
|
234
|
-
after { Appsignal.internal_logger = nil }
|
|
235
|
+
before { Appsignal.config = project_fixture_config("not_active") }
|
|
235
236
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
object = double
|
|
240
|
-
expect(object).to receive(:some_method).and_return(1)
|
|
237
|
+
describe ".monitor_transaction" do
|
|
238
|
+
it "does not create a transaction" do
|
|
239
|
+
object = double(:some_method => 1)
|
|
241
240
|
|
|
242
241
|
expect do
|
|
243
|
-
|
|
242
|
+
Appsignal.monitor_transaction("perform_job.nothing") do
|
|
244
243
|
object.some_method
|
|
245
|
-
end
|
|
246
|
-
end.to_not
|
|
244
|
+
end
|
|
245
|
+
end.to_not(change { created_transactions.count })
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "returns the block's return value" do
|
|
249
|
+
object = double(:some_method => 1)
|
|
250
|
+
|
|
251
|
+
return_value = Appsignal.monitor_transaction("perform_job.nothing") do
|
|
252
|
+
object.some_method
|
|
253
|
+
end
|
|
254
|
+
expect(return_value).to eq 1
|
|
247
255
|
end
|
|
248
256
|
|
|
249
257
|
context "with an unknown event type" do
|
|
@@ -254,8 +262,11 @@ describe Appsignal do
|
|
|
254
262
|
end
|
|
255
263
|
|
|
256
264
|
it "logs an error" do
|
|
257
|
-
|
|
258
|
-
|
|
265
|
+
logs =
|
|
266
|
+
capture_logs do
|
|
267
|
+
Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
|
|
268
|
+
end
|
|
269
|
+
expect(logs).to contains_log(
|
|
259
270
|
:error,
|
|
260
271
|
"Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
|
|
261
272
|
"(for jobs and tasks) or 'process_action' (for HTTP requests)"
|
|
@@ -265,111 +276,129 @@ describe Appsignal do
|
|
|
265
276
|
end
|
|
266
277
|
|
|
267
278
|
describe ".listen_for_error" do
|
|
268
|
-
|
|
269
|
-
|
|
279
|
+
let(:error) { ExampleException.new("specific error") }
|
|
280
|
+
|
|
281
|
+
it "reraises the error" do
|
|
270
282
|
expect do
|
|
271
|
-
Appsignal.listen_for_error
|
|
272
|
-
raise error
|
|
273
|
-
end
|
|
283
|
+
Appsignal.listen_for_error { raise error }
|
|
274
284
|
end.to raise_error(error)
|
|
275
285
|
end
|
|
286
|
+
|
|
287
|
+
it "does not create a transaction" do
|
|
288
|
+
expect do
|
|
289
|
+
expect do
|
|
290
|
+
Appsignal.listen_for_error { raise error }
|
|
291
|
+
end.to raise_error(error)
|
|
292
|
+
end.to_not(change { created_transactions.count })
|
|
293
|
+
end
|
|
276
294
|
end
|
|
277
295
|
|
|
278
296
|
describe ".send_error" do
|
|
279
|
-
|
|
297
|
+
let(:error) { ExampleException.new("specific error") }
|
|
298
|
+
|
|
299
|
+
it "does not raise an error" do
|
|
300
|
+
Appsignal.send_error(error)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "does not create a transaction" do
|
|
280
304
|
expect do
|
|
281
|
-
Appsignal.send_error(
|
|
282
|
-
end.to_not
|
|
305
|
+
Appsignal.send_error(error)
|
|
306
|
+
end.to_not(change { created_transactions.count })
|
|
283
307
|
end
|
|
284
308
|
end
|
|
285
309
|
|
|
286
310
|
describe ".set_error" do
|
|
287
|
-
|
|
311
|
+
let(:error) { ExampleException.new("specific error") }
|
|
312
|
+
|
|
313
|
+
it "does not raise an error" do
|
|
314
|
+
Appsignal.set_error(error)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it "does not create a transaction" do
|
|
288
318
|
expect do
|
|
289
|
-
Appsignal.set_error(
|
|
290
|
-
end.to_not
|
|
319
|
+
Appsignal.set_error(error)
|
|
320
|
+
end.to_not(change { created_transactions.count })
|
|
291
321
|
end
|
|
292
322
|
end
|
|
293
323
|
|
|
294
324
|
describe ".set_namespace" do
|
|
295
|
-
it "
|
|
296
|
-
|
|
297
|
-
Appsignal.set_namespace("custom")
|
|
298
|
-
end.to_not raise_error
|
|
325
|
+
it "does not raise an error" do
|
|
326
|
+
Appsignal.set_namespace("custom")
|
|
299
327
|
end
|
|
300
328
|
end
|
|
301
329
|
|
|
302
330
|
describe ".tag_request" do
|
|
303
|
-
it "
|
|
304
|
-
|
|
305
|
-
Appsignal.tag_request(:tag => "tag")
|
|
306
|
-
end.to_not raise_error
|
|
331
|
+
it "does not raise an error" do
|
|
332
|
+
Appsignal.tag_request(:tag => "tag")
|
|
307
333
|
end
|
|
308
334
|
end
|
|
309
335
|
end
|
|
310
336
|
|
|
311
337
|
context "with config and started" do
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
before do
|
|
315
|
-
Appsignal.config = project_fixture_config
|
|
316
|
-
Appsignal.start
|
|
317
|
-
Appsignal.start_logger
|
|
318
|
-
Appsignal.internal_logger = test_logger(log_stream)
|
|
319
|
-
end
|
|
320
|
-
after { Appsignal.internal_logger = nil }
|
|
338
|
+
before { start_agent }
|
|
339
|
+
around { |example| keep_transactions { example.run } }
|
|
321
340
|
|
|
322
341
|
describe ".monitor_transaction" do
|
|
323
342
|
context "with a successful call" do
|
|
324
|
-
it "
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
343
|
+
it "instruments and completes for a background job" do
|
|
344
|
+
return_value = nil
|
|
345
|
+
expect do
|
|
346
|
+
return_value =
|
|
347
|
+
Appsignal.monitor_transaction(
|
|
348
|
+
"perform_job.something",
|
|
349
|
+
{
|
|
350
|
+
:class => "BackgroundJob",
|
|
351
|
+
:method => "perform"
|
|
352
|
+
}
|
|
353
|
+
) do
|
|
354
|
+
:return_value
|
|
355
|
+
end
|
|
356
|
+
end.to(change { created_transactions.count }.by(1))
|
|
357
|
+
expect(return_value).to eq(:return_value)
|
|
358
|
+
|
|
359
|
+
transaction = last_transaction
|
|
360
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
|
|
361
|
+
expect(transaction).to have_action("BackgroundJob#perform")
|
|
362
|
+
expect(transaction).to include_event("name" => "perform_job.something")
|
|
363
|
+
expect(transaction).to be_completed
|
|
340
364
|
end
|
|
341
365
|
|
|
342
|
-
it "
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
366
|
+
it "instruments and completes for a http request" do
|
|
367
|
+
return_value = nil
|
|
368
|
+
expect do
|
|
369
|
+
return_value =
|
|
370
|
+
Appsignal.monitor_transaction(
|
|
371
|
+
"process_action.something",
|
|
372
|
+
{
|
|
373
|
+
:controller => "BlogPostsController",
|
|
374
|
+
:action => "show"
|
|
375
|
+
}
|
|
376
|
+
) do
|
|
377
|
+
:return_value
|
|
378
|
+
end
|
|
379
|
+
end.to(change { created_transactions.count }.by(1))
|
|
380
|
+
expect(return_value).to eq(:return_value)
|
|
348
381
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
)
|
|
353
|
-
|
|
354
|
-
expect(current.namespace).to eq Appsignal::Transaction::HTTP_REQUEST
|
|
355
|
-
expect(current.request).to be_a(::Rack::Request)
|
|
356
|
-
object.some_method
|
|
357
|
-
end
|
|
382
|
+
transaction = last_transaction
|
|
383
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
384
|
+
expect(transaction).to have_action("BlogPostsController#show")
|
|
385
|
+
expect(transaction).to include_event("name" => "process_action.something")
|
|
386
|
+
expect(transaction).to be_completed
|
|
358
387
|
end
|
|
359
388
|
end
|
|
360
389
|
|
|
361
390
|
context "with an erroring call" do
|
|
362
|
-
let(:error) { ExampleException.new }
|
|
363
|
-
|
|
364
|
-
it "should add the error to the current transaction and complete" do
|
|
365
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_error).with(error)
|
|
366
|
-
expect(Appsignal::Transaction).to receive(:complete_current!)
|
|
391
|
+
let(:error) { ExampleException.new("error message") }
|
|
367
392
|
|
|
393
|
+
it "adds the error to the current transaction and complete" do
|
|
368
394
|
expect do
|
|
369
395
|
Appsignal.monitor_transaction("perform_job.something") do
|
|
370
396
|
raise error
|
|
371
397
|
end
|
|
372
398
|
end.to raise_error(error)
|
|
399
|
+
|
|
400
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
401
|
+
expect(last_transaction).to be_completed
|
|
373
402
|
end
|
|
374
403
|
end
|
|
375
404
|
|
|
@@ -381,8 +410,11 @@ describe Appsignal do
|
|
|
381
410
|
end
|
|
382
411
|
|
|
383
412
|
it "logs an error" do
|
|
384
|
-
|
|
385
|
-
|
|
413
|
+
logs =
|
|
414
|
+
capture_logs do
|
|
415
|
+
Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
|
|
416
|
+
end
|
|
417
|
+
expect(logs).to contains_log(
|
|
386
418
|
:error,
|
|
387
419
|
"Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
|
|
388
420
|
"(for jobs and tasks) or 'process_action' (for HTTP requests)"
|
|
@@ -392,8 +424,6 @@ describe Appsignal do
|
|
|
392
424
|
end
|
|
393
425
|
|
|
394
426
|
describe ".monitor_single_transaction" do
|
|
395
|
-
around { |example| keep_transactions { example.run } }
|
|
396
|
-
|
|
397
427
|
context "with a successful call" do
|
|
398
428
|
it "calls monitor_transaction and Appsignal.stop" do
|
|
399
429
|
expect(Appsignal).to receive(:stop)
|
|
@@ -407,18 +437,8 @@ describe Appsignal do
|
|
|
407
437
|
end
|
|
408
438
|
|
|
409
439
|
transaction = last_transaction
|
|
410
|
-
|
|
411
|
-
expect(
|
|
412
|
-
"action" => "my_controller#my_action"
|
|
413
|
-
)
|
|
414
|
-
expect(transaction_hash["events"]).to match([
|
|
415
|
-
hash_including(
|
|
416
|
-
"name" => "perform_job.something",
|
|
417
|
-
"title" => "",
|
|
418
|
-
"body" => "",
|
|
419
|
-
"body_format" => Appsignal::EventFormatter::DEFAULT
|
|
420
|
-
)
|
|
421
|
-
])
|
|
440
|
+
expect(transaction).to have_action("my_controller#my_action")
|
|
441
|
+
expect(transaction).to include_event("name" => "perform_job.something")
|
|
422
442
|
end
|
|
423
443
|
end
|
|
424
444
|
|
|
@@ -439,75 +459,55 @@ describe Appsignal do
|
|
|
439
459
|
end.to raise_error(error)
|
|
440
460
|
|
|
441
461
|
transaction = last_transaction
|
|
442
|
-
|
|
443
|
-
expect(
|
|
444
|
-
"action" => "my_controller#my_action"
|
|
445
|
-
)
|
|
446
|
-
expect(transaction_hash["events"]).to match([
|
|
447
|
-
hash_including(
|
|
448
|
-
"name" => "perform_job.something",
|
|
449
|
-
"title" => "",
|
|
450
|
-
"body" => "",
|
|
451
|
-
"body_format" => Appsignal::EventFormatter::DEFAULT
|
|
452
|
-
)
|
|
453
|
-
])
|
|
462
|
+
expect(transaction).to have_action("my_controller#my_action")
|
|
463
|
+
expect(transaction).to include_event("name" => "perform_job.something")
|
|
454
464
|
end
|
|
455
465
|
end
|
|
456
466
|
end
|
|
457
467
|
|
|
458
468
|
describe ".tag_request" do
|
|
459
|
-
let(:transaction) { http_request_transaction }
|
|
460
469
|
around do |example|
|
|
461
470
|
start_agent
|
|
462
|
-
with_current_transaction
|
|
463
|
-
keep_transactions { example.run }
|
|
464
|
-
end
|
|
471
|
+
with_current_transaction(transaction) { example.run }
|
|
465
472
|
end
|
|
466
473
|
|
|
467
474
|
context "with transaction" do
|
|
475
|
+
let(:transaction) { http_request_transaction }
|
|
476
|
+
|
|
468
477
|
it "calls set_tags on the current transaction" do
|
|
469
478
|
Appsignal.tag_request("a" => "b")
|
|
470
|
-
transaction.complete # Manually trigger transaction sampling
|
|
471
479
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
"tags" => { "a" => "b" }
|
|
475
|
-
)
|
|
476
|
-
)
|
|
480
|
+
transaction._sample
|
|
481
|
+
expect(transaction).to include_tags("a" => "b")
|
|
477
482
|
end
|
|
478
483
|
end
|
|
479
484
|
|
|
480
485
|
context "without transaction" do
|
|
481
486
|
let(:transaction) { nil }
|
|
482
487
|
|
|
483
|
-
it "
|
|
488
|
+
it "does not set tags on the transaction" do
|
|
484
489
|
expect(Appsignal.tag_request).to be_falsy
|
|
490
|
+
Appsignal.tag_request("a" => "b")
|
|
491
|
+
|
|
492
|
+
expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_tags)
|
|
485
493
|
end
|
|
486
494
|
end
|
|
487
495
|
|
|
488
|
-
it "
|
|
496
|
+
it "also listens to tag_job" do
|
|
489
497
|
expect(Appsignal).to respond_to(:tag_job)
|
|
490
498
|
end
|
|
491
499
|
end
|
|
492
500
|
|
|
493
501
|
describe ".add_breadcrumb" do
|
|
494
|
-
|
|
502
|
+
around do |example|
|
|
503
|
+
start_agent
|
|
504
|
+
with_current_transaction(transaction) { example.run }
|
|
505
|
+
end
|
|
495
506
|
|
|
496
507
|
context "with transaction" do
|
|
497
508
|
let(:transaction) { http_request_transaction }
|
|
498
|
-
around do |example|
|
|
499
|
-
Appsignal.config = project_fixture_config
|
|
500
|
-
set_current_transaction transaction do
|
|
501
|
-
example.run
|
|
502
|
-
end
|
|
503
|
-
end
|
|
504
509
|
|
|
505
|
-
it "
|
|
506
|
-
expect(transaction).to receive(:add_breadcrumb)
|
|
507
|
-
.with("Network", "http", "User made network request", { :response => 200 }, fixed_time)
|
|
508
|
-
end
|
|
509
|
-
|
|
510
|
-
after do
|
|
510
|
+
it "adds the breadcrumb to the transaction" do
|
|
511
511
|
Appsignal.add_breadcrumb(
|
|
512
512
|
"Network",
|
|
513
513
|
"http",
|
|
@@ -515,13 +515,22 @@ describe Appsignal do
|
|
|
515
515
|
{ :response => 200 },
|
|
516
516
|
fixed_time
|
|
517
517
|
)
|
|
518
|
+
|
|
519
|
+
transaction._sample
|
|
520
|
+
expect(transaction).to include_breadcrumb(
|
|
521
|
+
"http",
|
|
522
|
+
"Network",
|
|
523
|
+
"User made network request",
|
|
524
|
+
{ "response" => 200 },
|
|
525
|
+
fixed_time
|
|
526
|
+
)
|
|
518
527
|
end
|
|
519
528
|
end
|
|
520
529
|
|
|
521
530
|
context "without transaction" do
|
|
522
531
|
let(:transaction) { nil }
|
|
523
532
|
|
|
524
|
-
it "
|
|
533
|
+
it "does not add a breadcrumb to any transaction" do
|
|
525
534
|
expect(Appsignal.add_breadcrumb("Network", "http")).to be_falsy
|
|
526
535
|
end
|
|
527
536
|
end
|
|
@@ -550,13 +559,15 @@ describe Appsignal do
|
|
|
550
559
|
end
|
|
551
560
|
|
|
552
561
|
it "should not raise an exception when out of range" do
|
|
553
|
-
expect(Appsignal::Extension).to receive(:set_gauge).with(
|
|
554
|
-
|
|
562
|
+
expect(Appsignal::Extension).to receive(:set_gauge).with(
|
|
563
|
+
"key",
|
|
564
|
+
10,
|
|
565
|
+
Appsignal::Extension.data_map_new
|
|
566
|
+
).and_raise(RangeError)
|
|
555
567
|
expect(Appsignal.internal_logger).to receive(:warn)
|
|
556
568
|
.with("Gauge value 10 for key 'key' is too big")
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
end.to_not raise_error
|
|
569
|
+
|
|
570
|
+
Appsignal.set_gauge("key", 10)
|
|
560
571
|
end
|
|
561
572
|
end
|
|
562
573
|
|
|
@@ -634,9 +645,8 @@ describe Appsignal do
|
|
|
634
645
|
.with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
|
|
635
646
|
expect(Appsignal.internal_logger).to receive(:warn)
|
|
636
647
|
.with("Counter value 10 for key 'key' is too big")
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
end.to_not raise_error
|
|
648
|
+
|
|
649
|
+
Appsignal.increment_counter("key", 10)
|
|
640
650
|
end
|
|
641
651
|
end
|
|
642
652
|
|
|
@@ -664,9 +674,8 @@ describe Appsignal do
|
|
|
664
674
|
.with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
|
|
665
675
|
expect(Appsignal.internal_logger).to receive(:warn)
|
|
666
676
|
.with("Distribution value 10 for key 'key' is too big")
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
end.to_not raise_error
|
|
677
|
+
|
|
678
|
+
Appsignal.add_distribution_value("key", 10)
|
|
670
679
|
end
|
|
671
680
|
end
|
|
672
681
|
end
|
|
@@ -706,46 +715,39 @@ describe Appsignal do
|
|
|
706
715
|
end
|
|
707
716
|
|
|
708
717
|
describe ".send_error" do
|
|
709
|
-
let(:
|
|
710
|
-
Appsignal::Transaction.new(
|
|
711
|
-
SecureRandom.uuid,
|
|
712
|
-
Appsignal::Transaction::HTTP_REQUEST,
|
|
713
|
-
Appsignal::Transaction::GenericRequest.new({})
|
|
714
|
-
)
|
|
715
|
-
end
|
|
716
|
-
let(:error) { ExampleException.new }
|
|
718
|
+
let(:error) { ExampleException.new("error message") }
|
|
717
719
|
let(:err_stream) { std_stream }
|
|
718
720
|
let(:stderr) { err_stream.read }
|
|
719
|
-
around
|
|
721
|
+
around do |example|
|
|
722
|
+
keep_transactions { example.run }
|
|
723
|
+
end
|
|
720
724
|
|
|
721
725
|
it "sends the error to AppSignal" do
|
|
722
|
-
expect(
|
|
723
|
-
kind_of(String),
|
|
724
|
-
Appsignal::Transaction::HTTP_REQUEST,
|
|
725
|
-
kind_of(Appsignal::Transaction::GenericRequest)
|
|
726
|
-
).and_return(transaction)
|
|
727
|
-
expect(transaction).to receive(:set_error).with(error)
|
|
728
|
-
expect(transaction).to_not receive(:set_tags)
|
|
729
|
-
expect(transaction).to receive(:complete)
|
|
726
|
+
expect { Appsignal.send_error(error) }.to(change { created_transactions.count }.by(1))
|
|
730
727
|
|
|
731
|
-
|
|
728
|
+
transaction = last_transaction
|
|
729
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
730
|
+
expect(transaction).to_not have_action
|
|
731
|
+
expect(transaction).to have_error("ExampleException", "error message")
|
|
732
|
+
expect(transaction).to_not include_tags
|
|
733
|
+
expect(transaction).to be_completed
|
|
732
734
|
end
|
|
733
735
|
|
|
734
736
|
context "when given error is not an Exception" do
|
|
735
|
-
let(:error) {
|
|
737
|
+
let(:error) { "string value" }
|
|
736
738
|
|
|
737
739
|
it "logs an error message" do
|
|
738
|
-
|
|
740
|
+
logs = capture_logs { Appsignal.send_error(error) }
|
|
741
|
+
expect(logs).to contains_log(
|
|
742
|
+
:error,
|
|
739
743
|
"Appsignal.send_error: Cannot send error. " \
|
|
740
744
|
"The given value is not an exception: #{error.inspect}"
|
|
741
745
|
)
|
|
742
746
|
end
|
|
743
747
|
|
|
744
748
|
it "does not send the error" do
|
|
745
|
-
expect(
|
|
749
|
+
expect { Appsignal.send_error(error) }.to_not(change { created_transactions.count })
|
|
746
750
|
end
|
|
747
|
-
|
|
748
|
-
after { Appsignal.send_error(error) }
|
|
749
751
|
end
|
|
750
752
|
|
|
751
753
|
context "with tags" do
|
|
@@ -760,13 +762,7 @@ describe Appsignal do
|
|
|
760
762
|
end.to change { created_transactions.count }.by(1)
|
|
761
763
|
end
|
|
762
764
|
|
|
763
|
-
|
|
764
|
-
transaction_hash = transaction.to_h
|
|
765
|
-
expect(transaction_hash).to include(
|
|
766
|
-
"sample_data" => hash_including(
|
|
767
|
-
"tags" => { "a" => "a", "b" => "b" }
|
|
768
|
-
)
|
|
769
|
-
)
|
|
765
|
+
expect(last_transaction).to include_tags("a" => "a", "b" => "b")
|
|
770
766
|
|
|
771
767
|
message = "The tags argument for `Appsignal.send_error` is deprecated. " \
|
|
772
768
|
"Please use the block method to set tags instead.\n\n" \
|
|
@@ -791,9 +787,7 @@ describe Appsignal do
|
|
|
791
787
|
end.to change { created_transactions.count }.by(1)
|
|
792
788
|
end
|
|
793
789
|
|
|
794
|
-
|
|
795
|
-
transaction_hash = transaction.to_h
|
|
796
|
-
expect(transaction_hash).to include("namespace" => namespace)
|
|
790
|
+
expect(last_transaction).to have_namespace(namespace)
|
|
797
791
|
|
|
798
792
|
message = "The namespace argument for `Appsignal.send_error` is deprecated. " \
|
|
799
793
|
"Please use the block method to set the namespace instead.\n\n" \
|
|
@@ -808,23 +802,15 @@ describe Appsignal do
|
|
|
808
802
|
|
|
809
803
|
context "when given a block" do
|
|
810
804
|
it "yields the transaction and allows additional metadata to be set" do
|
|
811
|
-
captured_transaction = nil
|
|
812
805
|
keep_transactions do
|
|
813
806
|
Appsignal.send_error(StandardError.new("my_error")) do |transaction|
|
|
814
|
-
captured_transaction = transaction
|
|
815
807
|
transaction.set_action("my_action")
|
|
816
808
|
transaction.set_namespace("my_namespace")
|
|
817
809
|
end
|
|
818
810
|
end
|
|
819
|
-
expect(
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
"error" => {
|
|
823
|
-
"name" => "StandardError",
|
|
824
|
-
"message" => "my_error",
|
|
825
|
-
"backtrace" => kind_of(String) # TODO: should be Array
|
|
826
|
-
}
|
|
827
|
-
)
|
|
811
|
+
expect(last_transaction).to have_namespace("my_namespace")
|
|
812
|
+
expect(last_transaction).to have_action("my_action")
|
|
813
|
+
expect(last_transaction).to have_error("StandardError", "my_error")
|
|
828
814
|
end
|
|
829
815
|
end
|
|
830
816
|
end
|
|
@@ -841,17 +827,10 @@ describe Appsignal do
|
|
|
841
827
|
end.to raise_error(ExampleException, "I am an exception")
|
|
842
828
|
end.to change { created_transactions.count }.by(1)
|
|
843
829
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
"backtrace" => kind_of(String)
|
|
849
|
-
},
|
|
850
|
-
"namespace" => Appsignal::Transaction::HTTP_REQUEST, # Default namespace
|
|
851
|
-
"sample_data" => hash_including(
|
|
852
|
-
"tags" => {}
|
|
853
|
-
)
|
|
854
|
-
)
|
|
830
|
+
# Default namespace
|
|
831
|
+
expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
832
|
+
expect(last_transaction).to have_error("ExampleException", "I am an exception")
|
|
833
|
+
expect(last_transaction).to_not include_tags
|
|
855
834
|
end
|
|
856
835
|
|
|
857
836
|
context "with tags" do
|
|
@@ -864,17 +843,10 @@ describe Appsignal do
|
|
|
864
843
|
end.to raise_error(ExampleException, "I am an exception")
|
|
865
844
|
end.to change { created_transactions.count }.by(1)
|
|
866
845
|
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
"backtrace" => kind_of(String)
|
|
872
|
-
},
|
|
873
|
-
"namespace" => Appsignal::Transaction::HTTP_REQUEST, # Default namespace
|
|
874
|
-
"sample_data" => hash_including(
|
|
875
|
-
"tags" => { "foo" => "bar" }
|
|
876
|
-
)
|
|
877
|
-
)
|
|
846
|
+
# Default namespace
|
|
847
|
+
expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
848
|
+
expect(last_transaction).to have_error("ExampleException", "I am an exception")
|
|
849
|
+
expect(last_transaction).to include_tags("foo" => "bar")
|
|
878
850
|
end
|
|
879
851
|
end
|
|
880
852
|
|
|
@@ -888,17 +860,10 @@ describe Appsignal do
|
|
|
888
860
|
end.to raise_error(ExampleException, "I am an exception")
|
|
889
861
|
end.to change { created_transactions.count }.by(1)
|
|
890
862
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
"backtrace" => kind_of(String)
|
|
896
|
-
},
|
|
897
|
-
"namespace" => "custom_namespace",
|
|
898
|
-
"sample_data" => hash_including(
|
|
899
|
-
"tags" => {}
|
|
900
|
-
)
|
|
901
|
-
)
|
|
863
|
+
# Default namespace
|
|
864
|
+
expect(last_transaction).to have_namespace("custom_namespace")
|
|
865
|
+
expect(last_transaction).to have_error("ExampleException", "I am an exception")
|
|
866
|
+
expect(last_transaction).to_not include_tags
|
|
902
867
|
end
|
|
903
868
|
end
|
|
904
869
|
end
|
|
@@ -907,42 +872,56 @@ describe Appsignal do
|
|
|
907
872
|
let(:err_stream) { std_stream }
|
|
908
873
|
let(:stderr) { err_stream.read }
|
|
909
874
|
let(:error) { ExampleException.new("I am an exception") }
|
|
910
|
-
|
|
875
|
+
let(:transaction) { http_request_transaction }
|
|
911
876
|
around { |example| keep_transactions { example.run } }
|
|
912
877
|
|
|
913
878
|
context "when there is an active transaction" do
|
|
914
|
-
|
|
915
|
-
expect(transaction).to receive(:set_error).with(error)
|
|
916
|
-
expect(transaction).to_not receive(:set_tags)
|
|
917
|
-
expect(transaction).to_not receive(:set_namespace)
|
|
879
|
+
before { set_current_transaction(transaction) }
|
|
918
880
|
|
|
881
|
+
it "adds the error to the active transaction" do
|
|
919
882
|
Appsignal.set_error(error)
|
|
883
|
+
|
|
884
|
+
transaction._sample
|
|
885
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
886
|
+
expect(transaction).to have_error("ExampleException", "I am an exception")
|
|
887
|
+
expect(transaction).to_not include_tags
|
|
920
888
|
end
|
|
921
889
|
|
|
922
890
|
context "when the error is not an Exception" do
|
|
923
891
|
let(:error) { Object.new }
|
|
924
892
|
|
|
893
|
+
it "does not set an error" do
|
|
894
|
+
silence { Appsignal.set_error(error) }
|
|
895
|
+
|
|
896
|
+
transaction._sample
|
|
897
|
+
expect(transaction).to_not have_error
|
|
898
|
+
expect(transaction).to_not include_tags
|
|
899
|
+
end
|
|
900
|
+
|
|
925
901
|
it "logs an error" do
|
|
926
|
-
|
|
902
|
+
logs = capture_logs { Appsignal.set_error(error) }
|
|
903
|
+
expect(logs).to contains_log(
|
|
904
|
+
:error,
|
|
927
905
|
"Appsignal.set_error: Cannot set error. " \
|
|
928
906
|
"The given value is not an exception: #{error.inspect}"
|
|
929
907
|
)
|
|
930
|
-
expect(transaction).to_not receive(:set_error)
|
|
931
|
-
expect(transaction).to_not receive(:set_tags)
|
|
932
|
-
expect(transaction).to_not receive(:set_namespace)
|
|
933
|
-
|
|
934
|
-
Appsignal.set_error(error)
|
|
935
908
|
end
|
|
936
909
|
end
|
|
937
910
|
|
|
938
911
|
context "with tags" do
|
|
939
912
|
let(:tags) { { "foo" => "bar" } }
|
|
940
913
|
|
|
941
|
-
it "
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
914
|
+
it "tags the transaction" do
|
|
915
|
+
silence(:allowed => ["set_error", "The tags argument for"]) do
|
|
916
|
+
Appsignal.set_error(error, tags)
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
transaction._sample
|
|
920
|
+
expect(transaction).to have_error(error)
|
|
921
|
+
expect(transaction).to include_tags(tags)
|
|
922
|
+
end
|
|
945
923
|
|
|
924
|
+
it "prints a deprecation warning and tags the transaction" do
|
|
946
925
|
logs = capture_logs do
|
|
947
926
|
capture_std_streams(std_stream, err_stream) do
|
|
948
927
|
Appsignal.set_error(error, tags)
|
|
@@ -963,11 +942,17 @@ describe Appsignal do
|
|
|
963
942
|
context "with namespace" do
|
|
964
943
|
let(:namespace) { "admin" }
|
|
965
944
|
|
|
966
|
-
it "
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
945
|
+
it "sets the namespace on the transaction" do
|
|
946
|
+
silence(:allowed => ["set_error", "The namespace argument for"]) do
|
|
947
|
+
Appsignal.set_error(error, nil, namespace)
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
expect(transaction).to have_error("ExampleException", "I am an exception")
|
|
951
|
+
expect(transaction).to have_namespace(namespace)
|
|
952
|
+
expect(transaction).to_not include_tags
|
|
953
|
+
end
|
|
970
954
|
|
|
955
|
+
it "prints a deprecation warning andsets the namespace on the transaction" do
|
|
971
956
|
logs = capture_logs do
|
|
972
957
|
capture_std_streams(std_stream, err_stream) do
|
|
973
958
|
Appsignal.set_error(error, nil, namespace)
|
|
@@ -987,135 +972,137 @@ describe Appsignal do
|
|
|
987
972
|
|
|
988
973
|
context "when given a block" do
|
|
989
974
|
it "yields the transaction and allows additional metadata to be set" do
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
captured_transaction = transaction
|
|
994
|
-
transaction.set_action("my_action")
|
|
995
|
-
transaction.set_namespace("my_namespace")
|
|
996
|
-
end
|
|
975
|
+
Appsignal.set_error(StandardError.new("my_error")) do |t|
|
|
976
|
+
t.set_action("my_action")
|
|
977
|
+
t.set_namespace("my_namespace")
|
|
997
978
|
end
|
|
998
979
|
|
|
999
|
-
expect(transaction).to
|
|
1000
|
-
expect(
|
|
1001
|
-
|
|
1002
|
-
"action" => "my_action",
|
|
1003
|
-
"error" => {
|
|
1004
|
-
"name" => "StandardError",
|
|
1005
|
-
"message" => "my_error",
|
|
1006
|
-
"backtrace" => kind_of(String)
|
|
1007
|
-
}
|
|
1008
|
-
)
|
|
980
|
+
expect(transaction).to have_namespace("my_namespace")
|
|
981
|
+
expect(transaction).to have_action("my_action")
|
|
982
|
+
expect(transaction).to have_error("StandardError", "my_error")
|
|
1009
983
|
end
|
|
1010
984
|
end
|
|
1011
985
|
end
|
|
1012
986
|
|
|
1013
987
|
context "when there is no active transaction" do
|
|
1014
988
|
it "does nothing" do
|
|
1015
|
-
allow(Appsignal::Transaction).to receive(:current).and_return(nil)
|
|
1016
|
-
|
|
1017
|
-
expect(transaction).to_not receive(:set_error)
|
|
1018
|
-
|
|
1019
989
|
Appsignal.set_error(error)
|
|
990
|
+
|
|
991
|
+
expect(transaction).to_not have_error
|
|
1020
992
|
end
|
|
1021
993
|
end
|
|
1022
994
|
end
|
|
1023
995
|
|
|
1024
996
|
describe ".set_action" do
|
|
1025
|
-
|
|
997
|
+
around { |example| keep_transactions { example.run } }
|
|
1026
998
|
|
|
1027
|
-
|
|
1028
|
-
|
|
999
|
+
context "with current transaction" do
|
|
1000
|
+
before { set_current_transaction(transaction) }
|
|
1029
1001
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1002
|
+
it "sets the namespace on the current transaction" do
|
|
1003
|
+
Appsignal.set_action("custom")
|
|
1032
1004
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1005
|
+
expect(transaction).to have_action("custom")
|
|
1006
|
+
end
|
|
1035
1007
|
|
|
1036
|
-
|
|
1008
|
+
it "does not set the action if the action is nil" do
|
|
1009
|
+
Appsignal.set_action(nil)
|
|
1037
1010
|
|
|
1038
|
-
|
|
1011
|
+
expect(transaction).to_not have_action
|
|
1012
|
+
end
|
|
1039
1013
|
end
|
|
1040
1014
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1015
|
+
context "without current transaction" do
|
|
1016
|
+
it "does not set ther action" do
|
|
1017
|
+
Appsignal.set_action("custom")
|
|
1043
1018
|
|
|
1044
|
-
|
|
1019
|
+
expect(transaction).to_not have_action
|
|
1020
|
+
end
|
|
1045
1021
|
end
|
|
1046
1022
|
end
|
|
1047
1023
|
|
|
1048
1024
|
describe ".set_namespace" do
|
|
1049
|
-
|
|
1025
|
+
around { |example| keep_transactions { example.run } }
|
|
1050
1026
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1027
|
+
context "with current transaction" do
|
|
1028
|
+
before { set_current_transaction(transaction) }
|
|
1053
1029
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1030
|
+
it "should set the namespace to the current transaction" do
|
|
1031
|
+
Appsignal.set_namespace("custom")
|
|
1056
1032
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1033
|
+
expect(transaction).to have_namespace("custom")
|
|
1034
|
+
end
|
|
1059
1035
|
|
|
1060
|
-
|
|
1036
|
+
it "does not update the namespace if the namespace is nil" do
|
|
1037
|
+
Appsignal.set_namespace(nil)
|
|
1061
1038
|
|
|
1062
|
-
|
|
1039
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
1040
|
+
end
|
|
1063
1041
|
end
|
|
1064
1042
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1043
|
+
context "without current transaction" do
|
|
1044
|
+
it "does not update the namespace" do
|
|
1045
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
1046
|
+
|
|
1047
|
+
Appsignal.set_namespace("custom")
|
|
1067
1048
|
|
|
1068
|
-
|
|
1049
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
1050
|
+
end
|
|
1069
1051
|
end
|
|
1070
1052
|
end
|
|
1071
1053
|
|
|
1072
1054
|
describe ".instrument" do
|
|
1073
1055
|
it_behaves_like "instrument helper" do
|
|
1074
1056
|
let(:instrumenter) { Appsignal }
|
|
1075
|
-
before
|
|
1076
|
-
expect(Appsignal::Transaction).to receive(:current).at_least(:once)
|
|
1077
|
-
.and_return(transaction)
|
|
1078
|
-
end
|
|
1057
|
+
before { set_current_transaction(transaction) }
|
|
1079
1058
|
end
|
|
1080
1059
|
end
|
|
1081
1060
|
|
|
1082
1061
|
describe ".instrument_sql" do
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
.and_return(transaction)
|
|
1086
|
-
end
|
|
1062
|
+
around { |example| keep_transactions { example.run } }
|
|
1063
|
+
before { set_current_transaction(transaction) }
|
|
1087
1064
|
|
|
1088
1065
|
it "creates an SQL event on the transaction" do
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1066
|
+
result =
|
|
1067
|
+
Appsignal.instrument_sql "name", "title", "body" do
|
|
1068
|
+
"return value"
|
|
1069
|
+
end
|
|
1092
1070
|
|
|
1093
|
-
result = Appsignal.instrument_sql "name", "title", "body" do
|
|
1094
|
-
"return value"
|
|
1095
|
-
end
|
|
1096
1071
|
expect(result).to eq "return value"
|
|
1072
|
+
expect(transaction).to include_event(
|
|
1073
|
+
"name" => "name",
|
|
1074
|
+
"title" => "title",
|
|
1075
|
+
"body" => "body",
|
|
1076
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT
|
|
1077
|
+
)
|
|
1097
1078
|
end
|
|
1098
1079
|
end
|
|
1099
1080
|
|
|
1100
1081
|
describe ".without_instrumentation" do
|
|
1082
|
+
around { |example| keep_transactions { example.run } }
|
|
1101
1083
|
let(:transaction) { http_request_transaction }
|
|
1102
|
-
before { allow(Appsignal::Transaction).to receive(:current).and_return(transaction) }
|
|
1103
1084
|
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1085
|
+
context "with current transaction" do
|
|
1086
|
+
before { set_current_transaction(transaction) }
|
|
1087
|
+
|
|
1088
|
+
it "does not record events on the transaction" do
|
|
1089
|
+
expect(transaction).to receive(:pause!).and_call_original
|
|
1090
|
+
expect(transaction).to receive(:resume!).and_call_original
|
|
1091
|
+
|
|
1092
|
+
Appsignal.instrument("register.this.event") { :do_nothing }
|
|
1093
|
+
Appsignal.without_instrumentation do
|
|
1094
|
+
Appsignal.instrument("dont.register.this.event") { :do_nothing }
|
|
1095
|
+
end
|
|
1096
|
+
|
|
1097
|
+
expect(transaction).to include_event("name" => "register.this.event")
|
|
1098
|
+
expect(transaction).to_not include_event("name" => "dont.register.this.event")
|
|
1110
1099
|
end
|
|
1111
|
-
expect(transaction.to_h["events"].map { |e| e["name"] })
|
|
1112
|
-
.to match_array("register.this.event")
|
|
1113
1100
|
end
|
|
1114
1101
|
|
|
1115
|
-
context "without transaction" do
|
|
1102
|
+
context "without current transaction" do
|
|
1116
1103
|
let(:transaction) { nil }
|
|
1117
1104
|
|
|
1118
|
-
it "
|
|
1105
|
+
it "does not crash" do
|
|
1119
1106
|
Appsignal.without_instrumentation { :do_nothing }
|
|
1120
1107
|
end
|
|
1121
1108
|
end
|
|
@@ -1123,17 +1110,35 @@ describe Appsignal do
|
|
|
1123
1110
|
end
|
|
1124
1111
|
|
|
1125
1112
|
describe ".start_logger" do
|
|
1113
|
+
let(:stderr_stream) { std_stream }
|
|
1114
|
+
let(:stderr) { stderr_stream.read }
|
|
1115
|
+
let(:log_stream) { std_stream }
|
|
1116
|
+
let(:log) { log_contents(log_stream) }
|
|
1117
|
+
|
|
1118
|
+
it "prints and logs a deprecation warning" do
|
|
1119
|
+
use_logger_with(log_stream) do
|
|
1120
|
+
capture_std_streams(std_stream, stderr_stream) do
|
|
1121
|
+
Appsignal.start_logger
|
|
1122
|
+
end
|
|
1123
|
+
end
|
|
1124
|
+
expect(stderr).to include("appsignal WARNING: Callng 'Appsignal.start_logger' is deprecated.")
|
|
1125
|
+
expect(log).to contains_log(:warn, "Callng 'Appsignal.start_logger' is deprecated.")
|
|
1126
|
+
end
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
describe "._start_logger" do
|
|
1126
1130
|
let(:out_stream) { std_stream }
|
|
1127
1131
|
let(:output) { out_stream.read }
|
|
1128
1132
|
let(:log_path) { File.join(tmp_dir, "log") }
|
|
1129
1133
|
let(:log_file) { File.join(log_path, "appsignal.log") }
|
|
1134
|
+
let(:log_level) { "debug" }
|
|
1130
1135
|
|
|
1131
1136
|
before do
|
|
1132
1137
|
FileUtils.mkdir_p(log_path)
|
|
1133
1138
|
# Clear state from previous test
|
|
1134
1139
|
Appsignal.internal_logger = nil
|
|
1135
|
-
if Appsignal.instance_variable_defined?(:@
|
|
1136
|
-
Appsignal.remove_instance_variable(:@
|
|
1140
|
+
if Appsignal.instance_variable_defined?(:@in_memory_logger)
|
|
1141
|
+
Appsignal.remove_instance_variable(:@in_memory_logger)
|
|
1137
1142
|
end
|
|
1138
1143
|
end
|
|
1139
1144
|
after { FileUtils.rm_rf(log_path) }
|
|
@@ -1141,10 +1146,12 @@ describe Appsignal do
|
|
|
1141
1146
|
def initialize_config
|
|
1142
1147
|
Appsignal.config = project_fixture_config(
|
|
1143
1148
|
"production",
|
|
1144
|
-
:log_path => log_path
|
|
1149
|
+
:log_path => log_path,
|
|
1150
|
+
:log_level => log_level
|
|
1145
1151
|
)
|
|
1146
|
-
Appsignal.internal_logger.error("Log in memory")
|
|
1147
|
-
|
|
1152
|
+
Appsignal.internal_logger.error("Log in memory line 1")
|
|
1153
|
+
Appsignal.internal_logger.debug("Log in memory line 2")
|
|
1154
|
+
expect(Appsignal.in_memory_logger.messages).to_not be_empty
|
|
1148
1155
|
end
|
|
1149
1156
|
|
|
1150
1157
|
context "when the log path is writable" do
|
|
@@ -1154,7 +1161,7 @@ describe Appsignal do
|
|
|
1154
1161
|
before do
|
|
1155
1162
|
capture_stdout(out_stream) do
|
|
1156
1163
|
initialize_config
|
|
1157
|
-
Appsignal.
|
|
1164
|
+
Appsignal._start_logger
|
|
1158
1165
|
Appsignal.internal_logger.error("Log to file")
|
|
1159
1166
|
end
|
|
1160
1167
|
expect(Appsignal.internal_logger).to be_a(Appsignal::Utils::IntegrationLogger)
|
|
@@ -1166,12 +1173,26 @@ describe Appsignal do
|
|
|
1166
1173
|
expect(output).to be_empty
|
|
1167
1174
|
end
|
|
1168
1175
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1176
|
+
context "with log level info" do
|
|
1177
|
+
let(:log_level) { "info" }
|
|
1178
|
+
|
|
1179
|
+
it "amends info log level and higher memory log messages to log file" do
|
|
1180
|
+
expect(log_file_contents).to include "[ERROR] appsignal: Log in memory line 1"
|
|
1181
|
+
expect(log_file_contents).to_not include "[DEBUG]"
|
|
1182
|
+
end
|
|
1183
|
+
end
|
|
1184
|
+
|
|
1185
|
+
context "with log level debug" do
|
|
1186
|
+
let(:log_level) { "debug" }
|
|
1187
|
+
|
|
1188
|
+
it "amends debug log level and higher memory log messages to log file" do
|
|
1189
|
+
expect(log_file_contents).to include "[ERROR] appsignal: Log in memory line 1"
|
|
1190
|
+
expect(log_file_contents).to include "[DEBUG] appsignal: Log in memory line 2"
|
|
1191
|
+
end
|
|
1171
1192
|
end
|
|
1172
1193
|
|
|
1173
1194
|
it "clears the in memory log after writing to the new logger" do
|
|
1174
|
-
expect(Appsignal.
|
|
1195
|
+
expect(Appsignal.instance_variable_get(:@in_memory_logger)).to be_nil
|
|
1175
1196
|
end
|
|
1176
1197
|
end
|
|
1177
1198
|
|
|
@@ -1182,7 +1203,7 @@ describe Appsignal do
|
|
|
1182
1203
|
|
|
1183
1204
|
capture_stdout(out_stream) do
|
|
1184
1205
|
initialize_config
|
|
1185
|
-
Appsignal.
|
|
1206
|
+
Appsignal._start_logger
|
|
1186
1207
|
Appsignal.internal_logger.error("Log to not writable log file")
|
|
1187
1208
|
expect(Appsignal.internal_logger).to be_a(Appsignal::Utils::IntegrationLogger)
|
|
1188
1209
|
end
|
|
@@ -1198,7 +1219,7 @@ describe Appsignal do
|
|
|
1198
1219
|
end
|
|
1199
1220
|
|
|
1200
1221
|
it "clears the in memory log after writing to the new logger" do
|
|
1201
|
-
expect(Appsignal.
|
|
1222
|
+
expect(Appsignal.instance_variable_get(:@in_memory_logger)).to be_nil
|
|
1202
1223
|
end
|
|
1203
1224
|
|
|
1204
1225
|
it "outputs a warning" do
|
|
@@ -1216,7 +1237,7 @@ describe Appsignal do
|
|
|
1216
1237
|
|
|
1217
1238
|
capture_stdout(out_stream) do
|
|
1218
1239
|
initialize_config
|
|
1219
|
-
Appsignal.
|
|
1240
|
+
Appsignal._start_logger
|
|
1220
1241
|
Appsignal.internal_logger.error("Log to not writable log path")
|
|
1221
1242
|
end
|
|
1222
1243
|
expect(Appsignal.internal_logger).to be_a(Appsignal::Utils::IntegrationLogger)
|
|
@@ -1245,7 +1266,7 @@ describe Appsignal do
|
|
|
1245
1266
|
before do
|
|
1246
1267
|
capture_stdout(out_stream) do
|
|
1247
1268
|
initialize_config
|
|
1248
|
-
Appsignal.
|
|
1269
|
+
Appsignal._start_logger
|
|
1249
1270
|
Appsignal.internal_logger.error("Log to stdout")
|
|
1250
1271
|
end
|
|
1251
1272
|
expect(Appsignal.internal_logger).to be_a(Appsignal::Utils::IntegrationLogger)
|
|
@@ -1261,7 +1282,7 @@ describe Appsignal do
|
|
|
1261
1282
|
end
|
|
1262
1283
|
|
|
1263
1284
|
it "clears the in memory log after writing to the new logger" do
|
|
1264
|
-
expect(Appsignal.
|
|
1285
|
+
expect(Appsignal.instance_variable_get(:@in_memory_logger)).to be_nil
|
|
1265
1286
|
end
|
|
1266
1287
|
end
|
|
1267
1288
|
|
|
@@ -1272,7 +1293,7 @@ describe Appsignal do
|
|
|
1272
1293
|
before do
|
|
1273
1294
|
Appsignal.config = nil
|
|
1274
1295
|
capture_stdout(out_stream) do
|
|
1275
|
-
Appsignal.
|
|
1296
|
+
Appsignal._start_logger
|
|
1276
1297
|
end
|
|
1277
1298
|
end
|
|
1278
1299
|
|
|
@@ -1287,7 +1308,7 @@ describe Appsignal do
|
|
|
1287
1308
|
capture_stdout(out_stream) do
|
|
1288
1309
|
initialize_config
|
|
1289
1310
|
Appsignal.config[:log_level] = "debug"
|
|
1290
|
-
Appsignal.
|
|
1311
|
+
Appsignal._start_logger
|
|
1291
1312
|
end
|
|
1292
1313
|
end
|
|
1293
1314
|
|