appsignal 3.9.1-java → 3.9.3-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3135 -0
  3. data/.rubocop.yml +28 -20
  4. data/.rubocop_todo.yml +7 -33
  5. data/CHANGELOG.md +58 -0
  6. data/Rakefile +79 -64
  7. data/appsignal.gemspec +1 -1
  8. data/build_matrix.yml +109 -179
  9. data/ext/base.rb +1 -1
  10. data/gemfiles/hanami-2.1.gemfile +7 -0
  11. data/lib/appsignal/cli/diagnose.rb +1 -1
  12. data/lib/appsignal/config.rb +1 -1
  13. data/lib/appsignal/demo.rb +0 -1
  14. data/lib/appsignal/environment.rb +5 -1
  15. data/lib/appsignal/extension/jruby.rb +1 -1
  16. data/lib/appsignal/helpers/instrumentation.rb +3 -3
  17. data/lib/appsignal/hooks/active_job.rb +2 -1
  18. data/lib/appsignal/integrations/action_cable.rb +1 -1
  19. data/lib/appsignal/integrations/grape.rb +19 -47
  20. data/lib/appsignal/integrations/hanami.rb +27 -41
  21. data/lib/appsignal/integrations/padrino.rb +46 -43
  22. data/lib/appsignal/integrations/railtie.rb +1 -4
  23. data/lib/appsignal/integrations/resque.rb +1 -1
  24. data/lib/appsignal/integrations/sidekiq.rb +2 -4
  25. data/lib/appsignal/integrations/sinatra.rb +7 -2
  26. data/lib/appsignal/probes/gvl.rb +24 -2
  27. data/lib/appsignal/probes/sidekiq.rb +1 -1
  28. data/lib/appsignal/probes.rb +1 -1
  29. data/lib/appsignal/rack/abstract_middleware.rb +62 -28
  30. data/lib/appsignal/rack/event_handler.rb +37 -26
  31. data/lib/appsignal/rack/grape_middleware.rb +40 -0
  32. data/lib/appsignal/rack/hanami_middleware.rb +20 -0
  33. data/lib/appsignal/rack/rails_instrumentation.rb +14 -56
  34. data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
  35. data/lib/appsignal/utils.rb +1 -0
  36. data/lib/appsignal/version.rb +1 -1
  37. data/lib/appsignal.rb +34 -33
  38. data/spec/.rubocop.yml +1 -1
  39. data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
  40. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  41. data/spec/lib/appsignal/config_spec.rb +7 -5
  42. data/spec/lib/appsignal/demo_spec.rb +38 -41
  43. data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
  44. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
  45. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
  46. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
  47. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
  48. data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
  49. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
  50. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
  51. data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
  52. data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
  53. data/spec/lib/appsignal/hooks/rake_spec.rb +9 -19
  54. data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
  55. data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
  56. data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
  57. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
  58. data/spec/lib/appsignal/integrations/hanami_spec.rb +126 -64
  59. data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
  60. data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
  61. data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
  62. data/spec/lib/appsignal/integrations/padrino_spec.rb +47 -70
  63. data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
  64. data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
  65. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
  66. data/spec/lib/appsignal/integrations/sinatra_spec.rb +8 -3
  67. data/spec/lib/appsignal/integrations/webmachine_spec.rb +28 -39
  68. data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
  69. data/spec/lib/appsignal/probes_spec.rb +7 -4
  70. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +215 -106
  71. data/spec/lib/appsignal/rack/event_handler_spec.rb +151 -69
  72. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -12
  73. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
  74. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +36 -0
  75. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
  76. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
  77. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +68 -86
  78. data/spec/lib/appsignal/transaction_spec.rb +79 -93
  79. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
  80. data/spec/lib/appsignal_spec.rb +363 -342
  81. data/spec/support/hanami/hanami_app.rb +1 -3
  82. data/spec/support/helpers/dependency_helper.rb +6 -1
  83. data/spec/support/helpers/std_streams_helper.rb +1 -1
  84. data/spec/support/helpers/transaction_helpers.rb +8 -0
  85. data/spec/support/matchers/transaction.rb +185 -0
  86. data/spec/support/mocks/dummy_app.rb +20 -0
  87. data/spec/support/shared_examples/instrument.rb +17 -12
  88. data/spec/support/testing.rb +18 -9
  89. metadata +17 -10
  90. data/.semaphore/semaphore.yml +0 -2347
  91. data/script/lint_git +0 -22
  92. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
  93. data/spec/support/matchers/be_completed.rb +0 -5
  94. /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
