appsignal 2.11.9-java → 3.0.0.beta.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.semaphore/semaphore.yml +0 -23
  4. data/CHANGELOG.md +5 -14
  5. data/build_matrix.yml +0 -4
  6. data/lib/appsignal.rb +1 -27
  7. data/lib/appsignal/auth_check.rb +2 -8
  8. data/lib/appsignal/cli.rb +1 -23
  9. data/lib/appsignal/config.rb +0 -24
  10. data/lib/appsignal/event_formatter.rb +0 -25
  11. data/lib/appsignal/hooks.rb +0 -23
  12. data/lib/appsignal/hooks/action_cable.rb +5 -44
  13. data/lib/appsignal/hooks/active_support_notifications.rb +7 -86
  14. data/lib/appsignal/hooks/celluloid.rb +5 -9
  15. data/lib/appsignal/hooks/net_http.rb +2 -12
  16. data/lib/appsignal/hooks/puma.rb +3 -5
  17. data/lib/appsignal/hooks/que.rb +1 -1
  18. data/lib/appsignal/hooks/rake.rb +2 -24
  19. data/lib/appsignal/hooks/redis.rb +2 -13
  20. data/lib/appsignal/hooks/resque.rb +2 -43
  21. data/lib/appsignal/hooks/sidekiq.rb +1 -5
  22. data/lib/appsignal/hooks/unicorn.rb +3 -24
  23. data/lib/appsignal/hooks/webmachine.rb +1 -7
  24. data/lib/appsignal/integrations/action_cable.rb +34 -0
  25. data/lib/appsignal/integrations/active_support_notifications.rb +77 -0
  26. data/lib/appsignal/integrations/net_http.rb +16 -0
  27. data/lib/appsignal/integrations/object.rb +61 -4
  28. data/lib/appsignal/integrations/padrino.rb +5 -7
  29. data/lib/appsignal/integrations/que.rb +26 -33
  30. data/lib/appsignal/integrations/railtie.rb +1 -4
  31. data/lib/appsignal/integrations/rake.rb +26 -2
  32. data/lib/appsignal/integrations/redis.rb +17 -0
  33. data/lib/appsignal/integrations/resque.rb +39 -10
  34. data/lib/appsignal/integrations/unicorn.rb +28 -0
  35. data/lib/appsignal/integrations/webmachine.rb +22 -24
  36. data/lib/appsignal/minutely.rb +0 -18
  37. data/lib/appsignal/version.rb +1 -1
  38. data/spec/lib/appsignal/auth_check_spec.rb +1 -24
  39. data/spec/lib/appsignal/cli_spec.rb +1 -1
  40. data/spec/lib/appsignal/config_spec.rb +0 -66
  41. data/spec/lib/appsignal/event_formatter_spec.rb +0 -37
  42. data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -88
  43. data/spec/lib/appsignal/hooks/celluloid_spec.rb +6 -1
  44. data/spec/lib/appsignal/hooks/rake_spec.rb +1 -2
  45. data/spec/lib/appsignal/hooks/redis_spec.rb +50 -15
  46. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +7 -61
  47. data/spec/lib/appsignal/hooks/unicorn_spec.rb +14 -3
  48. data/spec/lib/appsignal/hooks/webmachine_spec.rb +2 -13
  49. data/spec/lib/appsignal/hooks_spec.rb +0 -57
  50. data/spec/lib/appsignal/integrations/object_spec.rb +4 -95
  51. data/spec/lib/appsignal/integrations/padrino_spec.rb +2 -3
  52. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -45
  53. data/spec/lib/appsignal/integrations/webmachine_spec.rb +26 -8
  54. data/spec/lib/appsignal/minutely_spec.rb +0 -19
  55. data/spec/lib/appsignal/transaction_spec.rb +1 -14
  56. data/spec/lib/appsignal/transmitter_spec.rb +1 -1
  57. data/spec/lib/appsignal_spec.rb +0 -69
  58. data/spec/lib/puma/appsignal_spec.rb +0 -28
  59. data/spec/spec_helper.rb +1 -15
  60. metadata +10 -23
  61. data/lib/appsignal/cli/notify_of_deploy.rb +0 -131
  62. data/lib/appsignal/integrations/object_ruby_19.rb +0 -37
  63. data/lib/appsignal/integrations/object_ruby_modern.rb +0 -41
  64. data/lib/appsignal/integrations/resque_active_job.rb +0 -19
  65. data/lib/appsignal/js_exception_transaction.rb +0 -56
  66. data/lib/appsignal/rack/js_exception_catcher.rb +0 -80
  67. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +0 -180
  68. data/spec/lib/appsignal/integrations/object_19_spec.rb +0 -266
  69. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +0 -28
  70. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -28
  71. data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -128
  72. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +0 -170
