appsignal 3.12.6-java → 4.0.0.beta.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +499 -487
  3. data/CHANGELOG.md +151 -0
  4. data/Rakefile +31 -7
  5. data/benchmark.rake +4 -6
  6. data/build_matrix.yml +45 -39
  7. data/ext/agent.rb +27 -27
  8. data/ext/appsignal_extension.c +25 -0
  9. data/gemfiles/rails-7.2.gemfile +11 -0
  10. data/lib/appsignal/check_in/cron.rb +67 -0
  11. data/lib/appsignal/check_in.rb +46 -0
  12. data/lib/appsignal/cli/diagnose.rb +37 -28
  13. data/lib/appsignal/cli/install.rb +5 -1
  14. data/lib/appsignal/config.rb +57 -119
  15. data/lib/appsignal/demo.rb +2 -2
  16. data/lib/appsignal/extension/jruby.rb +14 -0
  17. data/lib/appsignal/helpers/instrumentation.rb +139 -414
  18. data/lib/appsignal/helpers/metrics.rb +0 -16
  19. data/lib/appsignal/hooks/action_cable.rb +8 -8
  20. data/lib/appsignal/hooks/active_job.rb +2 -2
  21. data/lib/appsignal/hooks/at_exit.rb +37 -0
  22. data/lib/appsignal/hooks.rb +1 -16
  23. data/lib/appsignal/integrations/action_cable.rb +2 -2
  24. data/lib/appsignal/integrations/capistrano/appsignal.cap +2 -4
  25. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +1 -4
  26. data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -3
  27. data/lib/appsignal/integrations/http.rb +2 -7
  28. data/lib/appsignal/integrations/que.rb +2 -2
  29. data/lib/appsignal/integrations/railtie.rb +26 -59
  30. data/lib/appsignal/integrations/rake.rb +2 -2
  31. data/lib/appsignal/integrations/resque.rb +2 -2
  32. data/lib/appsignal/integrations/shoryuken.rb +4 -4
  33. data/lib/appsignal/integrations/sidekiq.rb +3 -3
  34. data/lib/appsignal/integrations/webmachine.rb +2 -2
  35. data/lib/appsignal/loaders.rb +1 -1
  36. data/lib/appsignal/probes.rb +0 -9
  37. data/lib/appsignal/rack/abstract_middleware.rb +4 -26
  38. data/lib/appsignal/rack/event_handler.rb +4 -4
  39. data/lib/appsignal/rack/rails_instrumentation.rb +1 -1
  40. data/lib/appsignal/rack.rb +0 -25
  41. data/lib/appsignal/sample_data.rb +95 -0
  42. data/lib/appsignal/transaction.rb +235 -361
  43. data/lib/appsignal/utils/rails_helper.rb +4 -0
  44. data/lib/appsignal/version.rb +1 -1
  45. data/lib/appsignal.rb +20 -62
  46. data/spec/lib/appsignal/auth_check_spec.rb +1 -1
  47. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  48. data/spec/lib/appsignal/capistrano3_spec.rb +53 -13
  49. data/spec/lib/appsignal/{heartbeat_spec.rb → check_in_spec.rb} +45 -36
  50. data/spec/lib/appsignal/cli/demo_spec.rb +7 -27
  51. data/spec/lib/appsignal/cli/diagnose_spec.rb +145 -110
  52. data/spec/lib/appsignal/config_spec.rb +304 -379
  53. data/spec/lib/appsignal/extension_install_failure_spec.rb +5 -1
  54. data/spec/lib/appsignal/extension_spec.rb +5 -1
  55. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
  56. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -2
  57. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +1 -0
  58. data/spec/lib/appsignal/hooks/activejob_spec.rb +7 -12
  59. data/spec/lib/appsignal/hooks/at_exit_spec.rb +72 -0
  60. data/spec/lib/appsignal/hooks/gvl_spec.rb +10 -5
  61. data/spec/lib/appsignal/hooks/http_spec.rb +3 -3
  62. data/spec/lib/appsignal/hooks/net_http_spec.rb +3 -3
  63. data/spec/lib/appsignal/hooks/rake_spec.rb +6 -9
  64. data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -10
  65. data/spec/lib/appsignal/hooks/redis_spec.rb +4 -7
  66. data/spec/lib/appsignal/hooks/resque_spec.rb +3 -5
  67. data/spec/lib/appsignal/hooks_spec.rb +0 -41
  68. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +29 -20
  69. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +4 -9
  70. data/spec/lib/appsignal/integrations/http_spec.rb +0 -21
  71. data/spec/lib/appsignal/integrations/railtie_spec.rb +179 -157
  72. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +3 -5
  73. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +48 -62
  74. data/spec/lib/appsignal/loaders/hanami_spec.rb +6 -9
  75. data/spec/lib/appsignal/loaders/padrino_spec.rb +6 -10
  76. data/spec/lib/appsignal/loaders/sinatra_spec.rb +6 -9
  77. data/spec/lib/appsignal/loaders_spec.rb +8 -1
  78. data/spec/lib/appsignal/marker_spec.rb +1 -1
  79. data/spec/lib/appsignal/probes_spec.rb +4 -83
  80. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +4 -63
  81. data/spec/lib/appsignal/rack/event_handler_spec.rb +18 -15
  82. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +3 -11
  83. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +4 -5
  84. data/spec/lib/appsignal/sample_data_spec.rb +174 -0
  85. data/spec/lib/appsignal/transaction_spec.rb +791 -1031
  86. data/spec/lib/appsignal/transmitter_spec.rb +6 -8
  87. data/spec/lib/appsignal_spec.rb +294 -643
  88. data/spec/spec_helper.rb +1 -3
  89. data/spec/support/fixtures/projects/valid/config/appsignal.yml +4 -7
  90. data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +16 -0
  91. data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +56 -0
  92. data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +5 -0
  93. data/spec/support/helpers/api_request_helper.rb +3 -2
  94. data/spec/support/helpers/config_helpers.rb +41 -11
  95. data/spec/support/helpers/dependency_helper.rb +8 -0
  96. data/spec/support/helpers/log_helpers.rb +1 -0
  97. data/spec/support/helpers/rails_helper.rb +6 -6
  98. data/spec/support/helpers/transaction_helpers.rb +2 -24
  99. data/spec/support/matchers/transaction.rb +3 -3
  100. data/spec/support/mocks/appsignal_mock.rb +3 -3
  101. data/spec/support/mocks/mock_probe.rb +2 -0
  102. data/spec/support/testing.rb +2 -2
  103. metadata +14 -23
  104. data/gemfiles/que_beta.gemfile +0 -5
  105. data/lib/appsignal/heartbeat.rb +0 -59
  106. data/lib/appsignal/helpers/heartbeats.rb +0 -44
  107. data/lib/appsignal/integrations/grape.rb +0 -35
  108. data/lib/appsignal/integrations/hanami.rb +0 -13
  109. data/lib/appsignal/integrations/padrino.rb +0 -13
  110. data/lib/appsignal/integrations/sinatra.rb +0 -13
  111. data/lib/appsignal/rack/generic_instrumentation.rb +0 -22
  112. data/lib/appsignal/rack/streaming_listener.rb +0 -28
  113. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -36
  114. data/spec/lib/appsignal/integrations/hanami_spec.rb +0 -17
  115. data/spec/lib/appsignal/integrations/padrino_spec.rb +0 -15
  116. data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -15
  117. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +0 -81
  118. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +0 -69
  119. data/spec/support/fixtures/projects/valid/config/environments/development.rb +0 -0
  120. data/spec/support/fixtures/projects/valid/config/environments/production.rb +0 -0
  121. data/spec/support/fixtures/projects/valid/config/environments/test.rb +0 -0
  122. data/spec/support/rails/my_app.rb +0 -6
  123. /data/spec/support/fixtures/projects/{valid/config/application.rb → valid_with_rails_app/log/.gitkeep} +0 -0
