appsignal 3.9.3-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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +22 -19
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +180 -0
  5. data/Gemfile +1 -0
  6. data/README.md +0 -1
  7. data/Rakefile +1 -1
  8. data/benchmark.rake +99 -42
  9. data/build_matrix.yml +10 -12
  10. data/gemfiles/webmachine1.gemfile +5 -4
  11. data/lib/appsignal/cli/demo.rb +0 -1
  12. data/lib/appsignal/config.rb +57 -97
  13. data/lib/appsignal/demo.rb +15 -20
  14. data/lib/appsignal/environment.rb +6 -1
  15. data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
  16. data/lib/appsignal/event_formatter.rb +3 -2
  17. data/lib/appsignal/helpers/instrumentation.rb +490 -16
  18. data/lib/appsignal/hooks/action_cable.rb +21 -16
  19. data/lib/appsignal/hooks/active_job.rb +15 -14
  20. data/lib/appsignal/hooks/delayed_job.rb +1 -1
  21. data/lib/appsignal/hooks/shoryuken.rb +3 -63
  22. data/lib/appsignal/integrations/action_cable.rb +5 -7
  23. data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
  24. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
  25. data/lib/appsignal/integrations/data_mapper.rb +1 -0
  26. data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
  27. data/lib/appsignal/integrations/dry_monitor.rb +1 -0
  28. data/lib/appsignal/integrations/excon.rb +1 -0
  29. data/lib/appsignal/integrations/http.rb +1 -0
  30. data/lib/appsignal/integrations/net_http.rb +1 -0
  31. data/lib/appsignal/integrations/object.rb +6 -0
  32. data/lib/appsignal/integrations/padrino.rb +21 -25
  33. data/lib/appsignal/integrations/que.rb +13 -20
  34. data/lib/appsignal/integrations/railtie.rb +1 -1
  35. data/lib/appsignal/integrations/rake.rb +45 -15
  36. data/lib/appsignal/integrations/redis.rb +1 -0
  37. data/lib/appsignal/integrations/redis_client.rb +1 -0
  38. data/lib/appsignal/integrations/resque.rb +2 -5
  39. data/lib/appsignal/integrations/shoryuken.rb +75 -0
  40. data/lib/appsignal/integrations/sidekiq.rb +7 -25
  41. data/lib/appsignal/integrations/unicorn.rb +1 -0
  42. data/lib/appsignal/integrations/webmachine.rb +12 -9
  43. data/lib/appsignal/logger.rb +7 -3
  44. data/lib/appsignal/probes/helpers.rb +1 -0
  45. data/lib/appsignal/probes/mri.rb +1 -0
  46. data/lib/appsignal/probes/sidekiq.rb +1 -0
  47. data/lib/appsignal/probes.rb +3 -0
  48. data/lib/appsignal/rack/abstract_middleware.rb +67 -24
  49. data/lib/appsignal/rack/body_wrapper.rb +143 -0
  50. data/lib/appsignal/rack/event_handler.rb +39 -8
  51. data/lib/appsignal/rack/generic_instrumentation.rb +6 -4
  52. data/lib/appsignal/rack/grape_middleware.rb +3 -2
  53. data/lib/appsignal/rack/hanami_middleware.rb +1 -1
  54. data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
  55. data/lib/appsignal/rack/rails_instrumentation.rb +1 -3
  56. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
  57. data/lib/appsignal/rack/streaming_listener.rb +14 -59
  58. data/lib/appsignal/rack.rb +60 -0
  59. data/lib/appsignal/span.rb +1 -0
  60. data/lib/appsignal/transaction.rb +353 -104
  61. data/lib/appsignal/utils/data.rb +0 -1
  62. data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
  63. data/lib/appsignal/utils/integration_logger.rb +0 -13
  64. data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
  65. data/lib/appsignal/utils/json.rb +0 -1
  66. data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
  67. data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
  68. data/lib/appsignal/utils.rb +6 -0
  69. data/lib/appsignal/version.rb +1 -1
  70. data/lib/appsignal.rb +9 -6
  71. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  72. data/spec/lib/appsignal/config_spec.rb +139 -43
  73. data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
  74. data/spec/lib/appsignal/hooks/activejob_spec.rb +9 -0
  75. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
  76. data/spec/lib/appsignal/hooks/rake_spec.rb +100 -17
  77. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
  78. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
  79. data/spec/lib/appsignal/integrations/padrino_spec.rb +181 -131
  80. data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
  81. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
  82. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -4
  83. data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -2
  84. data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -17
  85. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +144 -11
  86. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
  87. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -10
  88. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -17
  89. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +1 -1
  90. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
  91. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
  92. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +43 -120
  93. data/spec/lib/appsignal/rack_spec.rb +63 -0
  94. data/spec/lib/appsignal/transaction_spec.rb +1675 -953
  95. data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
  96. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
  97. data/spec/lib/appsignal_spec.rb +517 -13
  98. data/spec/support/helpers/transaction_helpers.rb +44 -20
  99. data/spec/support/matchers/transaction.rb +15 -1
  100. data/spec/support/mocks/dummy_app.rb +1 -1
  101. data/spec/support/testing.rb +1 -1
  102. metadata +12 -4
  103. data/support/check_versions +0 -22