@@ -28,29 +28,6 @@ describe Appsignal::AuthCheck do
28
28
  end.join("&")
29
29
  end
30
30
 
31
- describe ".new" do
32
- describe "with logger argument" do
33
- let(:err_stream) { std_stream }
34
- let(:stderr) { err_stream.read }
35
- let(:log_stream) { std_stream }
36
- let(:log) { log_contents(log_stream) }
37
-
38
- it "logs and prints a deprecation message" do
39
- Appsignal.logger = test_logger(log_stream)
40
-
41
- capture_std_streams(std_stream, err_stream) do
42
- Appsignal::AuthCheck.new(config, Appsignal.logger)
43
- end
44
-
45
- deprecation_message =
46
- "`Appsignal::AuthCheck.new`'s `logger` argument " \
47
- "will be removed in the next major version."
48
- expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
49
- expect(log).to contains_log :warn, deprecation_message
50
- end
51
- end
52
- end
53
-
54
31
  describe "#perform" do
55
32
  subject { auth_check.perform }
56
33
 
@@ -62,7 +39,7 @@ describe Appsignal::AuthCheck do
62
39
  end
63
40
  end
64
41
 
65
- context "when encountering an exception", :not_ruby19 do
42
+ context "when encountering an exception" do
66
43
  before { stubbed_request.to_timeout }
67
44
 
68
45
  it "raises an error" do
@@ -16,7 +16,7 @@ describe Appsignal::CLI do
16
16
 
17
17
  expect(output).to include "appsignal <command> [options]"
18
18
  expect(output).to include \
19
- "Available commands: demo, diagnose, install, notify_of_deploy"
19
+ "Available commands: demo, diagnose, install"
20
20
  end
21
21
  end
22
22
 
@@ -168,8 +168,6 @@ describe Appsignal::Config do
168
168
  :push_api_key => "abc",
169
169
  :name => "TestApp",
170
170
  :active => true,
171
- :enable_frontend_error_catching => false,
172
- :frontend_error_catching_path => "/appsignal_error_catcher",
173
171
  :enable_allocation_tracking => true,
174
172
  :enable_gc_instrumentation => false,
175
173
  :enable_host_metrics => true,
@@ -357,70 +355,6 @@ describe Appsignal::Config do
357
355
  config
358
356
  end
359
357
  end
