appsignal 2.11.5-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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.semaphore/semaphore.yml +0 -23
  4. data/CHANGELOG.md +6 -0
  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 +3 -34
  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/unicorn.rb +3 -24
  22. data/lib/appsignal/hooks/webmachine.rb +1 -7
  23. data/lib/appsignal/integrations/action_cable.rb +34 -0
  24. data/lib/appsignal/integrations/active_support_notifications.rb +77 -0
  25. data/lib/appsignal/integrations/net_http.rb +16 -0
  26. data/lib/appsignal/integrations/object.rb +61 -4
  27. data/lib/appsignal/integrations/padrino.rb +5 -7
  28. data/lib/appsignal/integrations/que.rb +26 -33
  29. data/lib/appsignal/integrations/railtie.rb +1 -4
  30. data/lib/appsignal/integrations/rake.rb +26 -2
  31. data/lib/appsignal/integrations/redis.rb +17 -0
  32. data/lib/appsignal/integrations/resque.rb +39 -10
  33. data/lib/appsignal/integrations/unicorn.rb +28 -0
  34. data/lib/appsignal/integrations/webmachine.rb +22 -24
  35. data/lib/appsignal/minutely.rb +0 -12
  36. data/lib/appsignal/version.rb +1 -1
  37. data/spec/lib/appsignal/auth_check_spec.rb +1 -24
  38. data/spec/lib/appsignal/cli_spec.rb +1 -1
  39. data/spec/lib/appsignal/config_spec.rb +0 -66
  40. data/spec/lib/appsignal/event_formatter_spec.rb +0 -37
  41. data/spec/lib/appsignal/hooks/celluloid_spec.rb +6 -1
  42. data/spec/lib/appsignal/hooks/rake_spec.rb +1 -2
  43. data/spec/lib/appsignal/hooks/redis_spec.rb +50 -15
  44. data/spec/lib/appsignal/hooks/unicorn_spec.rb +14 -3
  45. data/spec/lib/appsignal/hooks/webmachine_spec.rb +2 -13
  46. data/spec/lib/appsignal/hooks_spec.rb +0 -57
  47. data/spec/lib/appsignal/integrations/object_spec.rb +0 -4
  48. data/spec/lib/appsignal/integrations/padrino_spec.rb +2 -3
  49. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -45
  50. data/spec/lib/appsignal/integrations/webmachine_spec.rb +26 -8
  51. data/spec/lib/appsignal/minutely_spec.rb +0 -19
  52. data/spec/lib/appsignal/transaction_spec.rb +1 -14
  53. data/spec/lib/appsignal/transmitter_spec.rb +1 -1
  54. data/spec/lib/appsignal_spec.rb +0 -69
  55. data/spec/spec_helper.rb +1 -15
  56. metadata +9 -22
  57. data/lib/appsignal/cli/notify_of_deploy.rb +0 -131
  58. data/lib/appsignal/integrations/object_ruby_19.rb +0 -37
  59. data/lib/appsignal/integrations/object_ruby_modern.rb +0 -64
  60. data/lib/appsignal/integrations/resque_active_job.rb +0 -19
  61. data/lib/appsignal/js_exception_transaction.rb +0 -56
  62. data/lib/appsignal/rack/js_exception_catcher.rb +0 -80
  63. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +0 -180
  64. data/spec/lib/appsignal/integrations/object_19_spec.rb +0 -266
  65. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +0 -28
  66. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -28
  67. data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -128
  68. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +0 -170
@@ -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
 
@@ -3,12 +3,22 @@ describe Appsignal::Hooks::UnicornHook do
3
3
  before :context do
4
4
  module Unicorn
5
5
  class HttpServer
6
- def worker_loop(worker)
6
+ def worker_loop(_worker)
7
+ @worker_loop = true
8
+ end
9
+
10
+ def worker_loop?
11
+ @worker_loop == true
7
12
  end
8
13
  end
9
14
 
10
15
  class Worker
11
16
  def close
17
+ @close = true
18
+ end
19
+
20
+ def close?
21
+ @close == true
12
22
  end