@@ -14,13 +14,6 @@ describe Appsignal::Hooks::ActionCableHook do
14
14
  end
15
15
 
16
16
  describe ActionCable::Channel::Base do
17
- let(:transaction) do
18
- Appsignal::Transaction.new(
19
- transaction_id,
20
- Appsignal::Transaction::ACTION_CABLE,
21
- ActionDispatch::Request.new(env)
22
- )
23
- end
24
17
  let(:channel) do
25
18
  Class.new(ActionCable::Channel::Base) do
26
19
  def speak(_data)
@@ -37,21 +30,20 @@ describe Appsignal::Hooks::ActionCableHook do
37
30
  s.config.logger = ActiveSupport::Logger.new(log)
38
31
  end
39
32
  end
33
+ let(:env) do
34
+ http_request_env_with_data(
35
+ "action_dispatch.request_id" => request_id,
36
+ :params => params,
37
+ :with_queue_start => true
38
+ )
39
+ end
40
40
  let(:connection) { ActionCable::Connection::Base.new(server, env) }
41
41
  let(:identifier) { { :channel => "MyChannel" }.to_json }
42
42
  let(:params) { {} }
43
43
  let(:request_id) { SecureRandom.uuid }
44
- let(:transaction_id) { request_id }
45
- let(:env) do
46
- http_request_env_with_data("action_dispatch.request_id" => request_id, :params => params)
47
- end
48
44
  let(:instance) { channel.new(connection, identifier, params) }
49
45
  before do
50
46
  start_agent
51
- expect(Appsignal.active?).to be_truthy
52
- transaction
53
-
54
- set_current_transaction(transaction)
55
47
 
56
48
  # Stub transmit call for subscribe/unsubscribe tests
57
49
  allow(connection).to receive(:websocket)
@@ -64,7 +56,7 @@ describe Appsignal::Hooks::ActionCableHook do
64
56
  instance.perform_action("message" => "foo", "action" => "speak")
65
57
 
66
58
  transaction = last_transaction
67
- expect(transaction).to have_id(transaction_id)
59
+ expect(transaction).to have_id
68
60
  expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
69
61
  expect(transaction).to have_action("MyChannel#speak")
70
62
  expect(transaction).to_not have_error
@@ -83,40 +75,20 @@ describe Appsignal::Hooks::ActionCableHook do
83
75
  "action" => "speak",
84
76
  "message" => "foo"
85
77
  )
78
+ expect(transaction).to include_tags("request_id" => request_id)
79
+ expect(transaction).to_not have_queue_start
80
+ expect(transaction).to be_completed
86
81
  end
87
82
 
88
83
  context "without request_id (standalone server)" do
89
84
  let(:request_id) { nil }
90
- let(:transaction_id) { SecureRandom.uuid }
91
- let(:action_transaction) do
92
- Appsignal::Transaction.new(
93
- transaction_id,
94
- Appsignal::Transaction::ACTION_CABLE,
95
- ActionDispatch::Request.new(env)
96
- )
97
- end
98
- before do
99
- # Stub future (private AppSignal) transaction id generated by the hook.
100
- expect(SecureRandom).to receive(:uuid).and_return(transaction_id)
101
- end
102
85
 
