airbrake 9.1.0 → 9.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -322,7 +322,7 @@ RSpec.describe "Rails integration specs" do
322
322
  end
323
323
  end
324
324
 
325
- context "when an action performs a HTTP request" do
325
+ context "when an action performs a Net::HTTP request" do
326
326
  let!(:example_request) do
327
327
  stub_request(:get, 'http://example.com').to_return(body: '')
328
328
  end
@@ -334,5 +334,97 @@ RSpec.describe "Rails integration specs" do
334
334
  expect(example_request).to have_been_made
335
335
  end
336
336
  end
337
+
338
+ context "when an action performs a Curl request" do
339
+ let!(:example_request) do
340
+ stub_request(:get, 'http://example.com').to_return(body: '')
341
+ end
342
+
343
+ before { skip("JRuby doesn't support Curb") if Airbrake::JRUBY }
344
+
345
+ it "includes the http breakdown" do
346
+ expect(Airbrake).to receive(:notify_performance_breakdown)
347
+ .with(hash_including(groups: { view: be > 0, http: be > 0 }))
348
+ get '/breakdown_curl_http'
349
+ expect(example_request).to have_been_made
350
+ end
351
+ end
352
+
353
+ context "when an action performs a Curl::Easy request" do
354
+ let!(:example_request) do
355
+ stub_request(:get, 'http://example.com').to_return(body: '')
356
+ end
357
+
358
+ before { skip("JRuby doesn't support Curb") if Airbrake::JRUBY }
359
+
360
+ it "includes the http breakdown" do
361
+ expect(Airbrake).to receive(:notify_performance_breakdown)
362
+ .with(hash_including(groups: { view: be > 0, http: be > 0 }))
363
+ get '/breakdown_curl_http_easy'
364
+ expect(example_request).to have_been_made
365
+ end
366
+ end
367
+
368
+ context "when an action performs a Curl::Multi request" do
369
+ before { skip("JRuby doesn't support Curb") if Airbrake::JRUBY }
370
+
371
+ it "includes the http breakdown" do
372
+ expect(Airbrake).to receive(:notify_performance_breakdown)
373
+ .with(hash_including(groups: { view: be > 0, http: be > 0 }))
374
+ get '/breakdown_curl_http_multi'
375
+ end
376
+ end
377
+
378
+ context "when an action performs an Excon request" do
379
+ let!(:example_request) do
380
+ stub_request(:get, 'http://example.com').to_return(body: '')
381
+ end
382
+
383
+ it "includes the http breakdown" do
384
+ expect(Airbrake).to receive(:notify_performance_breakdown)
385
+ .with(hash_including(groups: { http: be > 0 }))
386
+ get '/breakdown_excon'
387
+ expect(example_request).to have_been_made
388
+ end
389
+ end
390
+
391
+ context "when an action performs a HTTP.rb request" do
392
+ let!(:example_request) do
393
+ stub_request(:get, 'http://example.com').to_return(body: '')
394
+ end
395
+
396
+ it "includes the http breakdown" do
397
+ expect(Airbrake).to receive(:notify_performance_breakdown)
398
+ .with(hash_including(groups: { http: be > 0 }))
399
+ get '/breakdown_http_rb'
400
+ expect(example_request).to have_been_made
401
+ end
402
+ end
403
+
404
+ context "when an action performs a HTTPClient request" do
405
+ let!(:example_request) do
406
+ stub_request(:get, 'http://example.com').to_return(body: '')
407
+ end
408
+
409
+ it "includes the http breakdown" do
410
+ expect(Airbrake).to receive(:notify_performance_breakdown)
411
+ .with(hash_including(groups: { http: be > 0 }))
412
+ get '/breakdown_http_client'
413
+ expect(example_request).to have_been_made
414
+ end
415
+ end
416
+
417
+ context "when an action performs a Typhoeus request" do
418
+ let!(:example_request) do
419
+ stub_request(:get, 'http://example.com').to_return(body: '')
420
+ end
421
+
422
+ it "includes the http breakdown" do
423
+ expect(Airbrake).to receive(:notify_performance_breakdown)
424
+ .with(hash_including(groups: { http: be > 0 }))
425
+ get '/breakdown_typhoeus'
426
+ expect(example_request).to have_been_made
427
+ end
428
+ end
337
429
  end
338
430
  end
