appsignal 3.10.0-java → 3.11.0-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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +88 -0
  4. data/Gemfile +1 -0
  5. data/benchmark.rake +99 -42
  6. data/lib/appsignal/cli/demo.rb +0 -1
  7. data/lib/appsignal/config.rb +54 -98
  8. data/lib/appsignal/demo.rb +15 -20
  9. data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
  10. data/lib/appsignal/event_formatter.rb +3 -2
  11. data/lib/appsignal/helpers/instrumentation.rb +331 -19
  12. data/lib/appsignal/hooks/action_cable.rb +21 -16
  13. data/lib/appsignal/hooks/active_job.rb +14 -8
  14. data/lib/appsignal/hooks/delayed_job.rb +1 -1
  15. data/lib/appsignal/hooks/shoryuken.rb +3 -63
  16. data/lib/appsignal/integrations/action_cable.rb +5 -7
  17. data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
  18. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
  19. data/lib/appsignal/integrations/data_mapper.rb +1 -0
  20. data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
  21. data/lib/appsignal/integrations/dry_monitor.rb +1 -0
  22. data/lib/appsignal/integrations/excon.rb +1 -0
  23. data/lib/appsignal/integrations/http.rb +1 -0
  24. data/lib/appsignal/integrations/net_http.rb +1 -0
  25. data/lib/appsignal/integrations/object.rb +6 -0
  26. data/lib/appsignal/integrations/que.rb +13 -20
  27. data/lib/appsignal/integrations/railtie.rb +1 -1
  28. data/lib/appsignal/integrations/rake.rb +1 -5
  29. data/lib/appsignal/integrations/redis.rb +1 -0
  30. data/lib/appsignal/integrations/redis_client.rb +1 -0
  31. data/lib/appsignal/integrations/resque.rb +2 -5
  32. data/lib/appsignal/integrations/shoryuken.rb +75 -0
  33. data/lib/appsignal/integrations/sidekiq.rb +7 -15
  34. data/lib/appsignal/integrations/unicorn.rb +1 -0
  35. data/lib/appsignal/integrations/webmachine.rb +2 -5
  36. data/lib/appsignal/logger.rb +7 -3
  37. data/lib/appsignal/probes/helpers.rb +1 -0
  38. data/lib/appsignal/probes/mri.rb +1 -0
  39. data/lib/appsignal/probes/sidekiq.rb +1 -0
  40. data/lib/appsignal/probes.rb +3 -0
  41. data/lib/appsignal/rack/abstract_middleware.rb +18 -12
  42. data/lib/appsignal/rack/event_handler.rb +39 -8
  43. data/lib/appsignal/rack/generic_instrumentation.rb +1 -0
  44. data/lib/appsignal/rack/grape_middleware.rb +2 -1
  45. data/lib/appsignal/rack/streaming_listener.rb +1 -0
  46. data/lib/appsignal/rack.rb +29 -0
  47. data/lib/appsignal/span.rb +1 -0
  48. data/lib/appsignal/transaction.rb +308 -101
  49. data/lib/appsignal/utils/data.rb +0 -1
  50. data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
  51. data/lib/appsignal/utils/integration_logger.rb +0 -13
  52. data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
  53. data/lib/appsignal/utils/json.rb +0 -1
  54. data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
  55. data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
  56. data/lib/appsignal/utils.rb +6 -0
  57. data/lib/appsignal/version.rb +1 -1
  58. data/lib/appsignal.rb +6 -5
  59. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  60. data/spec/lib/appsignal/config_spec.rb +138 -43
  61. data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
  62. data/spec/lib/appsignal/hooks/activejob_spec.rb +9 -0
  63. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
  64. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
  65. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
  66. data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
  67. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
  68. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -4
  69. data/spec/lib/appsignal/integrations/webmachine_spec.rb +13 -1
  70. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +48 -3
  71. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -10
  72. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
  73. data/spec/lib/appsignal/rack_spec.rb +63 -0
  74. data/spec/lib/appsignal/transaction_spec.rb +1634 -1071
  75. data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
  76. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
  77. data/spec/lib/appsignal_spec.rb +323 -10
  78. data/spec/support/helpers/transaction_helpers.rb +44 -20
  79. data/spec/support/matchers/transaction.rb +15 -1
  80. data/spec/support/testing.rb +1 -1
  81. metadata +6 -2