@@ -4,34 +4,6 @@ describe Appsignal do
4
4
 
5
5
  let(:transaction) { http_request_transaction }
6
6
 
7
- describe ".config=" do
8
- it "sets the config" do
9
- config = project_fixture_config
10
- expect(Appsignal.internal_logger).to_not receive(:level=)
11
-
12
- silence { Appsignal.config = config }
13
- expect(Appsignal.config).to eq config
14
- end
15
-
16
- it "prints a deprecation warning" do
17
- err_stream = std_stream
18
- capture_std_streams(std_stream, err_stream) do
19
- Appsignal.config = project_fixture_config
20
- end
21
- expect(err_stream.read).to include(
22
- "appsignal WARNING: Configuring AppSignal with `Appsignal.config=` is deprecated."
23
- )
24
- end
25
-
26
- it "logs a deprecation warning" do
27
- logs = capture_logs { silence { Appsignal.config = project_fixture_config } }
28
- expect(logs).to contains_log(
29
- :warn,
30
- "Configuring AppSignal with `Appsignal.config=` is deprecated."
31
- )
32
- end
33
- end
34
-
35
7
  describe ".configure" do
36
8
  context "when active" do
37
9
  it "doesn't update the config" do
@@ -62,11 +34,9 @@ describe Appsignal do
62
34
 
63
35
  context "with config but not started" do
64
36
  it "reuses the already loaded config if no env arg is given" do
65
- Appsignal._config = Appsignal::Config.new(
66
- project_fixture_path,
67
- :my_env,
68
- :ignore_actions => ["My action"]
69
- )
37
+ Appsignal.configure(:my_env, :root_path => project_fixture_path) do |config|
38
+ config.ignore_actions = ["My action"]
39
+ end
70
40
 
71
41
  Appsignal.configure do |config|
72
42
  expect(config.env).to eq("my_env")
@@ -76,6 +46,8 @@ describe Appsignal do
76
46
  config.name = "My app"
77
47
  config.push_api_key = "key"
78
48
  end
49
+ Appsignal.start
50
+
79
51
  expect(Appsignal.config.valid?).to be(true)
80
52
  expect(Appsignal.config.env).to eq("my_env")
81
53
  expect(Appsignal.config[:name]).to eq("My app")
@@ -84,11 +56,9 @@ describe Appsignal do
84
56
  end
85
57
 
86
58
  it "reuses the already loaded config if the env is the same" do
87
- Appsignal._config = Appsignal::Config.new(
88
- project_fixture_path,
89
- :my_env,
90
- :ignore_actions => ["My action"]
91
- )
59
+ Appsignal.configure(:my_env, :root_path => project_fixture_path) do |config|
60
+ config.ignore_actions = ["My action"]
61
+ end
92
62
 
93
63
  Appsignal.configure(:my_env) do |config|
94
64
  expect(config.ignore_actions).to eq(["My action"])
@@ -96,6 +66,8 @@ describe Appsignal do
96
66
  config.name = "My app"
97
67
  config.push_api_key = "key"
98
68
  end
69
+ Appsignal.start
70
+
99
71
  expect(Appsignal.config.valid?).to be(true)
100
72
  expect(Appsignal.config.env).to eq("my_env")
101
73
  expect(Appsignal.config[:active]).to be(true)
@@ -104,13 +76,11 @@ describe Appsignal do
104
76
  end
105
77
 
106
78
  it "loads a new config if the env is not the same" do
107
- Appsignal._config = Appsignal::Config.new(
108
- project_fixture_path,
109
- :my_env,
110
- :name => "Some name",
111
- :push_api_key => "Some key",
112
- :ignore_actions => ["My action"]
113
- )
79
+ Appsignal.configure(:my_env, :root_path => project_fixture_path) do |config|
80
+ config.name = "Some name"
81
+ config.push_api_key = "Some key"
82
+ config.ignore_actions = ["My action"]
83
+ end
114
84
 
115
85
  Appsignal.configure(:my_env2) do |config|
116
86
  expect(config.ignore_actions).to be_empty
@@ -118,6 +88,8 @@ describe Appsignal do
118
88
  config.name = "My app"
119
89
  config.push_api_key = "key"
120
90
  end
91
+ Appsignal.start
92
+
121
93
  expect(Appsignal.config.valid?).to be(true)
122
94
  expect(Appsignal.config.env).to eq("my_env2")
123
95
  expect(Appsignal.config[:active]).to be(true)
@@ -126,13 +98,11 @@ describe Appsignal do
126
98
  end
127
99
 
128
100
  it "loads a new config if the path is not the same" do
129
- Appsignal._config = Appsignal::Config.new(
130
- "/some/path",
131
- :my_env,
132
- :name => "Some name",
133
- :push_api_key => "Some key",
134
- :ignore_actions => ["My action"]
135
- )
101
+ Appsignal.configure(:my_env, :root_path => "/some/path") do |config|
102
+ config.name = "Some name"
103
+ config.push_api_key = "Some key"
104
+ config.ignore_actions = ["My action"]
105
+ end
136
106
 
137
107
  Appsignal.configure(:my_env, :root_path => project_fixture_path) do |config|
138
108
  expect(config.ignore_actions).to be_empty
@@ -140,6 +110,8 @@ describe Appsignal do
140
110
  config.name = "My app"
141
111
  config.push_api_key = "key"
142
112
  end
113
+ Appsignal.start
114
+
143
115
  expect(Appsignal.config.valid?).to be(true)
144
116
  expect(Appsignal.config.env).to eq("my_env")
145
117
  expect(Appsignal.config[:active]).to be(true)
@@ -161,6 +133,8 @@ describe Appsignal do
161
133
  config.name = "My app"
162
134
  config.push_api_key = "key"
163
135
  end
136
+ Appsignal.start
137
+
164
138
  expect(Appsignal.config.valid?).to be(true)
165
139
  expect(Appsignal.config.env).to eq("my_env")
166
140
  expect(Appsignal.config[:active]).to be(true)
@@ -174,23 +148,23 @@ describe Appsignal do
174
148
  Appsignal.configure(:test) do |config|
175
149
  config.push_api_key = "key"
176
150
  end
177
-
178
151
  Appsignal.start
152
+
179
153
  expect(Appsignal.config[:push_api_key]).to eq("key")
180
154
  end
181
155
 
182
156
  it "uses the given env" do
183
157
  ENV["APPSIGNAL_APP_ENV"] = "env_env"
184
158
  Appsignal.configure(:env_arg)
185
-
186
159
  Appsignal.start
160
+
187
161
  expect(Appsignal.config.env).to eq("env_arg")
188
162
  end
189
163
 
190
164
  it "uses the given root path to read the config file" do
191
165
  Appsignal.configure(:test, :root_path => project_fixture_path)
192
-
193
166
  Appsignal.start
167
+
194
168
  expect(Appsignal.config.env).to eq("test")
195
169
  expect(Appsignal.config[:push_api_key]).to eq("abc")
196
170
  # Ensure it loads from the config file in the given path
@@ -201,6 +175,7 @@ describe Appsignal do
201
175
  Dir.chdir project_fixture_path do
202
176
  Appsignal.configure(:test)
203
177
  end
178
+ Appsignal.start
204
179
 
205
180
  expect(Appsignal.config.env).to eq("test")
206
181
  expect(Appsignal.config[:push_api_key]).to eq("abc")