@@ -0,0 +1,89 @@
1
+ RSpec.describe Airbrake::Rack::Instrumentable do
2
+ after { Airbrake::Rack::RequestStore.clear }
3
+
4
+ describe ".airbrake_capture_timing" do
5
+ let(:routes) { Airbrake::Rack::RequestStore[:routes] }
6
+
7
+ let(:klass) do
8
+ Class.new do
9
+ extend Airbrake::Rack::Instrumentable
10
+
11
+ def method; end
12
+ airbrake_capture_timing :method
13
+
14
+ def method_with_arg(a); end
15
+ airbrake_capture_timing :method_with_arg
16
+
17
+ def method_with_args(a, b); end
18
+ airbrake_capture_timing :method_with_args
19
+
20
+ def method_with_vla(*args); end
21
+ airbrake_capture_timing :method_with_vla
22
+
23
+ def method_with_args_and_vla(*args); end
24
+ airbrake_capture_timing :method_with_args_and_vla
25
+
26
+ def method_with_kwargs(foo:, bar:); end
27
+ airbrake_capture_timing :method_with_kwargs
28
+ end
29
+ end
30
+
31
+ context "when request store doesn't have any routes" do
32
+ before { Airbrake::Rack::RequestStore.clear }
33
+
34
+ it "doesn't store timing of the tracked method" do
35
+ klass.new.method
36
+ expect(Airbrake::Rack::RequestStore.store).to be_empty
37
+ end
38
+ end
39
+
40
+ context "when request store has a route" do
41
+ let(:groups) { routes['/about'][:groups] }
42
+
43
+ before do
44
+ Airbrake::Rack::RequestStore[:routes] = {
45
+ '/about' => {
46
+ method: 'GET',
47
+ response_type: :html,
48
+ groups: {}
49
+ }
50
+ }
51
+ end
52
+
53
+ it "attaches timing for a method without an argument" do
54
+ klass.new.method
55
+ expect(groups).to match('method' => be > 0)
56
+ end
57
+
58
+ it "attaches timing for a method with an argument" do
59
+ klass.new.method_with_arg(1)
60
+ expect(groups).to match('method_with_arg' => be > 0)
61
+ end
62
+
63
+ it "attaches timing for a variable-length argument method" do
64
+ klass.new.method_with_vla(1, 2, 3)
65
+ expect(groups).to match('method_with_vla' => be > 0)
66
+ end
67
+
68
+ it "attaches timing for a method with args and a variable-length array" do
69
+ klass.new.method_with_args_and_vla(1, 2, 3)
70
+ expect(groups).to match('method_with_args_and_vla' => be > 0)
71
+ end
72
+
73
+ it "attaches timing for a method with kwargs" do
74
+ klass.new.method_with_kwargs(foo: 1, bar: 2)
75
+ expect(groups).to match('method_with_kwargs' => be > 0)
76
+ end
77
+
78
+ it "attaches all timings for multiple methods to the request store" do
79
+ klass.new.method
80
+ klass.new.method_with_arg(1)
81
+
82
+ expect(groups).to match(
83
+ 'method' => be > 0,
84
+ 'method_with_arg' => be > 0
85
+ )
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,46 @@
1
+ RSpec.describe Airbrake::Rack do
2
+ after { Airbrake::Rack::RequestStore.clear }
3
+
4
+ describe ".timing" do
5
+ let(:routes) { Airbrake::Rack::RequestStore[:routes] }
6
+
7
+ context "when request store doesn't have any routes" do
8
+ it "doesn't store timing" do
9
+ described_class.capture_timing('operation') {}
10
+ expect(Airbrake::Rack::RequestStore.store).to be_empty
11
+ end
12
+
13
+ it "returns the value of the block" do
14
+ expect(described_class.capture_timing('operation') { 1 }).to eq(1)
15
+ end
16
+ end
17
+
18
+ context "when request store has a route" do
19
+ before do
20
+ Airbrake::Rack::RequestStore[:routes] = {
21
+ '/about' => {
22
+ method: 'GET',
23
+ response_type: :html,
24
+ groups: {}
25
+ }
26
+ }
27
+ end
28
+
29
+ it "attaches all timings for different operations to the request store" do
30
+ described_class.capture_timing('operation 1') {}
31
+ described_class.capture_timing('operation 2') {}
32
+ described_class.capture_timing('operation 3') {}
33
+
34
+ expect(routes['/about'][:groups]).to match(
35
+ 'operation 1' => be > 0,
36
+ 'operation 2' => be > 0,
37
+ 'operation 3' => be > 0
38
+ )
39
+ end
40
+
41
+ it "returns the value of the block" do
42
+ expect(described_class.capture_timing('operation') { 1 }).to eq(1)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ require 'airbrake/rails/excon_subscriber'
2
+
3
+ RSpec.describe Airbrake::Rails::Excon do
4
+ after { Airbrake::Rack::RequestStore.clear }
5
+
6
+ let(:event) { double(Airbrake::Rails::Event) }
7
+
8
+ before do
9
+ allow(Airbrake::Rails::Event).to receive(:new).and_return(event)
10
+ end
11
+
12
+ context "when there are no routes in the request store" do
13
+ it "doesn't notify requests" do
14
+ expect(Airbrake).not_to receive(:notify_performance_breakdown)
15
+ subject.call([])
16
+ end
17
+ end
18
+
19
+ context "when there's a route in the request store" do
20
+ let(:route) { Airbrake::Rack::RequestStore[:routes]['/test-route'] }
21
+
22
+ before do
23
+ Airbrake::Rack::RequestStore[:routes] = {
24
+ '/test-route' => { groups: {} }
25
+ }
26
+
27
+ expect(event).to receive(:duration).and_return(0.1)
28
+ end
29
+
30
+ it "sets http group value of that route" do
31
+ subject.call([])
32
+ expect(route[:groups][:http]).to eq(0.1)
33
+ end
34
+
35
+ context "and when the subscriber is called multiple times" do
36
+ before { expect(event).to receive(:duration).and_return(0.1) }
37
+
38
+ it "increments http group value of that route" do
39
+ subject.call([])
40
+ subject.call([])
41
+
42
+ expect(route[:groups][:http]).to eq(0.2)
43
+ end
44
+ end
45
+ end
46
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: airbrake
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.1.0
4
+ version: 9.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Airbrake Technologies, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-17 00:00:00.000000000 Z
11
+ date: 2019-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: airbrake-ruby
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '4.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '4.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -240,6 +240,76 @@ dependencies:
240
240
  - - "~>"
