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.
Files changed (89) 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 +38 -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 +1 -1
  17. data/lib/appsignal/integrations/grape.rb +19 -47
  18. data/lib/appsignal/integrations/hanami.rb +8 -7
  19. data/lib/appsignal/integrations/padrino.rb +46 -43
  20. data/lib/appsignal/integrations/railtie.rb +0 -3
  21. data/lib/appsignal/integrations/sinatra.rb +0 -1
  22. data/lib/appsignal/probes/gvl.rb +24 -2
  23. data/lib/appsignal/probes/sidekiq.rb +1 -1
  24. data/lib/appsignal/probes.rb +1 -1
  25. data/lib/appsignal/rack/abstract_middleware.rb +62 -28
  26. data/lib/appsignal/rack/event_handler.rb +12 -3
  27. data/lib/appsignal/rack/grape_middleware.rb +40 -0
  28. data/lib/appsignal/rack/hanami_middleware.rb +1 -11
  29. data/lib/appsignal/rack/rails_instrumentation.rb +14 -55
  30. data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
  31. data/lib/appsignal/utils.rb +1 -0
  32. data/lib/appsignal/version.rb +1 -1
  33. data/lib/appsignal.rb +34 -33
  34. data/spec/.rubocop.yml +1 -1
  35. data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
  36. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  37. data/spec/lib/appsignal/config_spec.rb +7 -5
  38. data/spec/lib/appsignal/demo_spec.rb +38 -41
  39. data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
  40. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
  41. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
  42. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
  43. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
  44. data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
  45. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
  46. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
  47. data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
  48. data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
  49. data/spec/lib/appsignal/hooks/rake_spec.rb +9 -19
  50. data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
  51. data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
  52. data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
  53. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
  54. data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
  55. data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
  56. data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
  57. data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
  58. data/spec/lib/appsignal/integrations/padrino_spec.rb +47 -70
  59. data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
  60. data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
  61. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
  62. data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -1
  63. data/spec/lib/appsignal/integrations/webmachine_spec.rb +28 -39
  64. data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
  65. data/spec/lib/appsignal/probes_spec.rb +7 -4
  66. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +215 -106
  67. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
  68. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -12
  69. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
  70. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
  71. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
  72. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
  73. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +68 -86
  74. data/spec/lib/appsignal/transaction_spec.rb +76 -90
  75. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
  76. data/spec/lib/appsignal_spec.rb +363 -342
  77. data/spec/support/helpers/dependency_helper.rb +6 -1
  78. data/spec/support/helpers/std_streams_helper.rb +1 -1
  79. data/spec/support/helpers/transaction_helpers.rb +8 -0
  80. data/spec/support/matchers/transaction.rb +185 -0
  81. data/spec/support/mocks/dummy_app.rb +20 -0
  82. data/spec/support/shared_examples/instrument.rb +17 -12
  83. data/spec/support/testing.rb +18 -9
  84. metadata +15 -10
  85. data/.semaphore/semaphore.yml +0 -2347
  86. data/script/lint_git +0 -22
  87. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
  88. data/spec/support/matchers/be_completed.rb +0 -5
  89. /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