@@ -212,6 +187,7 @@ describe Appsignal do
212
187
  Appsignal.configure(:test) do |config|
213
188
  config.push_api_key = "key"
214
189
  end
190
+ Appsignal.start
215
191
 
216
192
  expect(Appsignal.config.valid?).to be(true)
217
193
  expect(Appsignal.config.env).to eq("test")
@@ -238,6 +214,7 @@ describe Appsignal do
238
214
  Appsignal.configure(:my_env) do |config|
239
215
  config.push_api_key = "key"
240
216
  end
217
+ Appsignal.start
241
218
 
242
219
  expect(Appsignal.config.valid?).to be(true)
243
220
  end
@@ -246,6 +223,7 @@ describe Appsignal do
246
223
  Appsignal.configure(:my_env) do |config|
247
224
  config.push_api_key = ""
248
225
  end
226
+ Appsignal.start
249
227
 
250
228
  expect(Appsignal.config.valid?).to be(false)
251
229
  end
@@ -398,7 +376,7 @@ describe Appsignal do
398
376
  end
399
377
 
400
378
  context "when config is loaded" do
401
- before { Appsignal._config = project_fixture_config }
379
+ before { Appsignal.configure(:production, :root_path => project_fixture_path) }
402
380
 
403
381
  it "should initialize logging" do
404
382
  Appsignal.start
@@ -410,6 +388,27 @@ describe Appsignal do
410
388
  Appsignal.start
411
389
  end
412
390
 
391
+ it "freezes the config" do
392
+ Appsignal.start
393
+
394
+ expect_frozen_error do
395
+ Appsignal.config[:ignore_actions] << "my action"
396
+ end
397
+ expect_frozen_error do
398
+ Appsignal.config.config_hash[:ignore_actions] << "my action"
399
+ end
400
+ expect_frozen_error do
401
+ Appsignal.config.config_hash.merge!(:option => :value)
402
+ end
403
+ expect_frozen_error do
404
+ Appsignal.config[:ignore_actions] = "my action"
405
+ end
406
+ end
407
+
408
+ def expect_frozen_error(&block)
409
+ expect(&block).to raise_error(FrozenError)
410
+ end
411
+
413
412
  context "when allocation tracking has been enabled" do
414
413
  before do
415
414
  Appsignal.config.config_hash[:enable_allocation_tracking] = true
@@ -496,8 +495,21 @@ describe Appsignal do
496
495
  end
497
496
  end
498
497
 
498
+ context "when already started" do
499
+ it "doesn't start again" do
500
+ start_agent
501
+
502
+ expect(Appsignal::Extension).to_not receive(:start)
503
+ logs = capture_logs { Appsignal.start }
504
+ expect(logs).to contains_log(
505
+ :warn,
506
+ "Ignoring call to Appsignal.start after AppSignal has started"
507
+ )
508
+ end
509
+ end
510
+
499
511
  context "with debug logging" do
500
- before { Appsignal._config = project_fixture_config("test") }
512
+ before { Appsignal.configure(:test, :root_path => project_fixture_path) }
501
513
 
502
514
  it "should change the log level" do
503
515
  Appsignal.start
@@ -533,7 +545,8 @@ describe Appsignal do
533
545
 
534
546
  context "when active" do
535
547
  before do
536
- Appsignal._config = project_fixture_config
548
+ Appsignal.configure(:production, :root_path => project_fixture_path)
549
+ Appsignal.start
537
550
  end
538
551
 
539
552
  it "starts the logger and extension" do
@@ -580,9 +593,7 @@ describe Appsignal do
580
593
  end
581
594
 
582
595
  context "when started with inactive config" do
583
- before do
584
- Appsignal._config = project_fixture_config("nonsense")
585
- end
596
+ before { Appsignal.configure(:nonsense, :root_path => project_fixture_path) }
586
597
 
587
598
  it { is_expected.to be_falsy }
588
599
  end
@@ -597,7 +608,8 @@ describe Appsignal do
597
608
 
598
609
  context "with inactive config" do
599
610
  before do
600
- Appsignal._config = project_fixture_config("nonsense")
611
+ Appsignal.configure(:nonsense, :root_path => project_fixture_path)
612
+ Appsignal.start
601
613
  end
602
614
 
603
615
  it { is_expected.to be_falsy }
@@ -605,7 +617,8 @@ describe Appsignal do
605
617
 
606
618
  context "with active config" do
607
619
  before do
608
- Appsignal._config = project_fixture_config
620
+ Appsignal.configure(:production, :root_path => project_fixture_path)
621
+ Appsignal.start
609
622
  end
610
623
 
611
624
  it { is_expected.to be_truthy }
@@ -631,65 +644,9 @@ describe Appsignal do
631
644
  end
632
645
 
633
646
  context "not active" do
634
- before { Appsignal._config = project_fixture_config("not_active") }
635
-
636
- describe ".monitor_transaction" do
637
- it "does not create a transaction" do
638
- object = double(:some_method => 1)
639
-
640
- expect do
641
- Appsignal.monitor_transaction("perform_job.nothing") do
642
- object.some_method
643
- end
644
- end.to_not(change { created_transactions.count })
645
- end
646
-
647
- it "returns the block's return value" do
648
- object = double(:some_method => 1)
649
-
650
- return_value = Appsignal.monitor_transaction("perform_job.nothing") do
651
- object.some_method
652
- end
653
- expect(return_value).to eq 1
654
- end
655
-
656
- context "with an unknown event type" do
657
- it "yields the given block" do
658
- expect do |blk|
659
- Appsignal.monitor_transaction("unknown.sidekiq", &blk)
660
- end.to yield_control
661
- end
662
-
663
- it "logs an error" do
664
- logs =
665
- capture_logs do
666
- Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
667
- end
668
- expect(logs).to contains_log(
669
- :error,
670
- "Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
671
- "(for jobs and tasks) or 'process_action' (for HTTP requests)"
672
- )
673
- end
674
- end
675
- end
676
-
677
- describe ".listen_for_error" do
678
- let(:error) { ExampleException.new("specific error") }
679
-
680
- it "reraises the error" do
681
- expect do
682
- Appsignal.listen_for_error { raise error }
683
- end.to raise_error(error)
684
- end
685
-
686
- it "does not create a transaction" do
687
- expect do
688
- expect do
689
- Appsignal.listen_for_error { raise error }
690
- end.to raise_error(error)
691
- end.to_not(change { created_transactions.count })
692
- end
647
+ before do
648
+ Appsignal.configure(:not_active, :root_path => project_fixture_path)
649
+ Appsignal.start
693
650
  end
694
651
 
695
652
  describe ".send_error" do
@@ -852,7 +809,7 @@ describe Appsignal do
852
809
  end
853
810
  end.to_not(change { created_transactions.count })
854
811
 
855
- warning = "An active transaction around this 'Appsignal.monitor' call."
812
+ warning = "A transaction is active around this 'Appsignal.monitor' call."
856
813
  expect(logs).to contains_log(:warn, warning)
857
814
  expect(stderr).to include("appsignal WARNING: #{warning}")
858
815
  end
@@ -897,211 +854,6 @@ describe Appsignal do
897
854
  end
898
855
  end
899
856
 