241
241
  - !ruby/object:Gem::Version
242
242
  version: '5'
243
+ - !ruby/object:Gem::Dependency
244
+ name: curb
245
+ requirement: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - "~>"
248
+ - !ruby/object:Gem::Version
249
+ version: '0.9'
250
+ type: :development
251
+ prerelease: false
252
+ version_requirements: !ruby/object:Gem::Requirement
253
+ requirements:
254
+ - - "~>"
255
+ - !ruby/object:Gem::Version
256
+ version: '0.9'
257
+ - !ruby/object:Gem::Dependency
258
+ name: excon
259
+ requirement: !ruby/object:Gem::Requirement
260
+ requirements:
261
+ - - "~>"
262
+ - !ruby/object:Gem::Version
263
+ version: '0.64'
264
+ type: :development
265
+ prerelease: false
266
+ version_requirements: !ruby/object:Gem::Requirement
267
+ requirements:
268
+ - - "~>"
269
+ - !ruby/object:Gem::Version
270
+ version: '0.64'
271
+ - !ruby/object:Gem::Dependency
272
+ name: http
273
+ requirement: !ruby/object:Gem::Requirement
274
+ requirements:
275
+ - - "~>"
276
+ - !ruby/object:Gem::Version
277
+ version: '2.2'
278
+ type: :development
279
+ prerelease: false
280
+ version_requirements: !ruby/object:Gem::Requirement
281
+ requirements:
282
+ - - "~>"
283
+ - !ruby/object:Gem::Version
284
+ version: '2.2'
285
+ - !ruby/object:Gem::Dependency
286
+ name: httpclient
287
+ requirement: !ruby/object:Gem::Requirement
288
+ requirements:
289
+ - - "~>"
290
+ - !ruby/object:Gem::Version
291
+ version: '2.8'
292
+ type: :development
293
+ prerelease: false
294
+ version_requirements: !ruby/object:Gem::Requirement
295
+ requirements:
296
+ - - "~>"
297
+ - !ruby/object:Gem::Version
298
+ version: '2.8'
299
+ - !ruby/object:Gem::Dependency
300
+ name: typhoeus
301
+ requirement: !ruby/object:Gem::Requirement
302
+ requirements:
303
+ - - "~>"
304
+ - !ruby/object:Gem::Version
305
+ version: '1.3'
306
+ type: :development
307
+ prerelease: false
308
+ version_requirements: !ruby/object:Gem::Requirement
309
+ requirements:
310
+ - - "~>"
311
+ - !ruby/object:Gem::Version
312
+ version: '1.3'
243
313
  description: |