360
-
361
- describe "support for old config keys" do
362
- let(:err_stream) { std_stream }
363
- let(:stderr) { err_stream.read }
364
- let(:config) { project_fixture_config(env, {}, test_logger(log)) }
365
- let(:log) { StringIO.new }
366
- before { capture_std_streams(std_stream, err_stream) { config } }
367
-
368
- describe ":api_key" do
369
- context "without :push_api_key" do
370
- let(:env) { "old_config" }
371
-
372
- it "sets the :push_api_key with the old :api_key value" do
373
- expect(config[:push_api_key]).to eq "def"
374
- expect(config.config_hash).to_not have_key :api_key
375
-
376
- message = "Old configuration key found. Please update the 'api_key' to 'push_api_key'"
377
- expect(stderr).to include "appsignal WARNING: #{message}"
378
- expect(log_contents(log)).to contains_log :warn, message
379
- end
380
- end
381
-
382
- context "with :push_api_key" do
383
- let(:env) { "old_config_mixed_with_new_config" }
384
-
385
- it "ignores the :api_key config and deletes it" do
386
- expect(config[:push_api_key]).to eq "ghi"
387
- expect(config.config_hash).to_not have_key :api_key
388
-
389
- message = "Old configuration key found. Please update the 'api_key' to 'push_api_key'"
390
- expect(stderr).to include "appsignal WARNING: #{message}"
391
- expect(log_contents(log)).to contains_log :warn, message
392
- end
393
- end
394
- end
395
-
396
- describe ":ignore_exceptions" do
397
- context "without :ignore_errors" do
398
- let(:env) { "old_config" }
399
-
400
- it "sets :ignore_errors with the old :ignore_exceptions value" do
401
- expect(config[:ignore_errors]).to eq ["StandardError"]
402
- expect(config.config_hash).to_not have_key :ignore_exceptions
403
-
404
- message = "Old configuration key found. Please update the 'ignore_exceptions' to 'ignore_errors'"
405
- expect(stderr).to include "appsignal WARNING: #{message}"
406
- expect(log_contents(log)).to contains_log :warn, message
407
- end
408
- end
409
-
410
- context "with :ignore_errors" do
411
- let(:env) { "old_config_mixed_with_new_config" }
412
-
413
- it "ignores the :ignore_exceptions config" do
414
- expect(config[:ignore_errors]).to eq ["NoMethodError"]
415
- expect(config.config_hash).to_not have_key :ignore_exceptions
416
-
417
- message = "Old configuration key found. Please update the 'ignore_exceptions' to 'ignore_errors'"
418
- expect(stderr).to include "appsignal WARNING: #{message}"
419
- expect(log_contents(log)).to contains_log :warn, message
420
- end
421
- end
422
- end
423
- end
424
358
  end
425
359
 
426
360
  context "with config in the environment" do
@@ -114,43 +114,6 @@ describe Appsignal::EventFormatter do
114
114
  end
115
115
  end
116
116
  end
117
-
118
- context "when registering deprecated formatters" do
119
- let(:err_stream) { std_stream }
120
- let(:stderr) { err_stream.read }
121
- let(:deprecated_formatter) do
122
- Class.new(Appsignal::EventFormatter) do
123
- register "mock.deprecated"
124
-
125
- def format(_payload)
126
- end
127
- end
128
- end
129
-
130
- it "registers deprecated formatters and logs & prints a warning" do
131
- message = "Formatter for 'mock.deprecated' is using a deprecated registration method. " \
132
- "This event formatter will not be loaded. " \
133
- "Please update the formatter according to the documentation at: " \
134
- "https://docs.appsignal.com/ruby/instrumentation/event-formatters.html"
135
-
136
- logs = capture_logs do
137
- capture_std_streams(std_stream, err_stream) { deprecated_formatter }
138
- end
139
- expect(logs).to contains_log :warn, message
140
- expect(stderr).to include "appsignal WARNING: #{message}"
141
-
142
- expect(klass.deprecated_formatter_classes.keys).to include("mock.deprecated")
143
- end
144
-
145
- it "initializes deprecated formatters" do
146
- capture_std_streams(std_stream, err_stream) { deprecated_formatter }
147
- klass.initialize_deprecated_formatters
148
-
149
- expect(klass.registered?("mock.deprecated")).to be_truthy
150
- expect(klass.formatters["mock.deprecated"]).to be_instance_of(deprecated_formatter)
151
- expect(klass.deprecated_formatter_classes["mock.deprecated"]).to eq(deprecated_formatter)
152
- end
153
- end
154
117
  end
155
118
 
156
119
  describe ".registered?" do
@@ -2,8 +2,6 @@ describe Appsignal::Hooks::ActionCableHook do
2
2
  if DependencyHelper.action_cable_present?
3
3
  context "with ActionCable" do
4
4
  require "action_cable/engine"