13
23
  end
14
24
  end
@@ -27,18 +37,19 @@ describe Appsignal::Hooks::UnicornHook do
27
37
  worker = double
28
38
 
29
39
  expect(Appsignal).to receive(:forked)
30
- expect(server).to receive(:worker_loop_without_appsignal).with(worker)
31
40
 
32
41
  server.worker_loop(worker)
42
+
43
+ expect(server.worker_loop?).to be true
33
44
  end
34
45
 
35
46
  it "adds behavior to Unicorn::Worker#close" do
36
47
  worker = Unicorn::Worker.new
37
48
 
38
49
  expect(Appsignal).to receive(:stop)
39
- expect(worker).to receive(:close_without_appsignal)
40
50
 
41
51
  worker.close
52
+ expect(worker.close?).to be true
42
53
  end
43
54
  end
44
55
 
@@ -10,19 +10,8 @@ describe Appsignal::Hooks::WebmachineHook do
10
10
  it { is_expected.to be_truthy }
11
11
  end
12
12
 
13
- it "should include the run alias methods" do
14
- expect(fsm).to respond_to(:run_with_appsignal)
15
- expect(fsm).to respond_to(:run_without_appsignal)
16
- end
17
-
18
- it "should include the handle_exceptions alias methods" do
19
- expect(
20
- fsm.respond_to?(:handle_exceptions_with_appsignal, true)
21
- ).to be_truthy
22
-
23
- expect(
24
- fsm.respond_to?(:handle_exceptions_without_appsignal, true)
25
- ).to be_truthy
13
+ it "adds behavior to Webmachine::Decision::FSM" do
14
+ expect(fsm.class.ancestors.first).to eq(Appsignal::Integrations::WebmachineIntegration)
26
15
  end
27
16
  end
28
17
  else
@@ -78,63 +78,6 @@ describe Appsignal::Hooks do
78
78
  expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
79
79
  Appsignal::Hooks.hooks.delete(:mock_error_hook)
80
80
  end
81
-
82
- describe "missing constants" do
83
- let(:err_stream) { std_stream }
84
- let(:stderr) { err_stream.read }
85
- let(:log_stream) { std_stream }
86
- let(:log) { log_contents(log_stream) }
87
- before do
88
- Appsignal.logger = test_logger(log_stream)
89
- end
90
-
91
- def call_constant(&block)
92
- capture_std_streams(std_stream, err_stream, &block)
93
- end
94
-
95
- describe "SidekiqProbe" do
96
- it "logs a deprecation message and returns the new constant" do
97
- constant = call_constant { Appsignal::Hooks::SidekiqProbe }
98
-
99
- expect(constant).to eql(Appsignal::Probes::SidekiqProbe)
100
- expect(constant.name).to eql("Appsignal::Probes::SidekiqProbe")
101
-
102
- deprecation_message =
103
- "The constant Appsignal::Hooks::SidekiqProbe has been deprecated. " \
104
- "Please update the constant name to Appsignal::Probes::SidekiqProbe " \
105
- "in the following file to remove this message.\n#{__FILE__}:"
106
- expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
107
- expect(log).to contains_log :warn, deprecation_message
108
- end
109
- end
110
-
111
- describe "PumaProbe" do
112
- it "logs a deprecation message and returns the new constant" do
113
- constant = call_constant { Appsignal::Hooks::PumaProbe }
114
-
115
- expect(constant).to eql(Appsignal::Probes::PumaProbe)
116
- expect(constant.name).to eql("Appsignal::Probes::PumaProbe")
117
-
118
- deprecation_message =
119
- "The constant Appsignal::Hooks::PumaProbe has been deprecated. " \
120
- "Please update the constant name to Appsignal::Probes::PumaProbe " \
121
- "in the following file to remove this message.\n#{__FILE__}:"
122
- expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
123
- expect(log).to contains_log :warn, deprecation_message
124
- end
125
- end
126
-
127
- describe "other constant" do
128
- it "raises a NameError like Ruby normally does" do
129
- expect do
130
- call_constant { Appsignal::Hooks::Unknown }
131
- end.to raise_error(NameError)
132
-
133
- expect(stderr).to be_empty
134
- expect(log).to be_empty
135
- end
136
- end
137
- end
138
81
  end