900
- describe ".monitor_transaction" do
901
- it "prints a deprecation warning" do
902
- err_stream = std_stream
903
- capture_std_streams(std_stream, err_stream) do
904
- Appsignal.monitor_transaction(
905
- "perform_job.something",
906
- :class => "BackgroundJob",
907
- :method => "perform"
908
- ) do
909
- :return_value
910
- end
911
- end
912
-
913
- expect(err_stream.read).to include(
914
- "appsignal WARNING: The `Appsignal.monitor_transaction` helper is deprecated."
915
- )
916
- end
917
-
918
- it "logs a deprecation warning" do
919
- logs =
920
- capture_logs do
921
- silence do
922
- Appsignal.monitor_transaction(
923
- "perform_job.something",
924
- :class => "BackgroundJob",
925
- :method => "perform"
926
- ) do
927
- :return_value
928
- end
929
- end
930
- end
931
-
932
- expect(logs).to contains_log(
933
- :warn,
934
- "The `Appsignal.monitor_transaction` helper is deprecated."
935
- )
936
- end
937
-
938
- context "with a successful call" do
939
- it "instruments and completes for a background job" do
940
- return_value = nil
941
- expect do
942
- return_value =
943
- Appsignal.monitor_transaction(
944
- "perform_job.something",
945
- {
946
- :class => "BackgroundJob",
947
- :method => "perform",
948
- :queue_start => fixed_time.to_i
949
- }
950
- ) do
951
- :return_value
952
- end
953
- end.to(change { created_transactions.count }.by(1))
954
- expect(return_value).to eq(:return_value)
955
-
956
- transaction = last_transaction
957
- expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
958
- expect(transaction).to have_action("BackgroundJob#perform")
959
- expect(transaction).to include_event("name" => "perform_job.something")
960
- expect(transaction).to have_queue_start(1_389_783_600_000)
961
- expect(transaction).to be_completed
962
- end
963
-
964
- it "instruments and completes for a http request" do
965
- return_value = nil
966
- expect do
967
- return_value =
968
- Appsignal.monitor_transaction(
969
- "process_action.something",
970
- {
971
- :controller => "BlogPostsController",
972
- :action => "show",
973
- "HTTP_X_REQUEST_START" => "t=#{fixed_time.to_i * 1000}"
974
- }
975
- ) do
976
- :return_value
977
- end
978
- end.to(change { created_transactions.count }.by(1))
979
- expect(return_value).to eq(:return_value)
980
-
981
- transaction = last_transaction
982
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
983
- expect(transaction).to have_action("BlogPostsController#show")
984
- expect(transaction).to include_event("name" => "process_action.something")
985
- expect(transaction).to have_queue_start(1_389_783_600_000)
986
- expect(transaction).to be_completed
987
- end
988
- end
989
-
990
- context "with an erroring call" do
991
- let(:error) { ExampleException.new("error message") }
992
-
993
- it "adds the error to the current transaction and complete" do
994
- expect do
995
- Appsignal.monitor_transaction("perform_job.something") do
996
- raise error
997
- end
998
- end.to raise_error(error)
999
-
1000
- expect(last_transaction).to have_error("ExampleException", "error message")
1001
- expect(last_transaction).to be_completed
1002
- end
1003
- end
1004
-
1005
- context "with an unknown event type" do
1006
- it "yields the given block" do
1007
- expect do |blk|
1008
- Appsignal.monitor_transaction("unknown.sidekiq", &blk)
1009
- end.to yield_control
1010
- end
1011
-
1012
- it "logs an error" do
1013
- logs =
1014
- capture_logs do
1015
- Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
1016
- end
1017
- expect(logs).to contains_log(
1018
- :error,
1019
- "Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
1020
- "(for jobs and tasks) or 'process_action' (for HTTP requests)"
1021
- )
1022
- end
1023
- end
1024
- end
1025
-
1026
- describe ".monitor_single_transaction" do
1027
- it "prints a deprecation warning" do
1028
- err_stream = std_stream
1029
- capture_std_streams(std_stream, err_stream) do
1030
- Appsignal.monitor_single_transaction(
1031
- "perform_job.something",
1032
- :class => "BackgroundJob",
1033
- :method => "perform"
1034
- ) do
1035
- :return_value
1036
- end
1037
- end
1038
-
1039
- expect(err_stream.read).to include(
1040
- "appsignal WARNING: The `Appsignal.monitor_single_transaction` helper is deprecated."
1041
- )
1042
- end
1043
-
1044
- it "logs a deprecation warning" do
1045
- logs =
1046
- capture_logs do
1047
- silence do
1048
- Appsignal.monitor_single_transaction(
1049
- "perform_job.something",
1050
- :class => "BackgroundJob",
1051
- :method => "perform"
1052
- ) do
1053
- :return_value
1054
- end
1055
- end
1056
- end
1057
-
1058
- expect(logs).to contains_log(
1059
- :warn,
1060
- "The `Appsignal.monitor_single_transaction` helper is deprecated."
1061
- )
1062
- end
1063
-
1064
- context "with a successful call" do
1065
- it "calls monitor_transaction and Appsignal.stop" do
1066
- expect(Appsignal).to receive(:stop)
1067
-
1068
- Appsignal.monitor_single_transaction(
1069
- "perform_job.something",
1070
- :controller => :my_controller,
1071
- :action => :my_action
1072
- ) do
1073
- # nothing
1074
- end
1075
-
1076
- transaction = last_transaction
1077
- expect(transaction).to have_action("my_controller#my_action")
1078
- expect(transaction).to include_event("name" => "perform_job.something")
1079
- end
1080
- end
1081
-
1082
- context "with an erroring call" do
1083
- let(:error) { ExampleException.new }
1084
-
1085
- it "calls monitor_transaction and stop and re-raises the error" do
1086
- expect(Appsignal).to receive(:stop)
1087
-
1088
- expect do
1089
- Appsignal.monitor_single_transaction(
1090
- "perform_job.something",
1091
- :controller => :my_controller,
1092
- :action => :my_action
1093
- ) do
1094
- raise error
1095
- end
1096
- end.to raise_error(error)
1097
-
1098
- transaction = last_transaction
1099
- expect(transaction).to have_action("my_controller#my_action")
1100
- expect(transaction).to include_event("name" => "perform_job.something")
1101
- end
1102
- end
1103
- end
1104
-
1105
857
  describe ".tag_request" do
1106
858
  before { start_agent }
1107
859
 
@@ -1137,30 +889,37 @@ describe Appsignal do
1137
889
  end
1138
890
  end
1139
891
 
1140
- describe ".set_params" do
892
+ describe ".add_params" do
1141
893
  before { start_agent }
1142
894
 
895
+ it "has a .set_params alias" do
896
+ expect(Appsignal.method(:add_params)).to eq(Appsignal.method(:set_params))
897
+ end
898
+
1143
899
  context "with transaction" do
1144
900
  let(:transaction) { http_request_transaction }
1145
901
  before { set_current_transaction(transaction) }
1146
902
 
1147
- it "sets parameters on the transaction" do
1148
- Appsignal.set_params("param1" => "value1")
903
+ it "adds parameters to the transaction" do
904
+ Appsignal.add_params("param1" => "value1")
1149
905
 
1150
906
  transaction._sample
1151
907
  expect(transaction).to include_params("param1" => "value1")
1152
908
  end
1153
909
 
1154
- it "overwrites the params if called multiple times" do
1155
- Appsignal.set_params("param1" => "value1")
1156
- Appsignal.set_params("param2" => "value2")
910
+ it "merges the params if called multiple times" do
911
+ Appsignal.add_params("param1" => "value1")
912
+ Appsignal.add_params("param2" => "value2")
1157
913
 
1158
914
  transaction._sample
1159
- expect(transaction).to include_params("param2" => "value2")
915
+ expect(transaction).to include_params(
916
+ "param1" => "value1",
917
+ "param2" => "value2"
918
+ )
1160
919
  end
1161
920
 
