appsignal 3.9.2-java → 3.10.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3138 -0
  3. data/.rubocop.yml +28 -20
  4. data/.rubocop_todo.yml +7 -33
  5. data/CHANGELOG.md +130 -0
  6. data/README.md +0 -1
  7. data/Rakefile +80 -65
  8. data/appsignal.gemspec +1 -1
  9. data/build_matrix.yml +112 -184
  10. data/ext/base.rb +1 -1
  11. data/gemfiles/hanami-2.1.gemfile +7 -0
  12. data/gemfiles/webmachine1.gemfile +5 -4
  13. data/lib/appsignal/cli/diagnose.rb +1 -1
  14. data/lib/appsignal/config.rb +5 -1
  15. data/lib/appsignal/demo.rb +0 -1
  16. data/lib/appsignal/environment.rb +11 -2
  17. data/lib/appsignal/extension/jruby.rb +1 -1
  18. data/lib/appsignal/helpers/instrumentation.rb +164 -2
  19. data/lib/appsignal/hooks/active_job.rb +1 -6
  20. data/lib/appsignal/integrations/grape.rb +19 -47
  21. data/lib/appsignal/integrations/hanami.rb +8 -7
  22. data/lib/appsignal/integrations/padrino.rb +51 -52
  23. data/lib/appsignal/integrations/railtie.rb +0 -3
  24. data/lib/appsignal/integrations/rake.rb +46 -12
  25. data/lib/appsignal/integrations/sidekiq.rb +1 -11
  26. data/lib/appsignal/integrations/sinatra.rb +0 -1
  27. data/lib/appsignal/integrations/webmachine.rb +15 -9
  28. data/lib/appsignal/probes/gvl.rb +24 -2
  29. data/lib/appsignal/probes/sidekiq.rb +1 -1
  30. data/lib/appsignal/probes.rb +1 -1
  31. data/lib/appsignal/rack/abstract_middleware.rb +104 -33
  32. data/lib/appsignal/rack/body_wrapper.rb +143 -0
  33. data/lib/appsignal/rack/event_handler.rb +12 -3
  34. data/lib/appsignal/rack/generic_instrumentation.rb +5 -4
  35. data/lib/appsignal/rack/grape_middleware.rb +40 -0
  36. data/lib/appsignal/rack/hanami_middleware.rb +2 -12
  37. data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
  38. data/lib/appsignal/rack/rails_instrumentation.rb +14 -57
  39. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
  40. data/lib/appsignal/rack/streaming_listener.rb +13 -59
  41. data/lib/appsignal/rack.rb +31 -0
  42. data/lib/appsignal/transaction.rb +50 -8
  43. data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
  44. data/lib/appsignal/utils.rb +1 -0
  45. data/lib/appsignal/version.rb +1 -1
  46. data/lib/appsignal.rb +36 -33
  47. data/spec/.rubocop.yml +1 -1
  48. data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
  49. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  50. data/spec/lib/appsignal/config_spec.rb +8 -5
  51. data/spec/lib/appsignal/demo_spec.rb +38 -41
  52. data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
  53. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
  54. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
  55. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
  56. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
  57. data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
  58. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
  59. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
  60. data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
  61. data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
  62. data/spec/lib/appsignal/hooks/rake_spec.rb +107 -34
  63. data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
  64. data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
  65. data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
  66. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
  67. data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
  68. data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
  69. data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
  70. data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
  71. data/spec/lib/appsignal/integrations/padrino_spec.rb +190 -163
  72. data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
  73. data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
  74. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
  75. data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -3
  76. data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -40
  77. data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
  78. data/spec/lib/appsignal/probes_spec.rb +7 -4
  79. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +302 -105
  80. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
  81. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
  82. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -27
  83. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
  84. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
  85. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
  86. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
  87. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
  88. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +44 -139
  89. data/spec/lib/appsignal/transaction_spec.rb +239 -94
  90. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
  91. data/spec/lib/appsignal_spec.rb +556 -344
  92. data/spec/support/helpers/dependency_helper.rb +6 -1
  93. data/spec/support/helpers/std_streams_helper.rb +1 -1
  94. data/spec/support/helpers/transaction_helpers.rb +8 -0
  95. data/spec/support/matchers/transaction.rb +185 -0
  96. data/spec/support/mocks/dummy_app.rb +20 -0
  97. data/spec/support/shared_examples/instrument.rb +17 -12
  98. data/spec/support/testing.rb +18 -9
  99. metadata +20 -11
  100. data/.semaphore/semaphore.yml +0 -2347
  101. data/script/lint_git +0 -22
  102. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
  103. data/spec/support/matchers/be_completed.rb +0 -5
  104. data/support/check_versions +0 -22
  105. /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