5
- # Require test helper to test with ConnectionStub
6
- require "action_cable/channel/test_case" if DependencyHelper.rails6_present?
7
5
 
8
6
  describe ".dependencies_present?" do
9
7
  subject { described_class.new.dependencies_present? }
@@ -264,49 +262,6 @@ describe Appsignal::Hooks::ActionCableHook do
264
262
  )
265
263
  end
266
264
  end
267
-
268
- if DependencyHelper.rails6_present?
269
- context "with ConnectionStub" do
270
- let(:connection) { ActionCable::Channel::ConnectionStub.new }
271
- let(:transaction_id) { "Stubbed transaction id" }
272
- before do
273
- # Stub future (private AppSignal) transaction id generated by the hook.
274
- expect(SecureRandom).to receive(:uuid).and_return(transaction_id)
275
- end
276
-
277
- it "does not fail on missing `#env` method on `ConnectionStub`" do
278
- instance.subscribe_to_channel
279
-
280
- expect(subject).to include(
281
- "action" => "MyChannel#subscribed",
282
- "error" => nil,
283
- "id" => transaction_id,
284
- "namespace" => Appsignal::Transaction::ACTION_CABLE,
285
- "metadata" => {
286
- "method" => "websocket",
287
- "path" => "" # No path as the ConnectionStub doesn't have the real request env
288
- }
289
- )
290
- expect(subject["events"].first).to include(
291
- "allocation_count" => kind_of(Integer),
292
- "body" => "",
293
- "body_format" => Appsignal::EventFormatter::DEFAULT,
294
- "child_allocation_count" => kind_of(Integer),
295
- "child_duration" => kind_of(Float),
296
- "child_gc_duration" => kind_of(Float),
297
- "count" => 1,
298
- "gc_duration" => kind_of(Float),
299
- "start" => kind_of(Float),
300
- "duration" => kind_of(Float),
301
- "name" => "subscribed.action_cable",
302
- "title" => ""
303
- )
304
- expect(subject["sample_data"]).to include(
305
- "params" => { "internal" => "true" }
306
- )
307
- end
308
- end
309
- end
310
265
  end
311
266
 
312
267
  describe "unsubscribe callback" do
@@ -394,49 +349,6 @@ describe Appsignal::Hooks::ActionCableHook do
394
349
  )
395
350
  end
396
351
  end
397
-
398
- if DependencyHelper.rails6_present?
399
- context "with ConnectionStub" do
400
- let(:connection) { ActionCable::Channel::ConnectionStub.new }
401
- let(:transaction_id) { "Stubbed transaction id" }
402
- before do
403
- # Stub future (private AppSignal) transaction id generated by the hook.
404
- expect(SecureRandom).to receive(:uuid).and_return(transaction_id)
405
- end
406
-
407
- it "does not fail on missing `#env` method on `ConnectionStub`" do
408
- instance.unsubscribe_from_channel
409
-
410
- expect(subject).to include(
411
- "action" => "MyChannel#unsubscribed",
412
- "error" => nil,
413
- "id" => transaction_id,
414
- "namespace" => Appsignal::Transaction::ACTION_CABLE,
415
- "metadata" => {
416
- "method" => "websocket",
417
- "path" => "" # No path as the ConnectionStub doesn't have the real request env
418
- }
419
- )
420
- expect(subject["events"].first).to include(
421
- "allocation_count" => kind_of(Integer),
422
- "body" => "",
423
- "body_format" => Appsignal::EventFormatter::DEFAULT,
424
- "child_allocation_count" => kind_of(Integer),
425
- "child_duration" => kind_of(Float),
426
- "child_gc_duration" => kind_of(Float),
427
- "count" => 1,
428
- "gc_duration" => kind_of(Float),
429
- "start" => kind_of(Float),
430
- "duration" => kind_of(Float),
431
- "name" => "unsubscribed.action_cable",
432
- "title" => ""
433
- )
434
- expect(subject["sample_data"]).to include(
435
- "params" => { "internal" => "true" }
436
- )
437
- end
438
- end
439
- end
440
352
  end