103
- it "uses its own internal request_id set by the subscribed callback" do
86
+ it "sets a generated request ID" do
104
87
  # Subscribe action, sets the request_id
105
88
  instance.subscribe_to_channel
106
- expect(transaction).to have_id(transaction_id)
107
-
108
- # Expect another transaction for the action.
109
- # This transaction will use the same request_id as the
110
- # transaction id used to subscribe to the channel.
111
- expect(Appsignal::Transaction).to receive(:create).with(
112
- transaction_id,
113
- Appsignal::Transaction::ACTION_CABLE,
114
- kind_of(ActionDispatch::Request)
115
- ).and_return(action_transaction)
116
- allow(Appsignal::Transaction).to receive(:current).and_return(action_transaction)
117
89
 
118
90
  instance.perform_action("message" => "foo", "action" => "speak")
119
- expect(action_transaction).to have_id(transaction_id)
91
+ expect(last_transaction).to include_tags("request_id" => kind_of(String))
120
92
  end
121
93
  end
122
94
 
@@ -139,7 +111,7 @@ describe Appsignal::Hooks::ActionCableHook do
139
111
  end.to raise_error(ExampleException)
140
112
 
141
113
  transaction = last_transaction
142
- expect(transaction).to have_id(transaction_id)
114
+ expect(transaction).to have_id
143
115
  expect(transaction).to have_action("MyChannel#speak")
144
116
  expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
145
117
  expect(transaction).to have_error("ExampleException", "oh no!")
@@ -151,6 +123,8 @@ describe Appsignal::Hooks::ActionCableHook do
151
123
  "action" => "speak",
152
124
  "message" => "foo"
153
125
  )
126
+ expect(transaction).to_not have_queue_start
127
+ expect(transaction).to be_completed
154
128
  end
155
129
  end
156
130
  end
@@ -162,7 +136,7 @@ describe Appsignal::Hooks::ActionCableHook do
162
136
  instance.subscribe_to_channel
163
137
 
164
138
  transaction = last_transaction
165
- expect(transaction).to have_id(transaction_id)
139
+ expect(transaction).to have_id
166
140
  expect(transaction).to have_action("MyChannel#subscribed")
167
141
  expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
168
142
  expect(transaction).to_not have_error
@@ -178,18 +152,17 @@ describe Appsignal::Hooks::ActionCableHook do
178
152
  "name" => "subscribed.action_cable",
179
153
  "title" => ""
180
154
  )
155
+ expect(transaction).to include_tags("request_id" => request_id)
156
+ expect(transaction).to_not have_queue_start
157
+ expect(transaction).to be_completed
181
158
  end
182
159
 
183
160
  context "without request_id (standalone server)" do
184
161
  let(:request_id) { nil }
185
- let(:transaction_id) { SecureRandom.uuid }
186
- before do
187
- allow(SecureRandom).to receive(:uuid).and_return(transaction_id)
188
- instance.subscribe_to_channel
189
- end
162
+ before { instance.subscribe_to_channel }
190
163
 
191
- it "uses its own internal request_id" do
192
- expect(last_transaction).to have_id(transaction_id)
164
+ it "sets a generated request ID" do
165
+ expect(last_transaction).to include_tags("request_id" => kind_of(String))
193
166
  end
194
167
  end
195
168
 
@@ -212,7 +185,7 @@ describe Appsignal::Hooks::ActionCableHook do
212
185
  end.to raise_error(ExampleException)
213
186
 
214
187
  transaction = last_transaction
215
- expect(transaction).to have_id(transaction_id)
188
+ expect(transaction).to have_id
216
189
  expect(transaction).to have_action("MyChannel#subscribed")
217
190
  expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
218
191
  expect(transaction).to have_error("ExampleException", "oh no!")
@@ -221,23 +194,20 @@ describe Appsignal::Hooks::ActionCableHook do
221
194
  "path" => "/blog"
222
195
  )
223
196
  expect(transaction).to include_params("internal" => "true")
197
+ expect(transaction).to_not have_queue_start
198
+ expect(transaction).to be_completed
224
199
  end
225
200
  end
226
201
 
227
202
  if DependencyHelper.rails6_present?
228
203
  context "with ConnectionStub" do
229
204
  let(:connection) { ActionCable::Channel::ConnectionStub.new }