@@ -18,7 +18,11 @@ if DependencyHelper.webmachine_present?
18
18
  Webmachine::Request.new(
19
19
  "GET",
20
20
  "http://google.com:80/foo?param1=value1&param2=value2",
21
- {},
21
+ {
22
+ "REQUEST_METHOD" => "GET",
23
+ "PATH_INFO" => "/some/path",
24
+ "ignored_header" => "something"
25
+ },
22
26
  nil
23
27
  )
24
28
  end
@@ -81,6 +85,14 @@ if DependencyHelper.webmachine_present?
81
85
  expect(last_transaction).to include_params("param1" => "value1", "param2" => "value2")
82
86
  end
83
87
 
88
+ it "sets the headers" do
89
+ fsm.run
90
+ expect(last_transaction).to include_environment(
91
+ "REQUEST_METHOD" => "GET",
92
+ "PATH_INFO" => "/some/path"
93
+ )
94
+ end
95
+
84
96
  it "closes the transaction" do
85
97
  fsm.run
86
98
  expect(last_transaction).to be_completed
@@ -5,7 +5,8 @@ describe Appsignal::Rack::AbstractMiddleware do
5
5
  Rack::MockRequest.env_for(
6
6
  request_path,
7
7
  "REQUEST_METHOD" => "GET",
8
- :params => { "page" => 2, "query" => "lorem" }
8
+ :params => { "page" => 2, "query" => "lorem" },
9
+ "rack.session" => { "session" => "data", "user_id" => 123 }
9
10
  )
10
11
  end
11
12
  let(:options) { {} }
@@ -247,7 +248,7 @@ describe Appsignal::Rack::AbstractMiddleware do
247
248
  end
248
249
  end
249
250
 
250
- context "with fetching the request method raises an error" do
251
+ context "when fetching the request method raises an error" do
251
252
  class BrokenRequestMethodRequest < Rack::Request
252
253
  def request_method
253
254
  raise "uh oh!"
@@ -255,11 +256,16 @@ describe Appsignal::Rack::AbstractMiddleware do
255
256
  end
256
257
 
257
258
  let(:options) { { :request_class => BrokenRequestMethodRequest } }
259
+
258
260
  it "does not store the invalid HTTP request method" do
259
261
  env["REQUEST_METHOD"] = "FOO"
260
- make_request
262
+ logs = capture_logs { make_request }
261
263
 
262
264
  expect(last_transaction).to_not include_metadata("method" => anything)
265
+ expect(logs).to contains_log(
266
+ :error,
267
+ "Exception while fetching the HTTP request method: RuntimeError: uh oh"
268
+ )
263
269
  end
264
270
  end
265
271
 
@@ -285,6 +291,35 @@ describe Appsignal::Rack::AbstractMiddleware do
285
291
  expect(last_transaction).to include_params("custom" => "param")
286
292
  end
287
293
  end
294
+
295
+ context "when fetching the request method raises an error" do
296
+ class BrokenRequestParamsRequest < Rack::Request
297
+ def params
298
+ raise "uh oh!"
299
+ end
300
+ end
301
+
302
+ let(:options) do
303
+ { :request_class => BrokenRequestParamsRequest, :params_method => :params }
304
+ end
305
+
306
+ it "does not store the invalid HTTP request method" do
307
+ logs = capture_logs { make_request }
308
+
309
+ expect(last_transaction).to_not include_params
310
+ expect(logs).to contains_log(
311
+ :error,
312
+ "Exception while fetching params " \
313
+ "from 'BrokenRequestParamsRequest#params': RuntimeError uh oh!"
314
+ )
315
+ end
316
+ end
317
+
318
+ it "sets session data" do
319
+ make_request
320
+
321
+ expect(last_transaction).to include_session_data("session" => "data", "user_id" => 123)
322
+ end
288
323
  end