139
82
 
140
83
  describe Appsignal::Hooks::Helpers do
@@ -1,9 +1,5 @@
1
1
  require "appsignal/integrations/object"
2
2
 
3
- def is_ruby_19
4
- RUBY_VERSION < "2.0"
5
- end
6
-
7
3
  describe Object do
8
4
  describe "#instrument_method" do
9
5
  context "with instance method" do
@@ -150,10 +150,9 @@ if DependencyHelper.padrino_present?
150
150
  let(:path) { "/static" }
151
151
  before do
152
152
  env["sinatra.static_file"] = true
153
- expect_any_instance_of(app)
154
- .to receive(:route_without_appsignal).and_return([200, {}, ["foo"]])
153
+ app.controllers { get(:static) { "Static!" } }
155
154
  end
156
- after { expect(response).to match_response(200, "foo") }
155
+ after { expect(response).to match_response(200, "Static!") }
157
156
 
158
157
  it "does not instrument the request" do
159
158
  expect_no_transaction_to_be_created
@@ -79,51 +79,6 @@ if DependencyHelper.rails_present?
79
79
 
80
80
  after { Appsignal::Integrations::Railtie.initialize_appsignal(app) }
81
81
  end
82
-
83
- describe "frontend_error_catching middleware" do
84
- let(:config) do
85
- Appsignal::Config.new(
86
- project_fixture_path,
87
- "test",
88
- :name => "MyApp",
89
- :enable_frontend_error_catching => enable_frontend_error_catching
90
- )
91
- end
92
- before { allow(Appsignal::Config).to receive(:new).and_return(config) }
93
- after { Appsignal::Integrations::Railtie.initialize_appsignal(app) }
94
-
95
- context "when enabled" do
96
- let(:enable_frontend_error_catching) { true }
97
-
98
- it "adds the Rails and JSExceptionCatcher middleware" do
99
- expect(app.middleware).to receive(:insert_after).with(
100
- ActionDispatch::DebugExceptions,
101
- Appsignal::Rack::RailsInstrumentation
102
- )
103
-
104
- expect(app.middleware).to receive(:insert_before).with(
105
- Appsignal::Rack::RailsInstrumentation,
106
- Appsignal::Rack::JSExceptionCatcher
107
- )
108
- end
109
- end
110
-
111
- context "when not enabled" do
112
- let(:enable_frontend_error_catching) { false }
113
-
114
- it "adds the Rails middleware, but not the JSExceptionCatcher middleware" do
115
- expect(app.middleware).to receive(:insert_after).with(
116
- ActionDispatch::DebugExceptions,
117
- Appsignal::Rack::RailsInstrumentation
118
- )
119
-
120
- expect(app.middleware).to_not receive(:insert_before).with(
121
- Appsignal::Rack::RailsInstrumentation,
122
- Appsignal::Rack::JSExceptionCatcher
123
- )
124
- end
125
- end
126
- end
127
82
  end
128
83
  end
129
84
  end
@@ -1,12 +1,24 @@
1
1
  if DependencyHelper.webmachine_present?
2
2
  require "appsignal/integrations/webmachine"
3
3
 
4
- describe Appsignal::Integrations::WebmachinePlugin::FSM do
4
+ class Response
5
+ attr_accessor :code
6
+
7
+ def body
8
+ ""
9
+ end
10
+
11
+ def headers
12
+ {}
13
+ end
14
+ end
15
+
16
+ describe Appsignal::Integrations::WebmachineIntegration do
5
17
  let(:request) do
6
18
  Webmachine::Request.new("GET", "http://google.com:80/foo", {}, nil)
7
19
  end
8
- let(:resource) { double(:trace? => false, :handle_exception => true) }
9
- let(:response) { double }
20
+ let(:resource) { double(:trace? => false, :handle_exception => true, :"code=" => nil) }
21
+ let(:response) { Response.new }
10
22
  let(:transaction) { double(:set_action_if_nil => true) }