441
353
  end
442
354
  end
@@ -3,6 +3,11 @@ describe Appsignal::Hooks::CelluloidHook do
3
3
  before :context do
4
4
  module Celluloid
5
5
  def self.shutdown
6
+ @shut_down = true
7
+ end
8
+
9
+ def self.shut_down?
10
+ @shut_down == true
6
11
  end
7
12
  end
8
13
  Appsignal::Hooks::CelluloidHook.new.install
@@ -18,7 +23,7 @@ describe Appsignal::Hooks::CelluloidHook do
18
23
  end
19
24
 
20
25
  specify { expect(Appsignal).to receive(:stop) }
21
- specify { expect(Celluloid).to receive(:shutdown_without_appsignal) }
26
+ specify { expect(Celluloid.shut_down?).to be true }
22
27
 
23
28
  after do
24
29
  Celluloid.shutdown
@@ -20,8 +20,7 @@ describe Appsignal::Hooks::RakeHook do
20
20
  end
21
21
 
22
22
  it "calls the original task" do
23
- expect(task).to receive(:execute_without_appsignal).with(arguments)
24
- perform
23
+ expect(perform).to eq([])
25
24
  end
26
25
  end
27
26
 
@@ -1,33 +1,68 @@
1
1
  describe Appsignal::Hooks::RedisHook do
2
2
  before do
3
3
  Appsignal.config = project_fixture_config
4
- Appsignal::Hooks.load_hooks
5
4
  end
6
5
 
7
6
  if DependencyHelper.redis_present?
8
7
  context "with redis" do
9
8
  context "with instrumentation enabled" do
10
- before do
11
- Appsignal.config.config_hash[:instrument_redis] = true
12
- allow_any_instance_of(Redis::Client).to receive(:process_without_appsignal).and_return(1)
13
- end
14
-
15
9
  describe "#dependencies_present?" do
16
10
  subject { described_class.new.dependencies_present? }
17
11
 
18
12
  it { is_expected.to be_truthy }
19
13
  end
20
14
 
21
- it "should instrument a redis call" do
22
- Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
23
- expect(Appsignal::Transaction.current).to receive(:start_event)
24
- .at_least(:once)
25
- expect(Appsignal::Transaction.current).to receive(:finish_event)
26
- .at_least(:once)
27
- .with("query.redis", "redis://127.0.0.1:6379/0", "get ?", 0)
15
+ describe "integration" do
16
+ before do
17
+ Appsignal.config.config_hash[:instrument_redis] = true
18
+ end
19
+
20
+ context "install" do
21
+ before do
22
+ Appsignal::Hooks.load_hooks
23
+ end
24
+
25
+ it "does something" do
26
+ # Test if the last included module (prepended module) was our
27
+ # integration. That's not certain with the assertions below
28
+ # because we have to overwrite the `process` method for the test.
29
+ expect(Redis::Client.included_modules.first)
30
+ .to eql(Appsignal::Integrations::RedisIntegration)
31
+ end
32
+ end
33
+
34
+ context "instrumentation" do
35
+ before do
36
+ # Stub Redis::Client class so that it doesn't perform an actual
37
+ # Redis query. This class will be included (prepended) with the
38
+ # AppSignal Redis integration.
39
+ stub_const("Redis::Client", Class.new do
40
+ def id
41
+ :stub_id
42
+ end
43
+
44
+ def process(_commands)
45
+ :stub_process
46
+ end
47
+ end)
48
+ # Load the integration again for the stubbed Redis::Client class.
49
+ # Call it directly because {Appsignal::Hooks.load_hooks} keeps
50
+ # track if it was installed already or not.
51
+ Appsignal::Hooks::RedisHook.new.install
52
+ end
53
+
54
+ it "instrument a redis call" do
55
+ Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
56
+ expect(Appsignal::Transaction.current).to receive(:start_event)
57
+ .at_least(:once)
58
+ expect(Appsignal::Transaction.current).to receive(:finish_event)
59
+ .at_least(:once)
60
+ .with("query.redis", :stub_id, "get ?", 0)
28
61
 