289
324
 
290
325
  context "with queue start header" do
@@ -316,6 +351,10 @@ describe Appsignal::Rack::AbstractMiddleware do
316
351
  def filtered_params
317
352
  { "abc" => "123" }
318
353
  end
354
+
355
+ def session
356
+ { "data" => "value" }
357
+ end
319
358
  end
320
359
 
321
360
  context "with overridden request class and params method" do
@@ -328,6 +367,12 @@ describe Appsignal::Rack::AbstractMiddleware do
328
367
 
329
368
  expect(last_transaction).to include_params("abc" => "123")
330
369
  end
370
+
371
+ it "uses the overridden request class to fetch session data" do
372
+ make_request
373
+
374
+ expect(last_transaction).to include_session_data("data" => "value")
375
+ end
331
376
  end
332
377
 
333
378
  context "with parent instrumentation" do
@@ -3,8 +3,11 @@ describe Appsignal::Rack::EventHandler do
3
3
  let(:env) do
4
4
  {
5
5
  "HTTP_X_REQUEST_START" => "t=#{queue_start_time.to_i}", # in milliseconds
6
- "REQUEST_METHOD" => "GET",
7
- "PATH_INFO" => "/path"
6
+ "REQUEST_METHOD" => "POST",
7
+ "PATH_INFO" => "/path",
8
+ "QUERY_STRING" => "query_param1=value1&query_param2=value2",
9
+ "rack.session" => { "session1" => "value1", "session2" => "value2" },
10
+ "rack.input" => StringIO.new("post_param1=value1&post_param2=value2")
8
11
  }
9
12
  end
10
13
  let(:request) { Rack::Request.new(env) }
@@ -172,20 +175,93 @@ describe Appsignal::Rack::EventHandler do
172
175
  expect(last_transaction).to_not be_completed
173
176
  end
174
177
 
175
- it "completes the transaction" do
178
+ it "sets params on the transaction" do
179
+ on_start
180
+ on_finish
181
+
182
+ expect(last_transaction).to include_params(
183
+ "query_param1" => "value1",
184
+ "query_param2" => "value2",
185
+ "post_param1" => "value1",
186
+ "post_param2" => "value2"
187
+ )
188
+ end
189
+
190
+ it "sets headers on the transaction" do
176
191
  on_start
177
192
  on_finish
178
193
 
179
- expect(last_transaction).to_not have_action
180
194
  expect(last_transaction).to include_environment(
181
- "REQUEST_METHOD" => "GET",
195
+ "REQUEST_METHOD" => "POST",
182
196
  "PATH_INFO" => "/path"
183
197
  )
198
+ end
199
+
200
+ it "sets session data on the transaction" do
201
+ on_start
202
+ on_finish
203
+
204
+ expect(last_transaction).to include_session_data(
205
+ "session1" => "value1",
206
+ "session2" => "value2"
207
+ )
208
+ end
209
+
210
+ it "sets the queue start time on the transaction" do
211
+ on_start
212
+ on_finish
213
+
184
214
  expect(last_transaction).to have_queue_start(queue_start_time)
215
+ end
216
+
217
+ it "completes the transaction" do
218
+ on_start
219
+ on_finish
220
+
221
+ expect(last_transaction).to_not have_action
185
222
  expect(last_transaction).to be_completed
186
223
  end
187
224
 
188
225
  context "without a response" do