11
23
  let(:fsm) { Webmachine::Decision::FSM.new(resource, request, response) }
12
24
  before(:context) { start_agent }
@@ -18,10 +30,8 @@ if DependencyHelper.webmachine_present?
18
30
  end
19
31
  end
20
32
 
21
- describe "#run_with_appsignal" do
33
+ describe "#run" do
22
34
  before do
23
- allow(fsm).to receive(:request).and_return(request)
24
- allow(fsm).to receive(:run_without_appsignal).and_return(true)
25
35
  allow(SecureRandom).to receive(:uuid).and_return("uuid")
26
36
  allow(Appsignal::Transaction).to receive(:create).and_return(transaction)
27
37
  end
@@ -40,7 +50,7 @@ if DependencyHelper.webmachine_present?
40
50
  end
41
51
 
42
52
  it "should call the original method" do
43
- expect(fsm).to receive(:run_without_appsignal)
53
+ expect(fsm).to receive(:run)
44
54
  end
45
55
 
46
56
  it "should instrument the original method" do
@@ -52,9 +62,17 @@ if DependencyHelper.webmachine_present?
52
62
  end
53
63
 
54
64
  after { fsm.run }
65
+
66
+ describe "concerning the response" do
67
+ it "sets a response code" do
68
+ expect(fsm.response.code).to be_nil
69
+ fsm.run
70
+ expect(fsm.response.code).not_to be_nil
71
+ end
72
+ end
55
73
  end
56
74
 
57
- describe "#handle_exceptions_with_appsignal" do
75
+ describe "#handle_exceptions" do
58
76
  let(:error) { ExampleException }
59
77
 
60
78
  it "should catch the error and send it to AppSignal" do
@@ -284,25 +284,6 @@ describe Appsignal::Minutely do
284
284
  end
285
285
  end
286
286
 
287
- describe "#<<" do
288
- let(:err_stream) { std_stream }
289
- let(:stderr) { err_stream.read }
290
- let(:log_stream) { std_stream }
291
- let(:log) { log_contents(log_stream) }
292
- before { Appsignal.logger = test_logger(log_stream) }
293
-
294
- it "adds the probe, but prints a deprecation warning" do
295
- probe = lambda {}
296
- capture_std_streams(std_stream, err_stream) { collection << probe }
297
- deprecation_message = "Deprecated " \
298
- "`Appsignal::Minute.probes <<` call. Please use " \
299
- "`Appsignal::Minutely.probes.register` instead."
300
- expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
301
- expect(log).to contains_log :warn, deprecation_message
302
- expect(collection[probe.object_id]).to eql(probe)
303
- end
304
- end
305
-
306
287
  describe "#register" do
307
288
  let(:log_stream) { std_stream }
308
289
  let(:log) { log_contents(log_stream) }
@@ -640,7 +640,7 @@ describe Appsignal::Transaction do
640
640
  end
641
641
 
642
642
  context "when the data cannot be converted to JSON" do
643
- it "does not update the sample data on the transaction", :not_ruby19 do
643
+ it "does not update the sample data on the transaction" do
644
644
  klass = Class.new do
645
645
  def to_s
646
646
  raise "foo" # Cause a deliberate error
@@ -652,19 +652,6 @@ describe Appsignal::Transaction do
652
652
  expect(log_contents(log)).to contains_log :error,
653
653
  "Error generating data (RuntimeError: foo) for"
654
654
  end
655
-
656
- it "does not update the sample data on the transaction", :only_ruby19 do
657
- klass = Class.new do
658
- def to_s
659
- raise "foo" # Cause a deliberate error
660
- end
661
- end
662
- transaction.set_sample_data("params", klass.new => 1)
663
-
664
- expect(transaction.to_h["sample_data"]).to eq({})
665
- expect(log_contents(log)).to contains_log :error,
666
- "Error generating data (RuntimeError: foo). Can't inspect data."
667
- end
668
655
  end
669
656
  end
670
657