@@ -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
- it "should do nothing when config is not set and there is no valid config in the env" do
25
- expect(Appsignal.internal_logger).to receive(:error)
26
- .with("Push API key not set after loading config").once
27
- expect(Appsignal.internal_logger).to receive(:error)
28
- .with("Not starting, no valid config for this environment").once
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
- expect(Appsignal.internal_logger).not_to receive(:error)
37
- silence { Appsignal.start }
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 "should should do nothing" do
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 "should resubscribe and start the extension" do
145
- expect(Appsignal).to receive(:start_logger)
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
- describe ".monitor_transaction" do
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
- it "should do nothing but still yield the block" do
237
- expect(Appsignal::Transaction).to_not receive(:create)
238
- expect(Appsignal).to_not receive(:instrument)
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
- expect(Appsignal.monitor_transaction("perform_job.nothing") do
242
+ Appsignal.monitor_transaction("perform_job.nothing") do
244
243
  object.some_method
245
- end).to eq 1
246
- end.to_not raise_error
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
- Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
258
- expect(log).to contains_log(
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
- it "does not record anything" do
269
- error = RuntimeError.new("specific error")
279
+ let(:error) { ExampleException.new("specific error") }
280
+
281
+ it "reraises the error" do
270
282
  expect do
271
- Appsignal.listen_for_error do
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
- it "should do nothing" do
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(RuntimeError.new)
282
- end.to_not raise_error
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
- it "should do nothing" do
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(RuntimeError.new)
290
- end.to_not raise_error
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 "should do nothing" do
296
- expect do
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 "should do nothing" do
304
- expect do
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
- let(:log_stream) { StringIO.new }
313
- let(:log) { log_contents(log_stream) }
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 "should instrument and complete for a background job" do
325
- expect(Appsignal).to receive(:instrument)
326
- .with("perform_job.something").and_yield
327
- expect(Appsignal::Transaction).to receive(:complete_current!)
328
- object = double
329
- expect(object).to receive(:some_method).and_return(1)
330
-
331
- expect(Appsignal.monitor_transaction(
332
- "perform_job.something",
333
- background_env_with_data
334
- ) do
335
- current = Appsignal::Transaction.current
336
- expect(current.namespace).to eq Appsignal::Transaction::BACKGROUND_JOB
337
- expect(current.request).to be_a(Appsignal::Transaction::GenericRequest)
338
- object.some_method
339
- end).to eq 1
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 "should instrument and complete for a http request" do
343
- expect(Appsignal).to receive(:instrument)
344
- .with("process_action.something").and_yield
345
- expect(Appsignal::Transaction).to receive(:complete_current!)
346
- object = double
347
- expect(object).to receive(:some_method)
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
- Appsignal.monitor_transaction(
350
- "process_action.something",
351
- http_request_env_with_data
352
- ) do
353
- current = Appsignal::Transaction.current
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
- Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
385
- expect(log).to contains_log(
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
- transaction_hash = transaction.to_h
411
- expect(transaction_hash).to include(
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
- transaction_hash = transaction.to_h
443
- expect(transaction_hash).to include(
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 transaction do
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
- expect(transaction.to_h).to include(
473
- "sample_data" => hash_including(
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 "should call set_tags on transaction" do
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 "should also listen to tag_job" do
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
- before { allow(Appsignal::Transaction).to receive(:current).and_return(transaction) }
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 "should call add_breadcrumb on transaction" do
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 "should not call add_breadcrumb on transaction" do
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("key", 10,
554
- Appsignal::Extension.data_map_new).and_raise(RangeError)
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
- expect do
558
- Appsignal.set_gauge("key", 10)
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
- expect do
638
- Appsignal.increment_counter("key", 10)
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
- expect do
668
- Appsignal.add_distribution_value("key", 10)
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(:transaction) do
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 { |example| keep_transactions { example.run } }
721
+ around do |example|
722
+ keep_transactions { example.run }
723
+ end
720
724
 
721
725
  it "sends the error to AppSignal" do
722
- expect(Appsignal::Transaction).to receive(:new).with(
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
- Appsignal.send_error(error)
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) { double }
737
+ let(:error) { "string value" }
736
738
 
737
739
  it "logs an error message" do
738
- expect(Appsignal.internal_logger).to receive(:error).with(
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(Appsignal::Transaction).to_not receive(:create)
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
- transaction = last_transaction
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
- transaction = last_transaction
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(captured_transaction.to_h).to include(
820
- "namespace" => "my_namespace",
821
- "action" => "my_action",
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
- expect(last_transaction.to_h).to include(
845
- "error" => {
846
- "name" => "ExampleException",
847
- "message" => "I am an exception",
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
- expect(last_transaction.to_h).to include(
868
- "error" => {
869
- "name" => "ExampleException",
870
- "message" => "I am an exception",
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
- expect(last_transaction.to_h).to include(
892
- "error" => {
893
- "name" => "ExampleException",
894
- "message" => "I am an exception",
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
- before { allow(Appsignal::Transaction).to receive(:current).and_return(transaction) }
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
- it "adds the error to the active transaction" do
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
- expect(Appsignal.internal_logger).to receive(:error).with(
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 "prints a deprecation warning and tags the transaction" do
942
- expect(transaction).to receive(:set_error).with(error)
943
- expect(transaction).to receive(:set_tags).with(tags)
944
- expect(transaction).to_not receive(:set_namespace)
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 "prints a deprecation warning andsets the namespace on the transaction" do
967
- expect(transaction).to receive(:set_error).with(error)
968
- expect(transaction).to_not receive(:set_tags)
969
- expect(transaction).to receive(:set_namespace).with(namespace)
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
- captured_transaction = nil
991
- keep_transactions do
992
- Appsignal.set_error(StandardError.new("my_error")) do |transaction|
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 eql(captured_transaction)
1000
- expect(captured_transaction.to_h).to include(
1001
- "namespace" => "my_namespace",
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
- before { allow(Appsignal::Transaction).to receive(:current).and_return(transaction) }
997
+ around { |example| keep_transactions { example.run } }
1026
998
 
1027
- it "should set the namespace to the current transaction" do
1028
- expect(transaction).to receive(:set_action).with("custom")
999
+ context "with current transaction" do
1000
+ before { set_current_transaction(transaction) }
1029
1001
 
1030
- Appsignal.set_action("custom")
1031
- end
1002
+ it "sets the namespace on the current transaction" do
1003
+ Appsignal.set_action("custom")
1032
1004
 
1033
- it "should do nothing if there is no current transaction" do
1034
- allow(Appsignal::Transaction).to receive(:current).and_return(nil)
1005
+ expect(transaction).to have_action("custom")
1006
+ end
1035
1007
 
1036
- expect(transaction).to_not receive(:set_action)
1008
+ it "does not set the action if the action is nil" do
1009
+ Appsignal.set_action(nil)
1037
1010
 
1038
- Appsignal.set_action("custom")
1011
+ expect(transaction).to_not have_action
1012
+ end
1039
1013
  end
1040
1014
 
1041
- it "should do nothing if the error is nil" do
1042
- expect(transaction).to_not receive(:set_action)
1015
+ context "without current transaction" do
1016
+ it "does not set ther action" do
1017
+ Appsignal.set_action("custom")
1043
1018
 
1044
- Appsignal.set_action(nil)
1019
+ expect(transaction).to_not have_action
1020
+ end
1045
1021
  end
1046
1022
  end
1047
1023
 
1048
1024
  describe ".set_namespace" do
1049
- before { allow(Appsignal::Transaction).to receive(:current).and_return(transaction) }
1025
+ around { |example| keep_transactions { example.run } }
1050
1026
 
1051
- it "should set the namespace to the current transaction" do
1052
- expect(transaction).to receive(:set_namespace).with("custom")
1027
+ context "with current transaction" do
1028
+ before { set_current_transaction(transaction) }
1053
1029
 
1054
- Appsignal.set_namespace("custom")
1055
- end
1030
+ it "should set the namespace to the current transaction" do
1031
+ Appsignal.set_namespace("custom")
1056
1032
 
1057
- it "should do nothing if there is no current transaction" do
1058
- allow(Appsignal::Transaction).to receive(:current).and_return(nil)
1033
+ expect(transaction).to have_namespace("custom")
1034
+ end
1059
1035
 
1060
- expect(transaction).to_not receive(:set_namespace)
1036
+ it "does not update the namespace if the namespace is nil" do
1037
+ Appsignal.set_namespace(nil)
1061
1038
 
1062
- Appsignal.set_namespace("custom")
1039
+ expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1040
+ end
1063
1041
  end
1064
1042
 
1065
- it "should do nothing if the error is nil" do
1066
- expect(transaction).to_not receive(:set_namespace)
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
- Appsignal.set_namespace(nil)
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 do
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
- before do
1084
- expect(Appsignal::Transaction).to receive(:current).at_least(:once)
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
- expect(transaction).to receive(:start_event)
1090
- expect(transaction).to receive(:finish_event)
1091
- .with("name", "title", "body", Appsignal::EventFormatter::SQL_BODY_FORMAT)
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
- it "does not record events on the transaction" do
1105
- expect(transaction).to receive(:pause!).and_call_original
1106
- expect(transaction).to receive(:resume!).and_call_original
1107
- Appsignal.instrument("register.this.event") { :do_nothing }
1108
- Appsignal.without_instrumentation do
1109
- Appsignal.instrument("dont.register.this.event") { :do_nothing }
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 "should not crash" do
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?(:@in_memory_log)
1136
- Appsignal.remove_instance_variable(:@in_memory_log)
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
- expect(Appsignal.in_memory_log.string).to_not be_empty
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.start_logger
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
- it "amends in memory log to log file" do
1170
- expect(log_file_contents).to include "[ERROR] appsignal: Log in memory"
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.in_memory_log.string).to be_empty
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.start_logger
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.in_memory_log.string).to be_empty
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.start_logger
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.start_logger
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.in_memory_log.string).to be_empty
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.start_logger
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.start_logger
1311
+ Appsignal._start_logger
1291
1312
  end
1292
1313
  end
1293
1314