29
- client = Redis::Client.new
30
- expect(client.process([[:get, "key"]])).to eq 1
62
+ client = Redis::Client.new
63
+ expect(client.process([[:get, "key"]])).to eql(:stub_process)
64
+ end
65
+ end
31
66
  end
32
67
  end
33
68
 
@@ -16,31 +16,14 @@ describe Appsignal::Hooks::SidekiqHook do
16
16
  end
17
17
 
18
18
  describe "#install" do
19
- class SidekiqMiddlewareMockWithPrepend < Array
20
- alias add <<
21
- alias exists? include?
22
-
23
- unless method_defined? :prepend
24
- def prepend(middleware) # For Ruby < 2.5
25
- insert(0, middleware)
26
- end
19
+ class SidekiqMiddlewareMock < Set
20
+ def exists?(middleware)
21
+ include?(middleware)
27
22
  end
28
23
  end
29
-
30
- class SidekiqMiddlewareMockWithoutPrepend < Array
31
- alias add <<
32
- alias exists? include?
33
-
34
- undef_method :prepend if method_defined? :prepend # For Ruby >= 2.5
35
- end
36
-
37
24
  module SidekiqMock
38
- def self.middleware_mock=(mock)
39
- @middlewares = mock.new
40
- end
41
-
42
25
  def self.middlewares
43
- @middlewares
26
+ @middlewares ||= SidekiqMiddlewareMock.new
44
27
  end
45
28
 
46
29
  def self.configure_server
@@ -53,52 +36,15 @@ describe Appsignal::Hooks::SidekiqHook do
53
36
  end
54
37
  end
55
38
 
56
- def add_middleware(middleware)
57
- Sidekiq.configure_server do |sidekiq_config|
58
- sidekiq_config.middlewares.add(middleware)
59
- end
60
- end
61
-
62
39
  before do
63
40
  Appsignal.config = project_fixture_config
64
41
  stub_const "Sidekiq", SidekiqMock
65
42
  end
66
43
 
67
- context "when Sidekiq middleware responds to prepend method" do # Sidekiq 3.3.0 and newer
68
- before { Sidekiq.middleware_mock = SidekiqMiddlewareMockWithPrepend }
69
-
70
- it "adds the AppSignal SidekiqPlugin to the Sidekiq middleware chain in the first position" do
71
- user_middleware1 = proc {}
72
- add_middleware(user_middleware1)
73
- described_class.new.install
74
- user_middleware2 = proc {}
75
- add_middleware(user_middleware2)
44
+ it "adds the AppSignal SidekiqPlugin to the Sidekiq middleware chain" do
45
+ described_class.new.install
76
46
 
77
- expect(Sidekiq.server_middleware).to eql([
78
- Appsignal::Hooks::SidekiqPlugin, # Prepend makes it the first entry
79
- user_middleware1,
80
- user_middleware2
81
- ])
82
- end
83
- end
84
-
85
- context "when Sidekiq middleware does not respond to prepend method" do
86
- before { Sidekiq.middleware_mock = SidekiqMiddlewareMockWithoutPrepend }
87
-
88
- it "adds the AppSignal SidekiqPlugin to the Sidekiq middleware chain" do
89
- user_middleware1 = proc {}
90
- add_middleware(user_middleware1)
91
- described_class.new.install
92
- user_middleware2 = proc {}
93
- add_middleware(user_middleware2)
94
-
95
- # Add middlewares in whatever order they were added
96
- expect(Sidekiq.server_middleware).to eql([
97
- user_middleware1,
98
- Appsignal::Hooks::SidekiqPlugin,
99
- user_middleware2
100
- ])
101
- end
47
+ expect(Sidekiq.server_middleware.exists?(Appsignal::Hooks::SidekiqPlugin)).to be(true)
102
48
  end
103
49
  end
104
50
  end