226
+ it "sets params on the transaction" do
227
+ on_start
228
+ on_finish
229
+
230
+ expect(last_transaction).to include_params(
231
+ "query_param1" => "value1",
232
+ "query_param2" => "value2",
233
+ "post_param1" => "value1",
234
+ "post_param2" => "value2"
235
+ )
236
+ end
237
+
238
+ it "sets headers on the transaction" do
239
+ on_start
240
+ on_finish
241
+
242
+ expect(last_transaction).to include_environment(
243
+ "REQUEST_METHOD" => "POST",
244
+ "PATH_INFO" => "/path"
245
+ )
246
+ end
247
+
248
+ it "sets session data on the transaction" do
249
+ on_start
250
+ on_finish
251
+
252
+ expect(last_transaction).to include_session_data(
253
+ "session1" => "value1",
254
+ "session2" => "value2"
255
+ )
256
+ end
257
+
258
+ it "sets the queue start time on the transaction" do
259
+ on_start
260
+ on_finish
261
+
262
+ expect(last_transaction).to have_queue_start(queue_start_time)
263
+ end
264
+
189
265
  it "completes the transaction" do
190
266
  on_start
191
267
  on_finish(request, nil)
@@ -193,11 +269,6 @@ describe Appsignal::Rack::EventHandler do
193
269
  # The action is not set on purpose, as we can't set a normalized route
194
270
  # It requires the app to set an action name
195
271
  expect(last_transaction).to_not have_action
196
- expect(last_transaction).to include_environment(
197
- "REQUEST_METHOD" => "GET",
198
- "PATH_INFO" => "/path"
199
- )
200
- expect(last_transaction).to have_queue_start(queue_start_time)
201
272
  expect(last_transaction).to be_completed
202
273
  end
203
274
 
@@ -114,8 +114,10 @@ if DependencyHelper.rails_present?
114
114
  make_request
115
115
 
116
116
  expect(last_transaction).to_not include_metadata("method" => anything)
117
- expect(log_contents(log))
118
- .to contains_log(:error, "Unable to report HTTP request method: '")
117
+ expect(log_contents(log)).to contains_log(
118
+ :error,
119
+ "Exception while fetching the HTTP request method: "
120
+ )
119
121
  end
120
122
  end
121
123
 
@@ -0,0 +1,63 @@
1
+ describe Appsignal::Rack::Utils do
2
+ describe ".queue_start_from" do
3
+ let(:header_time) { fixed_time - 0.4 }
4
+ let(:header_time_value) { (header_time * factor).to_i }
5
+ subject { described_class.queue_start_from(env) }
6
+
7
+ shared_examples "HTTP queue start" do
8
+ context "when env is nil" do
9
+ let(:env) { nil }
10
+
11
+ it { is_expected.to be_nil }
12
+ end
13
+
14
+ context "with no relevant header set" do
15
+ let(:env) { {} }
16
+
17
+ it { is_expected.to be_nil }
18
+ end
19
+
20
+ context "with the HTTP_X_REQUEST_START header set" do
21
+ let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time_value}" } }
22
+
23
+ it { is_expected.to eq 1_389_783_599_600 }
24
+
25
+ context "with unparsable content" do
26
+ let(:env) { { "HTTP_X_REQUEST_START" => "something" } }
27
+
28
+ it { is_expected.to be_nil }
29
+ end
30
+
31
+ context "with unparsable content at the end" do
32
+ let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time_value}aaaa" } }
33
+
34
+ it { is_expected.to eq 1_389_783_599_600 }
35
+ end
36
+
37
+ context "with a really low number" do
38
+ let(:env) { { "HTTP_X_REQUEST_START" => "t=100" } }
39
+
40
+ it { is_expected.to be_nil }
41
+ end
42
+
43
+ context "with the alternate HTTP_X_QUEUE_START header set" do
44
+ let(:env) { { "HTTP_X_QUEUE_START" => "t=#{header_time_value}" } }
45
+
46
+ it { is_expected.to eq 1_389_783_599_600 }
47
+ end
48
+ end
49
+ end
50
+
51
+ context "time in milliseconds" do
52
+ let(:factor) { 1_000 }
53
+
54
+ it_should_behave_like "HTTP queue start"
55
+ end
56
+
57
+ context "time in microseconds" do
58
+ let(:factor) { 1_000_000 }
59
+
60
+ it_should_behave_like "HTTP queue start"
61
+ end
62
+ end
63
+ end