1162
- it "sets parameters with a block on the transaction" do
1163
- Appsignal.set_params { { "param1" => "value1" } }
921
+ it "adds parameters with a block to the transaction" do
922
+ Appsignal.add_params { { "param1" => "value1" } }
1164
923
 
1165
924
  transaction._sample
1166
925
  expect(transaction).to include_params("param1" => "value1")
@@ -1168,37 +927,44 @@ describe Appsignal do
1168
927
  end
1169
928
 
1170
929
  context "without transaction" do
1171
- it "does not set tags on the transaction" do
1172
- Appsignal.set_params("a" => "b")
930
+ it "does not add tags to any transaction" do
931
+ Appsignal.add_params("a" => "b")
1173
932
 
1174
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_params)
933
+ expect_any_instance_of(Appsignal::Transaction).to_not receive(:add_params)
1175
934
  end
1176
935
  end
1177
936
  end
1178
937
 
1179
- describe ".set_session_data" do
938
+ describe ".add_session_data" do
1180
939
  before { start_agent }
1181
940
 
941
+ it "has a .set_session_data alias" do
942
+ expect(Appsignal.method(:add_session_data)).to eq(Appsignal.method(:set_session_data))
943
+ end
944
+
1182
945
  context "with transaction" do
1183
946
  let(:transaction) { http_request_transaction }
1184
947
  before { set_current_transaction(transaction) }
1185
948
 
1186
- it "sets session data on the transaction" do
1187
- Appsignal.set_session_data("data" => "value1")
949
+ it "adds session data to the transaction" do
950
+ Appsignal.add_session_data("data" => "value1")
1188
951
 
1189
952
  transaction._sample
1190
953
  expect(transaction).to include_session_data("data" => "value1")
1191
954
  end
1192
955
 
1193
- it "overwrites the session data if called multiple times" do
1194
- Appsignal.set_session_data("data" => "value1")
1195
- Appsignal.set_session_data("data" => "value2")
956
+ it "merges the session data if called multiple times" do
957
+ Appsignal.set_session_data("data1" => "value1")
958
+ Appsignal.set_session_data("data2" => "value2")
1196
959
 
1197
960
  transaction._sample
1198
- expect(transaction).to include_session_data("data" => "value2")
961
+ expect(transaction).to include_session_data(
962
+ "data1" => "value1",
963
+ "data2" => "value2"
964
+ )
1199
965
  end
1200
966
 
1201
- it "sets session data with a block on the transaction" do
967
+ it "adds session data with a block to the transaction" do
1202
968
  Appsignal.set_session_data { { "data" => "value1" } }
1203
969
 
1204
970
  transaction._sample
@@ -1207,38 +973,45 @@ describe Appsignal do
1207
973
  end
1208
974
 
1209
975
  context "without transaction" do
1210
- it "does not set session data on the transaction" do
976
+ it "does not add session data to any transaction" do
1211
977
  Appsignal.set_session_data("a" => "b")
1212
978
 
1213
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_session_data)
979
+ expect_any_instance_of(Appsignal::Transaction).to_not receive(:add_session_data)
1214
980
  end
1215
981
  end
1216
982
  end
1217
983
 
1218
- describe ".set_headers" do
984
+ describe ".add_headers" do
1219
985
  before { start_agent }
1220
986
 
987
+ it "has a .set_headers alias" do
988
+ expect(Appsignal.method(:add_headers)).to eq(Appsignal.method(:set_headers))
989
+ end
990
+
1221
991
  context "with transaction" do
1222
992
  let(:transaction) { http_request_transaction }
1223
993
  before { set_current_transaction(transaction) }
1224
994
 
1225
- it "sets request headers on the transaction" do
1226
- Appsignal.set_headers("PATH_INFO" => "/some-path")
995
+ it "adds request headers to the transaction" do
996
+ Appsignal.add_headers("PATH_INFO" => "/some-path")
1227
997
 
1228
998
  transaction._sample
1229
999
  expect(transaction).to include_environment("PATH_INFO" => "/some-path")
1230
1000
  end
1231
1001
 
1232
- it "overwrites the request headers if called multiple times" do
1233
- Appsignal.set_headers("PATH_INFO" => "/some-path1")
1234
- Appsignal.set_headers("PATH_INFO" => "/some-path2")
1002
+ it "merges the request headers if called multiple times" do
1003
+ Appsignal.add_headers("PATH_INFO" => "/some-path")
1004
+ Appsignal.add_headers("REQUEST_METHOD" => "GET")
1235
1005
 
1236
1006
  transaction._sample
1237
- expect(transaction).to include_environment("PATH_INFO" => "/some-path2")
1007
+ expect(transaction).to include_environment(
1008
+ "PATH_INFO" => "/some-path",
1009
+ "REQUEST_METHOD" => "GET"
1010
+ )
1238
1011
  end
1239
1012
 
1240
- it "sets request headers with a block on the transaction" do
1241
- Appsignal.set_headers { { "PATH_INFO" => "/some-path" } }
1013
+ it "adds request headers with a block to the transaction" do
1014
+ Appsignal.add_headers { { "PATH_INFO" => "/some-path" } }
1242
1015
 
1243
1016
  transaction._sample
1244
1017
  expect(transaction).to include_environment("PATH_INFO" => "/some-path")
@@ -1246,23 +1019,27 @@ describe Appsignal do
1246
1019
  end
1247
1020
 
1248
1021
  context "without transaction" do
1249
- it "does not set request headers on the transaction" do
1250
- Appsignal.set_headers("PATH_INFO" => "/some-path")
1022
+ it "does not add request headers to any transaction" do
1023
+ Appsignal.add_headers("PATH_INFO" => "/some-path")
1251
1024
 
1252
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_headers)
1025
+ expect_any_instance_of(Appsignal::Transaction).to_not receive(:add_headers)
1253
1026
  end
1254
1027
  end
1255
1028
  end
1256
1029
 
1257
- describe ".set_custom_data" do
1030
+ describe ".add_custom_data" do
1258
1031
  before { start_agent }
1259
1032
 
1033
+ it "has a .set_custom_data alias" do
1034
+ expect(Appsignal.method(:add_custom_data)).to eq(Appsignal.method(:set_custom_data))
1035
+ end
1036
+
1260
1037
  context "with transaction" do
1261
1038
  let(:transaction) { http_request_transaction }
1262
1039
  before { set_current_transaction transaction }
1263
1040
 
1264
- it "sets custom data on the current transaction" do
1265
- Appsignal.set_custom_data(
1041
+ it "adds custom data to the current transaction" do
1042
+ Appsignal.add_custom_data(
1266
1043
  :user => { :id => 123 },
1267
1044
  :organization => { :slug => "appsignal" }
1268
1045
  )
@@ -1273,16 +1050,27 @@ describe Appsignal do
1273
1050
  "organization" => { "slug" => "appsignal" }
1274
1051
  )
1275
1052
  end
1053
+
1054
+ it "merges the custom data if called multiple times" do
1055
+ Appsignal.add_custom_data(:abc => "value")
1056
+ Appsignal.add_custom_data(:def => "value")
1057
+
1058
+ transaction._sample
1059
+ expect(transaction).to include_custom_data(
1060
+ "abc" => "value",
1061
+ "def" => "value"
1062
+ )
1063
+ end
1276
1064
  end
1277
1065
 
1278
1066
  context "without transaction" do
1279
- it "does not set tags on the transaction" do
1280
- Appsignal.set_custom_data(
1067
+ it "does not add tags any the transaction" do
1068
+ Appsignal.add_custom_data(
1281
1069
  :user => { :id => 123 },
1282
1070
  :organization => { :slug => "appsignal" }
1283
1071
  )
1284
1072
 
1285
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_custom_data)
1073
+ expect_any_instance_of(Appsignal::Transaction).to_not receive(:add_custom_data)
1286
1074
  end