244
314
  Airbrake is an online tool that provides robust exception tracking in any of
245
315
  your Ruby applications. In doing so, it allows you to easily review errors, tie
@@ -266,6 +336,7 @@ files:
266
336
  - lib/airbrake/rack/context_filter.rb
267
337
  - lib/airbrake/rack/http_headers_filter.rb
268
338
  - lib/airbrake/rack/http_params_filter.rb
339
+ - lib/airbrake/rack/instrumentable.rb
269
340
  - lib/airbrake/rack/middleware.rb
270
341
  - lib/airbrake/rack/request_body_filter.rb
271
342
  - lib/airbrake/rack/request_store.rb
@@ -285,8 +356,13 @@ files:
285
356
  - lib/airbrake/rails/active_record_subscriber.rb
286
357
  - lib/airbrake/rails/app.rb
287
358
  - lib/airbrake/rails/backtrace_cleaner.rb
359
+ - lib/airbrake/rails/curb.rb
288
360
  - lib/airbrake/rails/event.rb
361
+ - lib/airbrake/rails/excon_subscriber.rb
362
+ - lib/airbrake/rails/http.rb
363
+ - lib/airbrake/rails/http_client.rb
289
364
  - lib/airbrake/rails/net_http.rb
365
+ - lib/airbrake/rails/typhoeus.rb
290
366
  - lib/airbrake/rake.rb
291
367
  - lib/airbrake/rake/tasks.rb
292
368
  - lib/airbrake/resque.rb
@@ -315,7 +391,9 @@ files:
315
391
  - spec/unit/rack/context_filter_spec.rb
316
392
  - spec/unit/rack/http_headers_filter_spec.rb
317
393
  - spec/unit/rack/http_params_filter_spec.rb
394
+ - spec/unit/rack/instrumentable_spec.rb
318
395
  - spec/unit/rack/middleware_spec.rb
396
+ - spec/unit/rack/rack_spec.rb
319
397
  - spec/unit/rack/request_body_filter_spec.rb
320
398
  - spec/unit/rack/request_store_spec.rb
321
399
  - spec/unit/rack/route_filter_spec.rb
@@ -327,6 +405,7 @@ files:
327
405
  - spec/unit/rails/action_controller_performance_breakdown_subscriber_spec.rb
328
406
  - spec/unit/rails/action_controller_route_subscriber_spec.rb
329
407
  - spec/unit/rails/active_record_subscriber_spec.rb
408
+ - spec/unit/rails/excon_spec.rb
330
409
  - spec/unit/rake/tasks_spec.rb
331
410
  - spec/unit/shoryuken_spec.rb
332
411
  - spec/unit/sidekiq/retryable_jobs_filter_spec.rb
@@ -351,8 +430,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
351
430
  - !ruby/object:Gem::Version
352
431
  version: '0'
353
432
  requirements: []
354
- rubyforge_project:
355
- rubygems_version: 2.6.13
433
+ rubygems_version: 3.0.1
356
434
  signing_key:
357
435
  specification_version: 4
358
436
  summary: Airbrake is an online tool that provides robust exception tracking in any
@@ -369,10 +447,12 @@ test_files:
369
447
  - spec/unit/rack/request_body_filter_spec.rb
370
448
  - spec/unit/rack/http_params_filter_spec.rb
371
449
  - spec/unit/rack/http_headers_filter_spec.rb
450
+ - spec/unit/rack/rack_spec.rb
372
451
  - spec/unit/rack/middleware_spec.rb
373
452
  - spec/unit/rack/session_filter_spec.rb
374
453
  - spec/unit/rack/context_filter_spec.rb
375
454
  - spec/unit/rack/user_filter_spec.rb
455
+ - spec/unit/rack/instrumentable_spec.rb
376
456
  - spec/unit/rack/user_spec.rb
377
457
  - spec/unit/rack/route_filter_spec.rb
378
458
  - spec/unit/rails/action_controller_performance_breakdown_subscriber_spec.rb
@@ -380,6 +460,7 @@ test_files:
380
460
  - spec/unit/rails/action_cable/notify_callback_spec.rb
381
461
  - spec/unit/rails/action_controller_notify_subscriber_spec.rb
382
462
  - spec/unit/rails/action_controller_route_subscriber_spec.rb
463
+ - spec/unit/rails/excon_spec.rb
383
464
  - spec/integration/sinatra/sinatra_spec.rb
384
465
  - spec/integration/rack/rack_spec.rb
385
466
  - spec/integration/shared_examples/rack_examples.rb