230
- let(:transaction_id) { "Stubbed transaction id" }
231
- before do
232
- # Stub future (private AppSignal) transaction id generated by the hook.
233
- expect(SecureRandom).to receive(:uuid).and_return(transaction_id)
234
- end
235
205
 
236
206
  it "does not fail on missing `#env` method on `ConnectionStub`" do
237
207
  instance.subscribe_to_channel
238
208
 
239
209
  transaction = last_transaction
240
- expect(transaction).to have_id(transaction_id)
210
+ expect(transaction).to have_id
241
211
  expect(transaction).to have_action("MyChannel#subscribed")
242
212
  expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
243
213
  expect(transaction).to_not have_error
@@ -245,7 +215,7 @@ describe Appsignal::Hooks::ActionCableHook do
245
215
  "method" => "websocket",
246
216
  "path" => "" # No path as the ConnectionStub doesn't have the real request env
247
217
  )
248
- expect(transaction).to include_params("internal" => "true")
218
+ expect(transaction).to_not include_params
249
219
  expect(transaction).to include_event(
250
220
  "body" => "",
251
221
  "body_format" => Appsignal::EventFormatter::DEFAULT,
@@ -253,6 +223,8 @@ describe Appsignal::Hooks::ActionCableHook do
253
223
  "name" => "subscribed.action_cable",
254
224
  "title" => ""
255
225
  )
226
+ expect(transaction).to_not have_queue_start
227
+ expect(transaction).to be_completed
256
228
  end
257
229
  end
258
230
  end
@@ -265,7 +237,7 @@ describe Appsignal::Hooks::ActionCableHook do
265
237
  instance.unsubscribe_from_channel
266
238
 
267
239
  transaction = last_transaction
268
- expect(transaction).to have_id(transaction_id)
240
+ expect(transaction).to have_id
269
241
  expect(transaction).to have_action("MyChannel#unsubscribed")
270
242
  expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
271
243
  expect(transaction).to_not have_error
@@ -281,18 +253,16 @@ describe Appsignal::Hooks::ActionCableHook do
281
253
  "name" => "unsubscribed.action_cable",
282
254
  "title" => ""
283
255
  )
256
+ expect(transaction).to_not have_queue_start
257
+ expect(transaction).to be_completed
284
258
  end
285
259
 
286
260
  context "without request_id (standalone server)" do
287
261
  let(:request_id) { nil }
288
- let(:transaction_id) { SecureRandom.uuid }
289
- before do
290
- allow(SecureRandom).to receive(:uuid).and_return(transaction_id)
291
- instance.unsubscribe_from_channel
292
- end
262
+ before { instance.unsubscribe_from_channel }
293
263
 
294
- it "uses its own internal request_id" do
295
- expect(transaction).to have_id(transaction_id)
264
+ it "sets a generated request ID" do
265
+ expect(last_transaction).to include_tags("request_id" => kind_of(String))
296
266
  end
297
267
  end
298
268
 
@@ -315,7 +285,7 @@ describe Appsignal::Hooks::ActionCableHook do
315
285
  end.to raise_error(ExampleException)
316
286
 
317
287
  transaction = last_transaction
318
- expect(transaction).to have_id(transaction_id)
288
+ expect(transaction).to have_id
319
289
  expect(transaction).to have_action("MyChannel#unsubscribed")
320
290
  expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
321
291
  expect(transaction).to have_error("ExampleException", "oh no!")
@@ -324,23 +294,20 @@ describe Appsignal::Hooks::ActionCableHook do
324
294
  "path" => "/blog"
325
295
  )
326
296
  expect(transaction).to include_params("internal" => "true")
297
+ expect(transaction).to_not have_queue_start
298
+ expect(transaction).to be_completed
327
299
  end
328
300
  end
329
301
 
330
302
  if DependencyHelper.rails6_present?
331
303
  context "with ConnectionStub" do
332
304
  let(:connection) { ActionCable::Channel::ConnectionStub.new }
333
- let(:transaction_id) { "Stubbed transaction id" }
334
- before do
335
- # Stub future (private AppSignal) transaction id generated by the hook.
336
- expect(SecureRandom).to receive(:uuid).and_return(transaction_id)
337
- end
338
305
 
339
306
  it "does not fail on missing `#env` method on `ConnectionStub`" do