1287
1075
  end
1288
1076
  end
@@ -1323,7 +1111,7 @@ describe Appsignal do
1323
1111
  end
1324
1112
  end
1325
1113
 
1326
- describe "custom stats" do
1114
+ describe "custom metrics" do
1327
1115
  let(:tags) { { :foo => "bar" } }
1328
1116
 
1329
1117
  describe ".set_gauge" do
@@ -1358,50 +1146,6 @@ describe Appsignal do
1358
1146
  end
1359
1147
  end
1360
1148
 
1361
- describe ".set_host_gauge" do
1362
- let(:err_stream) { std_stream }
1363
- let(:stderr) { err_stream.read }
1364
- let(:log_stream) { StringIO.new }
1365
- let(:logs) { log_contents(log_stream) }
1366
- let(:deprecation_message) do
1367
- "The `set_host_gauge` method has been deprecated. " \
1368
- "Calling this method has no effect. " \
1369
- "Please remove method call in the following file to remove " \
1370
- "this message."
1371
- end
1372
- before do
1373
- Appsignal.internal_logger = test_logger(log_stream)
1374
- capture_std_streams(std_stream, err_stream) { Appsignal.set_host_gauge("key", 0.1) }
1375
- end
1376
-
1377
- it "logs a deprecation warning" do
1378
- expect(stderr).to include("appsignal WARNING: #{deprecation_message}")
1379
- expect(logs).to include(deprecation_message)
1380
- end
1381
- end
1382
-
1383
- describe ".set_process_gauge" do
1384
- let(:err_stream) { std_stream }
1385
- let(:stderr) { err_stream.read }
1386
- let(:log_stream) { StringIO.new }
1387
- let(:logs) { log_contents(log_stream) }
1388
- let(:deprecation_message) do
1389
- "The `set_process_gauge` method has been deprecated. " \
1390
- "Calling this method has no effect. " \
1391
- "Please remove method call in the following file to remove " \
1392
- "this message."
1393
- end
1394
- before do
1395
- Appsignal.internal_logger = test_logger(log_stream)
1396
- capture_std_streams(std_stream, err_stream) { Appsignal.set_process_gauge("key", 0.1) }
1397
- end
1398
-
1399
- it "logs a deprecation warning" do
1400
- expect(stderr).to include("appsignal WARNING: #{deprecation_message}")
1401
- expect(logs).to include(deprecation_message)
1402
- end
1403
- end
1404
-
1405
1149
  describe ".increment_counter" do
1406
1150
  it "should call increment_counter on the extension with a string key" do
1407
1151
  expect(Appsignal::Extension).to receive(:increment_counter)
@@ -1537,138 +1281,52 @@ describe Appsignal do
1537
1281
  end
1538
1282
  end
1539
1283
 
1540
- context "with tags" do
1541
- let(:tags) { { :a => "a", :b => "b" } }
1542
-
1543
- it "prints a deprecation warning and tags the transaction" do
1544
- logs = capture_logs do
1545
- expect do
1546
- capture_std_streams(std_stream, err_stream) do
1547
- Appsignal.send_error(error, tags)
1548
- end
1549
- end.to change { created_transactions.count }.by(1)
1284
+ context "when given a block" do
1285
+ it "yields the transaction and allows additional metadata to be set" do
1286
+ Appsignal.send_error(StandardError.new("my_error")) do |transaction|
1287
+ transaction.set_action("my_action")
1288
+ transaction.set_namespace("my_namespace")
1550
1289
  end
1551
1290
 
1552
- expect(last_transaction).to include_tags("a" => "a", "b" => "b")
1553
-
1554
- message = "The tags argument for `Appsignal.send_error` is deprecated. " \
1555
- "Please use the block method to set tags instead.\n\n" \
1556
- " Appsignal.send_error(error) do |transaction|\n" \
1557
- " transaction.set_tags(#{tags.inspect})\n" \
1558
- " end\n\n" \
1559
- "Appsignal.send_error called on location: #{__FILE__}:"
1560
- expect(stderr).to include("appsignal WARNING: #{message}")
1561
- expect(logs).to include(message)
1291
+ expect(last_transaction).to have_namespace("my_namespace")
1292
+ expect(last_transaction).to have_action("my_action")
1293
+ expect(last_transaction).to have_error("StandardError", "my_error")
1562
1294
  end
1563
- end
1564
-
1565
- context "with namespace" do
1566
- let(:namespace) { "admin" }
1567
1295
 
1568
- it "prints a deprecation warning and sets the namespace on the transaction" do
1569
- logs = capture_logs do
1570
- expect do
1571
- capture_std_streams(std_stream, err_stream) do
1572
- Appsignal.send_error(error, nil, namespace)
1573
- end
1574
- end.to change { created_transactions.count }.by(1)
1296
+ it "yields and allows additional metadata to be set with global helpers" do
1297
+ Appsignal.send_error(StandardError.new("my_error")) do
1298
+ Appsignal.set_action("my_action")
1299
+ Appsignal.set_namespace("my_namespace")
1575
1300
  end
1576
1301
 
1577
- expect(last_transaction).to have_namespace(namespace)
1578
-
1579
- message = "The namespace argument for `Appsignal.send_error` is deprecated. " \
1580
- "Please use the block method to set the namespace instead.\n\n" \
1581
- " Appsignal.send_error(error) do |transaction|\n" \
1582
- " transaction.set_namespace(#{namespace.inspect})\n" \
1583
- " end\n\n" \
1584
- "Appsignal.send_error called on location: #{__FILE__}:"
1585
- expect(stderr).to include("appsignal WARNING: #{message}")
1586
- expect(logs).to include(message)
1587
- end
1588
- end
1589
-
1590
- context "when given a block" do
1591
- it "yields the transaction and allows additional metadata to be set" do
1592
- keep_transactions do
1593
- Appsignal.send_error(StandardError.new("my_error")) do |transaction|
1594
- transaction.set_action("my_action")
1595
- transaction.set_namespace("my_namespace")
1596
- end
1597
- end
1598
1302
  expect(last_transaction).to have_namespace("my_namespace")
1599
1303
  expect(last_transaction).to have_action("my_action")
1600
1304
  expect(last_transaction).to have_error("StandardError", "my_error")
1601
1305
  end
1602
- end
1603
- end
1604
1306
 
1605
- describe ".listen_for_error" do
1606
- around { |example| keep_transactions { example.run } }
1307
+ it "yields to set metadata and doesn't modify the active transaction" do
1308
+ active_transaction = http_request_transaction
1309
+ active_transaction.set_action("active action")
1310
+ active_transaction.set_namespace("active namespace")
1311
+ set_current_transaction(active_transaction)
1312
+ expect(current_transaction).to eq(active_transaction)
1607
1313
 
1608
- it "prints and logs a deprecation warning" do
1609
- err_stream = std_stream
1610
- logs =
1611
- capture_logs do
1612
- capture_std_streams(std_stream, err_stream) do
1613
- Appsignal.listen_for_error do
1614
- # Do nothing
1615
- end
1616
- end
1314
+ Appsignal.send_error(StandardError.new("my_error")) do
1315
+ Appsignal.set_action("my_action")
1316
+ Appsignal.set_namespace("my_namespace")
1617
1317
  end