@@ -2,11 +2,11 @@ if DependencyHelper.sinatra_present?
2
2
  require "appsignal/integrations/sinatra"
3
3
 
4
4
  module SinatraRequestHelpers
5
- def make_request(env)
5
+ def make_request
6
6
  middleware.call(env)
7
7
  end
8
8
 
9
- def make_request_with_error(env, error)
9
+ def make_request_with_error(error)
10
10
  expect { middleware.call(env) }.to raise_error(error)
11
11
  end
12
12
  end
@@ -30,7 +30,7 @@ if DependencyHelper.sinatra_present?
30
30
  before { allow(middleware).to receive(:raw_payload).and_return({}) }
31
31
 
32
32
  it "doesn't instrument requests" do
33
- expect { make_request(env) }.to_not(change { created_transactions.count })
33
+ expect { make_request }.to_not(change { created_transactions.count })
34
34
  end
35
35
  end
36
36
 
@@ -100,54 +100,48 @@ if DependencyHelper.sinatra_present?
100
100
  before { allow(Appsignal).to receive(:active?).and_return(false) }
101
101
 
102
102
  it "does not instrument requests" do
103
- expect { make_request(env) }.to_not(change { created_transactions.count })
103
+ expect { make_request }.to_not(change { created_transactions.count })
104
104
  end
105
105
 
106
106
  it "calls the next middleware in the stack" do
107
- make_request(env)
107
+ make_request
108
108
 
109
109
  expect(app).to have_received(:call).with(env)
110
110
  end
111
111
  end
112
112
 
113
113
  context "when appsignal is active" do
114
- context "without an exception" do
114
+ context "without an error" do
115
+ it "creates a transaction for the request" do
116
+ expect { make_request }.to(change { created_transactions.count }.by(1))
117
+
118
+ expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
119
+ end
120
+
115
121
  it "reports a process_action.sinatra event" do
116
- make_request(env)
117
-
118
- expect(last_transaction.to_h).to include(
119
- "events" => [
120
- hash_including(
121
- "body" => "",
122
- "body_format" => Appsignal::EventFormatter::DEFAULT,
123
- "count" => 1,
124
- "name" => "process_action.sinatra",
125
- "title" => ""
126
- )
127
- ]
128
- )
122
+ make_request
123
+
124
+ expect(last_transaction).to include_event("name" => "process_action.sinatra")
129
125
  end
130
126
  end
131
127
 
132
128
  context "with an error in sinatra.error" do
133
129
  let(:error) { ExampleException.new("error message") }
134
- before do
135
- env["sinatra.error"] = error
130
+ before { env["sinatra.error"] = error }
131
+
132
+ it "creates a transaction for the request" do
133
+ expect { make_request }.to(change { created_transactions.count }.by(1))
134
+
135
+ expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
136
136
  end
137
137
 
138
138
  context "when raise_errors is off" do
139
139
  let(:settings) { double(:raise_errors => false) }
140
140
 
141
- it "record the error" do
142
- expect { make_request(env) }
143
- .to(change { created_transactions.count }.by(1))
141
+ it "records the error" do
142
+ make_request
144
143
 
145
- expect(last_transaction.to_h).to include(
146
- "error" => hash_including(
147
- "name" => "ExampleException",
148
- "message" => "error message"
149
- )
150
- )
144
+ expect(last_transaction).to have_error("ExampleException", "error message")
151
145
  end
152
146
  end
153
147
 
@@ -155,10 +149,9 @@ if DependencyHelper.sinatra_present?
155
149
  let(:settings) { double(:raise_errors => true) }
156
150
 
157
151
  it "does not record the error" do
158
- expect { make_request(env) }
159
- .to(change { created_transactions.count }.by(1))
152
+ make_request
160
153
 
161
- expect(last_transaction.to_h).to include("error" => nil)
154
+ expect(last_transaction).to_not have_error
162
155
  end
163
156
  end
164
157
 
@@ -171,19 +164,18 @@ if DependencyHelper.sinatra_present?
171
164
  end
172
165
 
173
166
  it "does not record the error" do
174
- expect { make_request(env) }
175
- .to(change { created_transactions.count }.by(1))
167
+ make_request
176
168
 
177
- expect(last_transaction.to_h).to include("error" => nil)
169
+ expect(last_transaction).to_not have_error
178
170
  end
179
171
  end
180
172
  end
181
173
 
182
174
  describe "action name" do
183
175
  it "sets the action to the request method and path" do
184
- make_request(env)
176
+ make_request
185
177
 