340
307
  instance.unsubscribe_from_channel
341
308
 
342
309
  transaction = last_transaction
343
- expect(transaction).to have_id(transaction_id)
310
+ expect(transaction).to have_id
344
311
  expect(transaction).to have_action("MyChannel#unsubscribed")
345
312
  expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
346
313
  expect(transaction).to_not have_error
@@ -348,7 +315,7 @@ describe Appsignal::Hooks::ActionCableHook do
348
315
  "method" => "websocket",
349
316
  "path" => "" # No path as the ConnectionStub doesn't have the real request env
350
317
  )
351
- expect(transaction).to include_params("internal" => "true")
318
+ expect(transaction).to_not include_params
352
319
  expect(transaction).to include_event(
353
320
  "body" => "",
354
321
  "body_format" => Appsignal::EventFormatter::DEFAULT,
@@ -356,6 +323,8 @@ describe Appsignal::Hooks::ActionCableHook do
356
323
  "name" => "unsubscribed.action_cable",
357
324
  "title" => ""
358
325
  )
326
+ expect(transaction).to_not have_queue_start
327
+ expect(transaction).to be_completed
359
328
  end
360
329
  end
361
330
  end
@@ -126,6 +126,7 @@ if DependencyHelper.active_job_present?
126
126
  expect(transaction).to include_params([])
127
127
  expect(transaction).to include_tags(
128
128
  "active_job_id" => kind_of(String),
129
+ "request_id" => kind_of(String),
129
130
  "queue" => queue,
130
131
  "executions" => 1
131
132
  )
@@ -196,6 +197,7 @@ if DependencyHelper.active_job_present?
196
197
  expect(transaction).to include_params([])
197
198
  expect(transaction).to include_tags(
198
199
  "active_job_id" => kind_of(String),
200
+ "request_id" => kind_of(String),
199
201
  "queue" => queue,
200
202
  "executions" => 1
201
203
  )
@@ -335,6 +337,7 @@ if DependencyHelper.active_job_present?
335
337
  expect(transaction).to include_params([])
336
338
  expect(transaction).to include_tags(
337
339
  "active_job_id" => kind_of(String),
340
+ "request_id" => kind_of(String),
338
341
  "queue" => queue,
339
342
  "executions" => 1
340
343
  )
@@ -470,6 +473,7 @@ if DependencyHelper.active_job_present?
470
473
  )
471
474
  expect(transaction).to include_tags(
472
475
  "active_job_id" => kind_of(String),
476
+ "request_id" => kind_of(String),
473
477
  "queue" => "mailers",
474
478
  "executions" => 1
475
479
  )
@@ -488,6 +492,7 @@ if DependencyHelper.active_job_present?
488
492
  )
489
493
  expect(transaction).to include_tags(
490
494
  "active_job_id" => kind_of(String),
495
+ "request_id" => kind_of(String),
491
496
  "queue" => "mailers",
492
497
  "executions" => 1
493
498
  )
@@ -510,6 +515,7 @@ if DependencyHelper.active_job_present?
510
515
  )
511
516
  expect(transaction).to include_tags(
512
517
  "active_job_id" => kind_of(String),
518
+ "request_id" => kind_of(String),
513
519
  "queue" => "mailers",
514
520
  "executions" => 1
515
521
  )
@@ -549,6 +555,7 @@ if DependencyHelper.active_job_present?
549
555
  )
550
556
  expect(transaction).to include_tags(
551
557
  "active_job_id" => kind_of(String),
558
+ "request_id" => kind_of(String),
552
559
  "queue" => "mailers",
553
560
  "executions" => 1
554
561
  )
@@ -573,6 +580,7 @@ if DependencyHelper.active_job_present?
573
580
  )
574
581
  expect(transaction).to include_tags(
575
582
  "active_job_id" => kind_of(String),
583
+ "request_id" => kind_of(String),
576
584
  "queue" => "mailers",
577
585
  "executions" => 1
578
586
  )
@@ -599,6 +607,7 @@ if DependencyHelper.active_job_present?
599
607
  )
600
608
  expect(transaction).to include_tags(
601
609
  "active_job_id" => kind_of(String),
610
+ "request_id" => kind_of(String),
602
611
  "queue" => "mailers",
603
612
  "executions" => 1
604
613
  )