1618
- expect(err_stream.read)
1619
- .to include("appsignal WARNING: The `Appsignal.listen_for_error` helper is deprecated.")
1620
- expect(logs).to contains_log(
1621
- :warn,
1622
- "The `Appsignal.listen_for_error` helper is deprecated."
1623
- )
1624
- end
1625
-
1626
- it "records the error and re-raise it" do
1627
- expect do
1628
- expect do
1629
- Appsignal.listen_for_error do
1630
- raise ExampleException, "I am an exception"
1631
- end
1632
- end.to raise_error(ExampleException, "I am an exception")
1633
- end.to change { created_transactions.count }.by(1)
1634
-
1635
- # Default namespace
1636
- expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1637
- expect(last_transaction).to have_error("ExampleException", "I am an exception")
1638
- expect(last_transaction).to_not include_tags
1639
- end
1640
-
1641
- context "with tags" do
1642
- it "adds tags to the transaction" do
1643
- expect do
1644
- expect do
1645
- Appsignal.listen_for_error("foo" => "bar") do
1646
- raise ExampleException, "I am an exception"
1647
- end
1648
- end.to raise_error(ExampleException, "I am an exception")
1649
- end.to change { created_transactions.count }.by(1)
1650
1318
 
1651
- # Default namespace
1652
- expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1653
- expect(last_transaction).to have_error("ExampleException", "I am an exception")
1654
- expect(last_transaction).to include_tags("foo" => "bar")
1655
- end
1656
- end
1319
+ # Restores the active_transaction as the current transaction
1320
+ expect(current_transaction).to eq(active_transaction)
1657
1321
 
1658
- context "with a custom namespace" do
1659
- it "adds the namespace to the transaction" do
1660
- expect do
1661
- expect do
1662
- Appsignal.listen_for_error(nil, "custom_namespace") do
1663
- raise ExampleException, "I am an exception"
1664
- end
1665
- end.to raise_error(ExampleException, "I am an exception")
1666
- end.to change { created_transactions.count }.by(1)
1322
+ expect(last_transaction).to have_namespace("my_namespace")
1323
+ expect(last_transaction).to have_action("my_action")
1324
+ expect(last_transaction).to have_error("StandardError", "my_error")
1325
+ expect(last_transaction).to be_completed
1667
1326
 
1668
- # Default namespace
1669
- expect(last_transaction).to have_namespace("custom_namespace")
1670
- expect(last_transaction).to have_error("ExampleException", "I am an exception")
1671
- expect(last_transaction).to_not include_tags
1327
+ expect(active_transaction).to have_namespace("active namespace")
1328
+ expect(active_transaction).to have_action("active action")
1329
+ expect(active_transaction).to_not be_completed
1672
1330
  end
1673
1331
  end
1674
1332
  end
@@ -1713,68 +1371,6 @@ describe Appsignal do
1713
1371
  end
1714
1372
  end
1715
1373
 
1716
- context "with tags" do
1717
- let(:tags) { { "foo" => "bar" } }
1718
-
1719
- it "tags the transaction" do
1720
- silence(:allowed => ["set_error", "The tags argument for"]) do
1721
- Appsignal.set_error(error, tags)
1722
- end
1723
-
1724
- transaction._sample
1725
- expect(transaction).to have_error(error)
1726
- expect(transaction).to include_tags(tags)
1727
- end
1728
-
1729
- it "prints a deprecation warning and tags the transaction" do
1730
- logs = capture_logs do
1731
- capture_std_streams(std_stream, err_stream) do
1732
- Appsignal.set_error(error, tags)
1733
- end
1734
- end
1735
-
1736
- message = "The tags argument for `Appsignal.set_error` is deprecated. " \
1737
- "Please use the block method to set tags instead.\n\n" \
1738
- " Appsignal.set_error(error) do |transaction|\n" \
1739
- " transaction.set_tags(#{tags.inspect})\n" \
1740
- " end\n\n" \
1741
- "Appsignal.set_error called on location: #{__FILE__}:"
1742
- expect(stderr).to include("appsignal WARNING: #{message}")
1743
- expect(logs).to include(message)
1744
- end
1745
- end
1746
-
1747
- context "with namespace" do
1748
- let(:namespace) { "admin" }
1749
-
1750
- it "sets the namespace on the transaction" do
1751
- silence(:allowed => ["set_error", "The namespace argument for"]) do
1752
- Appsignal.set_error(error, nil, namespace)
1753
- end
1754
-
1755
- expect(transaction).to have_error("ExampleException", "I am an exception")
1756
- expect(transaction).to have_namespace(namespace)
1757
- expect(transaction).to_not include_tags
1758
- end
1759
-
1760
- it "prints a deprecation warning andsets the namespace on the transaction" do
1761
- logs = capture_logs do
1762
- capture_std_streams(std_stream, err_stream) do
1763
- Appsignal.set_error(error, nil, namespace)
1764
- end
1765
- end
1766
-
1767
- message = "The namespace argument for `Appsignal.set_error` is deprecated. " \
1768
- "Please use the block method to set the namespace instead.\n\n" \
1769
- " Appsignal.set_error(error) do |transaction|\n" \
1770
- " transaction.set_namespace(#{namespace.inspect})\n" \
1771
- " end\n\n" \
1772
- "Appsignal.set_error called on location: #{__FILE__}:"
1773
- expect(stderr).to include("appsignal WARNING: #{message}")
1774
- expect(logs).to include(message)
1775
- end
1776
- end
1777
-
1778
1374
  context "when given a block" do
1779
1375
  it "yields the transaction and allows additional metadata to be set" do
1780
1376
  Appsignal.set_error(StandardError.new("my_error")) do |t|
@@ -1818,7 +1414,7 @@ describe Appsignal do
1818
1414
  logs = capture_logs { Appsignal.report_error(error) }
1819
1415
  expect(logs).to contains_log(
1820
1416
  :error,
1821
- "Appsignal.report_error: Cannot set error. " \
1417
+ "Appsignal.report_error: Cannot add error. " \
1822
1418
  "The given value is not an exception: #{error.inspect}"
1823
1419
  )
1824
1420
  end
@@ -1852,6 +1448,21 @@ describe Appsignal do
1852
1448
  expect(transaction).to include_tags("tag1" => "value1")
1853
1449
  expect(transaction).to be_completed
1854
1450
  end
1451
+
1452
+ it "yields and allows additional metadata to be set with the global helpers" do
1453
+ Appsignal.report_error(error) do
1454
+ Appsignal.set_action("my_action")
1455
+ Appsignal.set_namespace("my_namespace")
1456
+ Appsignal.set_tags(:tag1 => "value1")
1457
+ end
1458
+
1459
+ transaction = last_transaction
1460
+ expect(transaction).to have_namespace("my_namespace")
1461
+ expect(transaction).to have_action("my_action")
1462
+ expect(transaction).to have_error("ExampleException", "error message")
1463
+ expect(transaction).to include_tags("tag1" => "value1")
1464
+ expect(transaction).to be_completed
1465
+ end
1855
1466
  end
1856
1467
  end
1857
1468
 
@@ -1859,7 +1470,7 @@ describe Appsignal do
1859
1470
  let(:transaction) { http_request_transaction }
1860
1471
  before { set_current_transaction(transaction) }
1861
1472
 
1862
- it "adds the error to the active transaction" do
1473
+ it "sets the error in the active transaction" do
1863
1474
  Appsignal.report_error(error)
1864
1475
 
1865
1476
  expect(last_transaction).to eq(transaction)
@@ -1868,6 +1479,41 @@ describe Appsignal do
1868
1479
  expect(transaction).to have_error("ExampleException", "error message")
1869
1480
  end
1870
1481
 