186
- expect(last_transaction.to_h).to include("action" => "GET /path")
178
+ expect(last_transaction).to have_action("GET /path")
187
179
  end
188
180
 
189
181
  context "without 'sinatra.route' env" do
@@ -192,9 +184,9 @@ if DependencyHelper.sinatra_present?
192
184
  end
193
185
 
194
186
  it "doesn't set an action name" do
195
- make_request(env)
187
+ make_request
196
188
 
197
- expect(last_transaction.to_h).to include("action" => nil)
189
+ expect(last_transaction).to_not have_action
198
190
  end
199
191
  end
200
192
 
@@ -202,9 +194,9 @@ if DependencyHelper.sinatra_present?
202
194
  before { env["SCRIPT_NAME"] = "/api" }
203
195
 
204
196
  it "sets the action name with an application prefix path" do
205
- make_request(env)
197
+ make_request
206
198
 
207
- expect(last_transaction.to_h).to include("action" => "GET /api/path")
199
+ expect(last_transaction).to have_action("GET /api/path")
208
200
  end
209
201
 
210
202
  context "without 'sinatra.route' env" do
@@ -213,9 +205,9 @@ if DependencyHelper.sinatra_present?
213
205
  end
214
206
 
215
207
  it "doesn't set an action name" do
216
- make_request(env)
208
+ make_request
217
209
 
218
- expect(last_transaction.to_h).to include("action" => nil)
210
+ expect(last_transaction).to_not have_action
219
211
  end
220
212
  end
221
213
  end
@@ -1,164 +1,69 @@
1
- require "appsignal/rack/streaming_listener"
2
-
3
- describe Appsignal::Rack::StreamingListener do
4
- before(:context) { start_agent }
5
- let(:headers) { {} }
6
- let(:env) do
7
- {
8
- "rack.input" => StringIO.new,
9
- "REQUEST_METHOD" => "GET",
10
- "PATH_INFO" => "/homepage",
11
- "QUERY_STRING" => "param=something"
12
- }
1
+ describe "Appsignal::Rack::StreamingListener" do
2
+ def load_middleware
3
+ load "lib/appsignal/rack/streaming_listener.rb"
13
4
  end
14
- let(:app) { double(:call => [200, headers, "body"]) }
15
- let(:listener) { Appsignal::Rack::StreamingListener.new(app, {}) }
16
-
17
- describe "#call" do
18
- context "when Appsignal is active" do
19
- before { allow(Appsignal).to receive(:active?).and_return(true) }
20
-
21
- it "should call `call_with_appsignal_monitoring`" do
22
- expect(listener).to receive(:call_with_appsignal_monitoring)
23
- end
24
- end
25
5
 
26
- context "when Appsignal is not active" do
27
- before { allow(Appsignal).to receive(:active?).and_return(false) }
6
+ describe "loading the streaming_listener integrations file" do
7
+ let(:err_stream) { std_stream }
8
+ let(:stderr) { err_stream.read }
9
+ after { Appsignal::Rack.send(:remove_const, :StreamingListener) }
28
10
 
29
- it "should not call `call_with_appsignal_monitoring`" do
30
- expect(listener).to_not receive(:call_with_appsignal_monitoring)
11
+ it "prints a deprecation warning to STDERR" do
12
+ capture_std_streams(std_stream, err_stream) do
13
+ load_middleware
31
14
  end
32
- end
33
15
 
