airbrake 9.5.0 → 11.0.1
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.
- checksums.yaml +4 -4
- data/lib/airbrake.rb +2 -0
- data/lib/airbrake/capistrano.rb +2 -0
- data/lib/airbrake/capistrano/capistrano2.rb +2 -0
- data/lib/airbrake/capistrano/capistrano3.rb +3 -1
- data/lib/airbrake/delayed_job.rb +24 -6
- data/lib/airbrake/logger.rb +2 -0
- data/lib/airbrake/rack.rb +4 -0
- data/lib/airbrake/rack/context_filter.rb +9 -2
- data/lib/airbrake/rack/http_headers_filter.rb +7 -5
- data/lib/airbrake/rack/http_params_filter.rb +2 -0
- data/lib/airbrake/rack/instrumentable.rb +112 -4
- data/lib/airbrake/rack/middleware.rb +3 -1
- data/lib/airbrake/rack/request_body_filter.rb +2 -0
- data/lib/airbrake/rack/request_store.rb +2 -0
- data/lib/airbrake/rack/route_filter.rb +8 -10
- data/lib/airbrake/rack/session_filter.rb +2 -0
- data/lib/airbrake/rack/user.rb +4 -0
- data/lib/airbrake/rack/user_filter.rb +2 -0
- data/lib/airbrake/rails.rb +8 -8
- data/lib/airbrake/rails/action_cable.rb +2 -0
- data/lib/airbrake/rails/action_cable/notify_callback.rb +2 -0
- data/lib/airbrake/rails/action_controller.rb +5 -0
- data/lib/airbrake/rails/action_controller_notify_subscriber.rb +6 -2
- data/lib/airbrake/rails/action_controller_performance_breakdown_subscriber.rb +6 -1
- data/lib/airbrake/rails/action_controller_route_subscriber.rb +8 -21
- data/lib/airbrake/rails/active_job.rb +25 -8
- data/lib/airbrake/rails/active_record.rb +2 -0
- data/lib/airbrake/rails/active_record_subscriber.rb +7 -3
- data/lib/airbrake/rails/app.rb +60 -25
- data/lib/airbrake/rails/backtrace_cleaner.rb +13 -0
- data/lib/airbrake/rails/curb.rb +19 -22
- data/lib/airbrake/rails/event.rb +4 -6
- data/lib/airbrake/rails/excon_subscriber.rb +4 -0
- data/lib/airbrake/rails/http.rb +2 -0
- data/lib/airbrake/rails/http_client.rb +12 -6
- data/lib/airbrake/rails/net_http.rb +14 -6
- data/lib/airbrake/rails/railtie.rb +55 -45
- data/lib/airbrake/rails/typhoeus.rb +11 -7
- data/lib/airbrake/rake.rb +3 -1
- data/lib/airbrake/rake/tasks.rb +7 -5
- data/lib/airbrake/resque.rb +32 -0
- data/lib/airbrake/shoryuken.rb +17 -3
- data/lib/airbrake/sidekiq.rb +22 -14
- data/lib/airbrake/sidekiq/retryable_jobs_filter.rb +2 -0
- data/lib/airbrake/sneakers.rb +39 -1
- data/lib/airbrake/version.rb +3 -1
- data/lib/generators/airbrake_generator.rb +2 -0
- data/lib/generators/airbrake_initializer.rb.erb +5 -3
- metadata +61 -90
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'airbrake/rails/event'
|
2
4
|
|
3
5
|
module Airbrake
|
@@ -6,6 +8,8 @@ module Airbrake
|
|
6
8
|
# @since v9.2.0
|
7
9
|
class Excon
|
8
10
|
def call(*args)
|
11
|
+
return unless Airbrake::Config.instance.performance_stats
|
12
|
+
|
9
13
|
routes = Airbrake::Rack::RequestStore[:routes]
|
10
14
|
return if !routes || routes.none?
|
11
15
|
|
data/lib/airbrake/rails/http.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
|
-
#
|
2
|
-
class HTTPClient
|
3
|
-
alias do_get_without_airbrake do_get_block
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module Airbrake
|
4
|
+
module Rails
|
5
|
+
# Allows measuring request timing.
|
6
|
+
module HTTPClient
|
7
|
+
def do_get_block(request, proxy, connection, &block)
|
8
|
+
Airbrake::Rack.capture_timing(:http) do
|
9
|
+
super(request, proxy, connection, &block)
|
10
|
+
end
|
11
|
+
end
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
15
|
+
|
16
|
+
HTTPClient.prepend(Airbrake::Rails::HTTPClient)
|
@@ -1,10 +1,18 @@
|
|
1
|
-
#
|
2
|
-
Net::HTTP.class_eval do
|
3
|
-
alias_method :request_without_airbrake, :request
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module Airbrake
|
4
|
+
module Rails
|
5
|
+
# Monkey-patch Net::HTTP to benchmark it.
|
6
|
+
# @api private
|
7
|
+
# @since v10.0.2
|
8
|
+
module NetHttp
|
9
|
+
def request(request, *args, &block)
|
10
|
+
Airbrake::Rack.capture_timing(:http) do
|
11
|
+
super(request, *args, &block)
|
12
|
+
end
|
13
|
+
end
|
8
14
|
end
|
9
15
|
end
|
10
16
|
end
|
17
|
+
|
18
|
+
Net::HTTP.prepend(Airbrake::Rails::NetHttp)
|
@@ -1,8 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Airbrake
|
2
4
|
module Rails
|
3
5
|
# This railtie works for any Rails application that supports railties (Rails
|
4
6
|
# 3.2+ apps). It makes Airbrake Ruby work with Rails and report errors
|
5
7
|
# occurring in the application automatically.
|
8
|
+
#
|
9
|
+
# rubocop:disable Metrics/BlockLength
|
6
10
|
class Railtie < ::Rails::Railtie
|
7
11
|
initializer('airbrake.middleware') do |app|
|
8
12
|
# Since Rails 3.2 the ActionDispatch::DebugExceptions middleware is
|
@@ -16,20 +20,20 @@ module Airbrake
|
|
16
20
|
# exist in Rails 5 anymore.
|
17
21
|
app.config.middleware.insert_after(
|
18
22
|
ActionDispatch::DebugExceptions,
|
19
|
-
Airbrake::Rack::Middleware
|
23
|
+
Airbrake::Rack::Middleware,
|
20
24
|
)
|
21
25
|
elsif defined?(::ActiveRecord::ConnectionAdapters::ConnectionManagement)
|
22
26
|
# Insert after ConnectionManagement to avoid DB connection leakage:
|
23
27
|
# https://github.com/airbrake/airbrake/pull/568
|
24
28
|
app.config.middleware.insert_after(
|
25
29
|
::ActiveRecord::ConnectionAdapters::ConnectionManagement,
|
26
|
-
'Airbrake::Rack::Middleware'
|
30
|
+
'Airbrake::Rack::Middleware',
|
27
31
|
)
|
28
32
|
else
|
29
33
|
# Insert after DebugExceptions for apps without ActiveRecord.
|
30
34
|
app.config.middleware.insert_after(
|
31
35
|
ActionDispatch::DebugExceptions,
|
32
|
-
'Airbrake::Rack::Middleware'
|
36
|
+
'Airbrake::Rack::Middleware',
|
33
37
|
)
|
34
38
|
end
|
35
39
|
end
|
@@ -42,7 +46,6 @@ module Airbrake
|
|
42
46
|
require 'airbrake/rake/tasks'
|
43
47
|
end
|
44
48
|
|
45
|
-
# rubocop:disable Metrics/BlockLength
|
46
49
|
initializer('airbrake.action_controller') do
|
47
50
|
ActiveSupport.on_load(:action_controller, run_once: true) do
|
48
51
|
# Patches ActionController with methods that allow us to retrieve
|
@@ -50,56 +53,52 @@ module Airbrake
|
|
50
53
|
require 'airbrake/rails/action_controller'
|
51
54
|
include Airbrake::Rails::ActionController
|
52
55
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
)
|
60
|
-
|
61
|
-
# Send route stats.
|
62
|
-
require 'airbrake/rails/action_controller_notify_subscriber'
|
63
|
-
ActiveSupport::Notifications.subscribe(
|
64
|
-
'process_action.action_controller',
|
65
|
-
Airbrake::Rails::ActionControllerNotifySubscriber.new
|
66
|
-
)
|
67
|
-
|
68
|
-
# Send performance breakdown: where a request spends its time.
|
69
|
-
require 'airbrake/rails/action_controller_performance_breakdown_subscriber'
|
70
|
-
ActiveSupport::Notifications.subscribe(
|
71
|
-
'process_action.action_controller',
|
72
|
-
Airbrake::Rails::ActionControllerPerformanceBreakdownSubscriber.new
|
73
|
-
)
|
56
|
+
# Cache route information for the duration of the request.
|
57
|
+
require 'airbrake/rails/action_controller_route_subscriber'
|
58
|
+
ActiveSupport::Notifications.subscribe(
|
59
|
+
'start_processing.action_controller',
|
60
|
+
Airbrake::Rails::ActionControllerRouteSubscriber.new,
|
61
|
+
)
|
74
62
|
|
75
|
-
|
63
|
+
# Send route stats.
|
64
|
+
require 'airbrake/rails/action_controller_notify_subscriber'
|
65
|
+
ActiveSupport::Notifications.subscribe(
|
66
|
+
'process_action.action_controller',
|
67
|
+
Airbrake::Rails::ActionControllerNotifySubscriber.new,
|
68
|
+
)
|
76
69
|
|
77
|
-
|
78
|
-
|
79
|
-
|
70
|
+
# Send performance breakdown: where a request spends its time.
|
71
|
+
require 'airbrake/rails/action_controller_performance_breakdown_subscriber'
|
72
|
+
ActiveSupport::Notifications.subscribe(
|
73
|
+
'process_action.action_controller',
|
74
|
+
Airbrake::Rails::ActionControllerPerformanceBreakdownSubscriber.new,
|
75
|
+
)
|
80
76
|
|
81
|
-
|
82
|
-
|
83
|
-
|
77
|
+
require 'airbrake/rails/net_http' if defined?(Net) && defined?(Net::HTTP)
|
78
|
+
require 'airbrake/rails/curb' if defined?(Curl) && defined?(Curl::CURB_VERSION)
|
79
|
+
require 'airbrake/rails/http' if defined?(HTTP) && defined?(HTTP::Client)
|
80
|
+
require 'airbrake/rails/http_client' if defined?(HTTPClient)
|
81
|
+
require 'airbrake/rails/typhoeus' if defined?(Typhoeus)
|
84
82
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
83
|
+
if defined?(Excon)
|
84
|
+
require 'airbrake/rails/excon_subscriber'
|
85
|
+
ActiveSupport::Notifications.subscribe(/excon/, Airbrake::Rails::Excon.new)
|
86
|
+
::Excon.defaults[:instrumentor] = ActiveSupport::Notifications
|
90
87
|
end
|
91
88
|
end
|
92
89
|
end
|
93
|
-
# rubocop:enable Metrics/BlockLength
|
94
90
|
|
95
91
|
initializer('airbrake.active_record') do
|
96
92
|
ActiveSupport.on_load(:active_record, run_once: true) do
|
97
93
|
# Reports exceptions occurring in some bugged ActiveRecord callbacks.
|
98
94
|
# Applicable only to the versions of Rails lower than 4.2.
|
99
|
-
|
100
|
-
|
95
|
+
if defined?(::Rails) &&
|
96
|
+
Gem::Version.new(::Rails.version) <= Gem::Version.new('4.2')
|
97
|
+
require 'airbrake/rails/active_record'
|
98
|
+
include Airbrake::Rails::ActiveRecord
|
99
|
+
end
|
101
100
|
|
102
|
-
if defined?(ActiveRecord)
|
101
|
+
if defined?(ActiveRecord)
|
103
102
|
# Send SQL queries.
|
104
103
|
require 'airbrake/rails/active_record_subscriber'
|
105
104
|
ActiveSupport::Notifications.subscribe(
|
@@ -107,11 +106,21 @@ module Airbrake
|
|
107
106
|
)
|
108
107
|
|
109
108
|
# Filter out parameters from SQL body.
|
110
|
-
|
111
|
-
|
112
|
-
|
109
|
+
if ::ActiveRecord::Base.respond_to?(:connection_db_config)
|
110
|
+
# Rails 6.1+ deprecates "connection_config" in favor of
|
111
|
+
# "connection_db_config", so we need an updated call.
|
112
|
+
Airbrake.add_performance_filter(
|
113
|
+
Airbrake::Filters::SqlFilter.new(
|
114
|
+
::ActiveRecord::Base.connection_db_config.configuration_hash[:adapter],
|
115
|
+
),
|
113
116
|
)
|
114
|
-
|
117
|
+
else
|
118
|
+
Airbrake.add_performance_filter(
|
119
|
+
Airbrake::Filters::SqlFilter.new(
|
120
|
+
::ActiveRecord::Base.connection_config[:adapter],
|
121
|
+
),
|
122
|
+
)
|
123
|
+
end
|
115
124
|
end
|
116
125
|
end
|
117
126
|
end
|
@@ -137,5 +146,6 @@ module Airbrake
|
|
137
146
|
end
|
138
147
|
end
|
139
148
|
end
|
149
|
+
# rubocop:enable Metrics/BlockLength
|
140
150
|
end
|
141
151
|
end
|
@@ -1,12 +1,16 @@
|
|
1
|
-
|
2
|
-
# Monkey-patch to measure request timing.
|
3
|
-
class Request
|
4
|
-
alias run_without_airbrake run
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module Airbrake
|
4
|
+
module Rails
|
5
|
+
# Allow measuring request timing.
|
6
|
+
module TyphoeusRequest
|
7
|
+
def run
|
8
|
+
Airbrake::Rack.capture_timing(:http) do
|
9
|
+
super
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
15
|
+
|
16
|
+
Typhoeus::Request.prepend(Airbrake::Rails::TyphoeusRequest)
|
data/lib/airbrake/rake.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This is not bulletproof, but if this file is executed before a task
|
2
4
|
# definition, we can grab tasks descriptions and locations.
|
3
5
|
# See: https://goo.gl/ksn6PE
|
@@ -30,7 +32,7 @@ module Rake
|
|
30
32
|
notice[:params].merge!(
|
31
33
|
rake_task: task_info,
|
32
34
|
execute_args: args,
|
33
|
-
argv: ARGV.join(' ')
|
35
|
+
argv: ARGV.join(' '),
|
34
36
|
)
|
35
37
|
|
36
38
|
Airbrake.notify_sync(notice)
|
data/lib/airbrake/rake/tasks.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'airbrake-ruby'
|
2
4
|
|
3
5
|
namespace :airbrake do
|
@@ -55,7 +57,7 @@ namespace :airbrake do
|
|
55
57
|
username: ENV['USERNAME'],
|
56
58
|
revision: ENV['REVISION'],
|
57
59
|
repository: ENV['REPOSITORY'],
|
58
|
-
version: ENV['VERSION']
|
60
|
+
version: ENV['VERSION'],
|
59
61
|
}
|
60
62
|
promise = Airbrake.notify_deploy(deploy_params)
|
61
63
|
promise.then do
|
@@ -69,7 +71,7 @@ namespace :airbrake do
|
|
69
71
|
app = ENV['HEROKU_APP']
|
70
72
|
|
71
73
|
config = Bundler.with_clean_env do
|
72
|
-
`heroku config --shell#{
|
74
|
+
`heroku config --shell#{" --app #{app}" if app}`
|
73
75
|
end
|
74
76
|
|
75
77
|
heroku_env = config.each_line.with_object({}) do |line, h|
|
@@ -97,14 +99,14 @@ namespace :airbrake do
|
|
97
99
|
end
|
98
100
|
end
|
99
101
|
|
100
|
-
url = "https://airbrake.io/api/v3/projects/#{id}/heroku-deploys?key=#{key}"
|
102
|
+
url = ["https://airbrake.io/api/v3/projects/#{id}/heroku-deploys?key=#{key}"]
|
101
103
|
url << "&environment=#{env}"
|
102
104
|
url << "&repository=#{repo}" unless repo.empty?
|
103
105
|
|
104
|
-
command = %(heroku addons:create deployhooks:http --url="#{url}")
|
106
|
+
command = [%(heroku addons:create deployhooks:http --url="#{url.join}")]
|
105
107
|
command << " --app #{app}" if app
|
106
108
|
|
107
|
-
puts "$ #{command}"
|
109
|
+
puts "$ #{command.join}"
|
108
110
|
Bundler.with_clean_env { puts `#{command}` }
|
109
111
|
end
|
110
112
|
end
|
data/lib/airbrake/resque.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Resque
|
2
4
|
module Failure
|
3
5
|
# Provides Resque integration with Airbrake.
|
@@ -27,3 +29,33 @@ module Resque
|
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
32
|
+
|
33
|
+
module Resque
|
34
|
+
# Measures elapsed time of a job and notifies Airbrake of the execution
|
35
|
+
# status.
|
36
|
+
#
|
37
|
+
# @since v9.6.0
|
38
|
+
class Job
|
39
|
+
# Store the original method to use it later.
|
40
|
+
alias perform_without_airbrake perform
|
41
|
+
|
42
|
+
def perform
|
43
|
+
timing = Airbrake::Benchmark.measure do
|
44
|
+
perform_without_airbrake
|
45
|
+
end
|
46
|
+
rescue StandardError => exception
|
47
|
+
Airbrake.notify_queue_sync(
|
48
|
+
queue: payload['class'],
|
49
|
+
error_count: 1,
|
50
|
+
timing: 0.01,
|
51
|
+
)
|
52
|
+
raise exception
|
53
|
+
else
|
54
|
+
Airbrake.notify_queue_sync(
|
55
|
+
queue: payload['class'],
|
56
|
+
error_count: 0,
|
57
|
+
timing: timing,
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/airbrake/shoryuken.rb
CHANGED
@@ -1,14 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Airbrake
|
2
4
|
module Shoryuken
|
3
5
|
# Provides integration with Shoryuken.
|
4
6
|
class ErrorHandler
|
5
7
|
# rubocop:disable Lint/RescueException
|
6
8
|
def call(worker, queue, _sqs_msg, body)
|
7
|
-
|
9
|
+
timing = Airbrake::Benchmark.measure do
|
10
|
+
yield
|
11
|
+
end
|
8
12
|
rescue Exception => exception
|
9
13
|
notify_airbrake(exception, worker, queue, body)
|
10
|
-
|
14
|
+
Airbrake.notify_queue(
|
15
|
+
queue: worker.class.to_s,
|
16
|
+
error_count: 1,
|
17
|
+
timing: 0.01,
|
18
|
+
)
|
11
19
|
raise exception
|
20
|
+
else
|
21
|
+
Airbrake.notify_queue(
|
22
|
+
queue: worker.class.to_s,
|
23
|
+
error_count: 0,
|
24
|
+
timing: timing,
|
25
|
+
)
|
12
26
|
end
|
13
27
|
# rubocop:enable Lint/RescueException
|
14
28
|
|
@@ -24,7 +38,7 @@ module Airbrake
|
|
24
38
|
def notice_context(queue, body)
|
25
39
|
{
|
26
40
|
queue: queue,
|
27
|
-
body: body.is_a?(Array) ? { batch: body } : { body: body }
|
41
|
+
body: body.is_a?(Array) ? { batch: body } : { body: body },
|
28
42
|
}
|
29
43
|
end
|
30
44
|
end
|
data/lib/airbrake/sidekiq.rb
CHANGED
@@ -1,22 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'airbrake/sidekiq/retryable_jobs_filter'
|
2
4
|
|
3
5
|
module Airbrake
|
4
6
|
module Sidekiq
|
5
7
|
# Provides integration with Sidekiq v2+.
|
6
8
|
class ErrorHandler
|
7
|
-
# rubocop:disable Lint/RescueException
|
8
9
|
def call(_worker, context, _queue)
|
9
|
-
|
10
|
-
|
10
|
+
timing = Airbrake::Benchmark.measure do
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
11
14
|
notify_airbrake(exception, context)
|
15
|
+
Airbrake.notify_queue(
|
16
|
+
queue: context['class'],
|
17
|
+
error_count: 1,
|
18
|
+
timing: 0.01,
|
19
|
+
)
|
12
20
|
raise exception
|
21
|
+
else
|
22
|
+
Airbrake.notify_queue(
|
23
|
+
queue: context['class'],
|
24
|
+
error_count: 0,
|
25
|
+
timing: timing,
|
26
|
+
)
|
13
27
|
end
|
14
|
-
# rubocop:enable Lint/RescueException
|
15
28
|
|
16
29
|
private
|
17
30
|
|
18
31
|
def notify_airbrake(exception, context)
|
19
|
-
Airbrake.notify(exception, context) do |notice|
|
32
|
+
Airbrake.notify(exception, job: context) do |notice|
|
20
33
|
notice[:context][:component] = 'sidekiq'
|
21
34
|
notice[:context][:action] = action(context)
|
22
35
|
end
|
@@ -28,20 +41,15 @@ module Airbrake
|
|
28
41
|
klass = context['class'] || context[:job] && context[:job]['class']
|
29
42
|
return klass unless context[:job] && context[:job]['args'].first.is_a?(Hash)
|
30
43
|
return klass unless (job_class = context[:job]['args'].first['job_class'])
|
44
|
+
|
31
45
|
job_class
|
32
46
|
end
|
33
47
|
end
|
34
48
|
end
|
35
49
|
end
|
36
50
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
chain.add(Airbrake::Sidekiq::ErrorHandler)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
else
|
44
|
-
Sidekiq.configure_server do |config|
|
45
|
-
config.error_handlers << Airbrake::Sidekiq::ErrorHandler.new.method(:notify_airbrake)
|
51
|
+
Sidekiq.configure_server do |config|
|
52
|
+
config.server_middleware do |chain|
|
53
|
+
chain.add(Airbrake::Sidekiq::ErrorHandler)
|
46
54
|
end
|
47
55
|
end
|