1482
+ context "when the active transaction already has an error" do
1483
+ let(:previous_error) { ExampleException.new("previous error message") }
1484
+
1485
+ before { transaction.set_error(previous_error) }
1486
+
1487
+ it "does not overwrite the existing set error" do
1488
+ Appsignal.report_error(error)
1489
+
1490
+ transaction._sample
1491
+ expect(transaction).to have_error("ExampleException", "previous error message")
1492
+ end
1493
+
1494
+ it "adds the error to the errors" do
1495
+ Appsignal.report_error(error)
1496
+
1497
+ expect(transaction.error_blocks).to eq({ error => [], previous_error => [] })
1498
+ end
1499
+
1500
+ context "when given a block" do
1501
+ it "only applies the block to the transaction for that error" do
1502
+ Appsignal.report_error(error) do |t|
1503
+ t.set_action("my_action")
1504
+ end
1505
+
1506
+ transaction.complete
1507
+ expect(transaction).to have_error("ExampleException", "previous error message")
1508
+ expect(transaction).not_to have_action("my_action")
1509
+
1510
+ expect(last_transaction).to_not be(transaction)
1511
+ expect(last_transaction).to have_error("ExampleException", "error message")
1512
+ expect(last_transaction).to have_action("my_action")
1513
+ end
1514
+ end
1515
+ end
1516
+
1871
1517
  it "does not complete the transaction" do
1872
1518
  Appsignal.report_error(error)
1873
1519
 
@@ -1875,19 +1521,67 @@ describe Appsignal do
1875
1521
  end
1876
1522
 
1877
1523
  context "when given a block" do
1878
- it "yields the transaction and allows additional metadata to be set" do
1524
+ before do
1879
1525
  Appsignal.report_error(error) do |t|
1880
1526
  t.set_action("my_action")
1881
1527
  t.set_namespace("my_namespace")
1882
1528
  t.set_tags(:tag1 => "value1")
1883
1529
  end
1530
+ end
1531
+
1532
+ it "applies the block to the error transaction when completed" do
1533
+ expect(transaction).not_to have_namespace("my_namespace")
1534
+ expect(transaction).not_to have_action("my_action")
1535
+ expect(transaction).not_to include_tags("tag1" => "value1")
1536
+ expect(transaction).to have_error
1537
+ expect(transaction).not_to be_completed
1538
+
1539
+ transaction.complete
1540
+ expect(transaction).to have_namespace("my_namespace")
1541
+ expect(transaction).to have_action("my_action")
1542
+ expect(transaction).to include_tags("tag1" => "value1")
1543
+ expect(transaction).to have_error
1544
+ expect(transaction).to be_completed
1545
+ end
1546
+
1547
+ it "does not apply the block to other error transactions" do
1548
+ Appsignal.report_error(StandardError.new("another error"))
1549
+
1550
+ transaction.complete
1551
+ expect(created_transactions.count).to eq(2)
1884
1552
 
1885
- transaction._sample
1886
1553
  expect(transaction).to have_namespace("my_namespace")
1887
1554
  expect(transaction).to have_action("my_action")
1888
- expect(transaction).to have_error("ExampleException", "error message")
1889
1555
  expect(transaction).to include_tags("tag1" => "value1")
1556
+ expect(transaction).to have_error("ExampleException", "error message")
1557
+ expect(transaction).to be_completed
1558
+
1559
+ expect(last_transaction).not_to be(transaction)
1560
+ expect(last_transaction).not_to have_namespace("my_namespace")
1561
+ expect(last_transaction).not_to have_action("my_action")
1562
+ expect(last_transaction).not_to include_tags("tag1" => "value1")
1563
+ expect(last_transaction).to have_error("StandardError", "another error")
1564
+ expect(last_transaction).to be_completed
1565
+ end
1566
+
1567
+ it "does not create a new transaction" do
1568
+ expect(created_transactions).to eq([transaction])
1569
+ end
1570
+
1571
+ it "yields and allows additional metadata to be set with the global helpers" do
1572
+ Appsignal.report_error(error) do
1573
+ Appsignal.set_action("my_action")
1574
+ Appsignal.set_namespace("my_namespace")
1575
+ Appsignal.set_tags(:tag1 => "value1")
1576
+ end
1577
+
1890
1578
  expect(transaction).to_not be_completed
1579
+
1580
+ transaction.complete
1581
+ expect(transaction).to have_namespace("my_namespace")
1582
+ expect(transaction).to have_action("my_action")
1583
+ expect(transaction).to have_error("ExampleException", "error message")
1584
+ expect(transaction).to include_tags("tag1" => "value1")
1891
1585
  end
1892
1586
  end
1893
1587
  end
@@ -1997,30 +1691,6 @@ describe Appsignal do
1997
1691
  expect(transaction).to include_event("name" => "register.this.event")
1998
1692
  expect(transaction).to_not include_event("name" => "dont.register.this.event")
1999
1693
  end
2000
-
2001
- it "has a without_instrumentation alias that prints a deprecation warning" do
2002
- Appsignal.instrument("register.this.event") { :do_nothing }
2003
- err_stream = std_stream
2004
- logs =
2005
- capture_logs do
2006
- capture_std_streams(std_stream, err_stream) do
2007
- Appsignal.without_instrumentation do
2008
- Appsignal.instrument("dont.register.this.event") { :do_nothing }
2009
- end
2010
- end
2011
- end
2012
-
2013
- expect(transaction).to include_event("name" => "register.this.event")
2014
- expect(transaction).to_not include_event("name" => "dont.register.this.event")
2015
-
2016
- expect(logs).to contains_log(
2017
- :warn,
2018
- "The `Appsignal.without_instrumentation` helper is deprecated."
2019
- )
2020
- expect(err_stream.read).to include(
2021
- "appsignal WARNING: The `Appsignal.without_instrumentation` helper is deprecated."
2022
- )
2023
- end
2024
1694
  end
2025
1695
 
2026
1696
  context "without current transaction" do
@@ -2033,24 +1703,6 @@ describe Appsignal do
2033
1703
  end
2034
1704
  end
2035
1705
 
2036
- describe ".start_logger" do
2037
- let(:stderr_stream) { std_stream }
2038
- let(:stderr) { stderr_stream.read }
2039
- let(:log_stream) { std_stream }
2040
- let(:log) { log_contents(log_stream) }
2041
-
2042
- it "prints and logs a deprecation warning" do
2043
- use_logger_with(log_stream) do
2044
- capture_std_streams(std_stream, stderr_stream) do
2045
- Appsignal.start_logger
2046
- end
2047
- end
2048
- expect(stderr)
2049
- .to include("appsignal WARNING: Calling 'Appsignal.start_logger' is deprecated.")
2050
- expect(log).to contains_log(:warn, "Calling 'Appsignal.start_logger' is deprecated.")
2051
- end
2052
- end
2053
-
2054
1706
  describe "._start_logger" do
2055
1707
  let(:out_stream) { std_stream }
2056
1708
  let(:output) { out_stream.read }
@@ -2069,11 +1721,10 @@ describe Appsignal do
2069
1721
  after { FileUtils.rm_rf(log_path) }
2070
1722
 
2071
1723
  def initialize_config
2072
- Appsignal._config = project_fixture_config(
2073
- "production",
2074
- :log_path => log_path,
2075
- :log_level => log_level
2076
- )
1724
+ Appsignal.configure(:production, :root_path => project_fixture_path) do |config|
1725
+ config.log_path = log_path
1726
+ config.log_level = log_level
1727
+ end
2077
1728
  Appsignal.internal_logger.error("Log in memory line 1")
2078
1729
  Appsignal.internal_logger.debug("Log in memory line 2")
2079
1730
  expect(Appsignal.in_memory_logger.messages).to_not be_empty