34
- after { listener.call(env) }
35
- end
36
-
37
- describe "#call_with_appsignal_monitoring" do
38
- let!(:transaction) do
39
- Appsignal::Transaction.create(
40
- SecureRandom.uuid,
41
- Appsignal::Transaction::HTTP_REQUEST,
42
- ::Rack::Request.new(env)
16
+ expect(stderr).to include(
17
+ "appsignal WARNING: The constant Appsignal::Rack::StreamingListener " \
18
+ "has been deprecated."
43
19
  )
44
20
  end
45
- let(:wrapper) { Appsignal::StreamWrapper.new("body", transaction) }
46
- let(:raw_payload) { { :foo => :bar } }
47
-
48
- before do
49
- allow(SecureRandom).to receive(:uuid).and_return("123")
50
- allow(listener).to receive(:raw_payload).and_return(raw_payload)
51
- allow(Appsignal::Transaction).to receive(:create).and_return(transaction)
52
- end
53
-
54
- it "should create a transaction" do
55
- expect(Appsignal::Transaction).to receive(:create)
56
- .with("123", Appsignal::Transaction::HTTP_REQUEST, instance_of(Rack::Request))
57
- .and_return(transaction)
58
-
59
- listener.call_with_appsignal_monitoring(env)
60
- end
61
-
62
- it "should instrument the call" do
63
- expect(Appsignal).to receive(:instrument)
64
- .with("process_action.rack")
65
- .and_yield
66
-
67
- listener.call_with_appsignal_monitoring(env)
68
- end
69
-
70
- it "should add `appsignal.action` to the transaction" do
71
- allow(Appsignal).to receive(:instrument).and_yield
72
-
73
- env["appsignal.action"] = "Action"
74
-
75
- expect(transaction).to receive(:set_action_if_nil).with("Action")
76
-
77
- listener.call_with_appsignal_monitoring(env)
78
- end
79
-
80
- it "should add the path, method and queue start to the transaction" do
81
- allow(Appsignal).to receive(:instrument).and_yield
82
21
 
83
- expect(transaction).to receive(:set_metadata).with("path", "/homepage")
84
- expect(transaction).to receive(:set_metadata).with("method", "GET")
85
- expect(transaction).to receive(:set_http_or_background_queue_start)
86
-
87
- listener.call_with_appsignal_monitoring(env)
88
- end
89
-
90
- context "with an exception in the instrumentation call" do
91
- let(:error) { ExampleException }
92
-
93
- it "should add the exception to the transaction" do
94
- allow(app).to receive(:call).and_raise(error)
95
-
96
- expect(transaction).to receive(:set_error).with(error)
97
-
98
- expect do
99
- listener.call_with_appsignal_monitoring(env)
100
- end.to raise_error(error)
101
- end
102
- end
103
-
104
- it "should wrap the body in a wrapper" do
105
- expect(Appsignal::StreamWrapper).to receive(:new)
106
- .with("body", transaction)
107
- .and_return(wrapper)
108
-
109
- body = listener.call_with_appsignal_monitoring(env)[2]
110
-
111
- expect(body).to be_a(Appsignal::StreamWrapper)
22
+ it "logs a warning" do
23
+ logs =
24
+ capture_logs do
25
+ silence do
26
+ load_middleware
27
+ end
28
+ end
29
+
30
+ expect(logs).to contains_log(
31
+ :warn,
32
+ "The constant Appsignal::Rack::StreamingListener has been deprecated."
33
+ )
112
34
  end
113
35
  end
114
- end
115
-
116
- describe Appsignal::StreamWrapper do
117
- let(:stream) { double }
118
- let(:transaction) do
119
- Appsignal::Transaction.create(SecureRandom.uuid, Appsignal::Transaction::HTTP_REQUEST, {})
120
- end
121
- let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
122
36
 
123
- describe "#each" do
124
- it "calls the original stream" do
125
- expect(stream).to receive(:each)
37
+ describe "middleware" do
38
+ let(:env) { {} }
39
+ let(:app) { DummyApp.new }
40
+ let(:middleware) { Appsignal::Rack::StreamingListener.new(app, {}) }
41
+ around { |example| keep_transactions { example.run } }
42
+ before(:context) { load_middleware }
43
+ before { start_agent }
126
44
 
127
- wrapper.each
45
+ def make_request
46
+ middleware.call(env)
128
47
  end
129
48
 
130
- context "when #each raises an error" do
131
- let(:error) { ExampleException }
132
-
133
- it "records the exception" do
134
- allow(stream).to receive(:each).and_raise(error)
135
-
136
- expect(transaction).to receive(:set_error).with(error)
49
+ it "instruments the call" do
50
+ make_request
137
51
 
138
- expect { wrapper.send(:each) }.to raise_error(error)
139
- end
52
+ expect(last_transaction).to include_event("name" => "process_streaming_request.rack")
140
53
  end
141
- end
142
54
 
143
- describe "#close" do
144
- it "closes the original stream and completes the transaction" do
145
- expect(stream).to receive(:close)
146
- expect(Appsignal::Transaction).to receive(:complete_current!)
55
+ it "set no action by default" do
56
+ make_request
147
57
 
148
- wrapper.close
58
+ expect(last_transaction).to_not have_action
149
59
  end
150
60
 
151
- context "when #close raises an error" do
152
- let(:error) { ExampleException }
153
-
154
- it "records the exception and completes the transaction" do
155
- allow(stream).to receive(:close).and_raise(error)
61
+ it "set `appsignal.action` to the action name" do
62
+ env["appsignal.action"] = "Action"
156
63
 
157
- expect(transaction).to receive(:set_error).with(error)
158
- expect(transaction).to receive(:complete)
64
+ make_request
159
65
 
160
- expect { wrapper.send(:close) }.to raise_error(error)
161
- end
66
+ expect(last_transaction).to have_action("Action")
162
67
  end
163
68
  end
164
69
  end