airbrake 10.0.2 → 13.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/airbrake/capistrano/capistrano2.rb +1 -1
- data/lib/airbrake/capistrano/capistrano3.rb +1 -1
- data/lib/airbrake/delayed_job.rb +28 -30
- data/lib/airbrake/logger.rb +3 -1
- data/lib/airbrake/rack/context_filter.rb +10 -6
- data/lib/airbrake/rack/http_headers_filter.rb +4 -4
- data/lib/airbrake/rack/instrumentable.rb +9 -5
- data/lib/airbrake/rack/route_filter.rb +3 -1
- data/lib/airbrake/rack/user.rb +2 -0
- data/lib/airbrake/rack.rb +2 -0
- data/lib/airbrake/rails/action_cable.rb +19 -17
- data/lib/airbrake/rails/action_controller.rb +3 -0
- data/lib/airbrake/rails/action_controller_notify_subscriber.rb +2 -0
- data/lib/airbrake/rails/action_controller_performance_breakdown_subscriber.rb +2 -0
- data/lib/airbrake/rails/action_controller_route_subscriber.rb +2 -0
- data/lib/airbrake/rails/active_job.rb +2 -2
- data/lib/airbrake/rails/active_record_subscriber.rb +2 -0
- data/lib/airbrake/rails/app.rb +22 -0
- data/lib/airbrake/rails/backtrace_cleaner.rb +11 -0
- data/lib/airbrake/rails/curb.rb +18 -23
- data/lib/airbrake/rails/event.rb +14 -2
- data/lib/airbrake/rails/excon_subscriber.rb +2 -0
- data/lib/airbrake/rails/http.rb +12 -8
- data/lib/airbrake/rails/http_client.rb +11 -7
- data/lib/airbrake/rails/railtie.rb +7 -99
- data/lib/airbrake/rails/railties/action_controller_tie.rb +90 -0
- data/lib/airbrake/rails/railties/active_record_tie.rb +74 -0
- data/lib/airbrake/rails/railties/middleware_tie.rb +62 -0
- data/lib/airbrake/rails/typhoeus.rb +10 -8
- data/lib/airbrake/rails.rb +6 -8
- data/lib/airbrake/rake/tasks.rb +10 -10
- data/lib/airbrake/rake.rb +47 -46
- data/lib/airbrake/resque.rb +26 -25
- data/lib/airbrake/shoryuken.rb +2 -4
- data/lib/airbrake/sidekiq/retryable_jobs_filter.rb +14 -8
- data/lib/airbrake/sidekiq.rb +5 -6
- data/lib/airbrake/sneakers.rb +28 -27
- data/lib/airbrake/version.rb +1 -1
- data/lib/generators/airbrake_generator.rb +3 -6
- data/lib/generators/airbrake_initializer.rb.erb +65 -65
- metadata +52 -138
@@ -6,34 +6,9 @@ module Airbrake
|
|
6
6
|
# 3.2+ apps). It makes Airbrake Ruby work with Rails and report errors
|
7
7
|
# occurring in the application automatically.
|
8
8
|
class Railtie < ::Rails::Railtie
|
9
|
-
initializer('airbrake.middleware'
|
10
|
-
|
11
|
-
|
12
|
-
# case the request is local. We want to insert our middleware after
|
13
|
-
# DebugExceptions, so we don't notify Airbrake about local requests.
|
14
|
-
|
15
|
-
if ::Rails.version.to_i >= 5
|
16
|
-
# Avoid the warning about deprecated strings.
|
17
|
-
# Insert after DebugExceptions, since ConnectionManagement doesn't
|
18
|
-
# exist in Rails 5 anymore.
|
19
|
-
app.config.middleware.insert_after(
|
20
|
-
ActionDispatch::DebugExceptions,
|
21
|
-
Airbrake::Rack::Middleware,
|
22
|
-
)
|
23
|
-
elsif defined?(::ActiveRecord::ConnectionAdapters::ConnectionManagement)
|
24
|
-
# Insert after ConnectionManagement to avoid DB connection leakage:
|
25
|
-
# https://github.com/airbrake/airbrake/pull/568
|
26
|
-
app.config.middleware.insert_after(
|
27
|
-
::ActiveRecord::ConnectionAdapters::ConnectionManagement,
|
28
|
-
'Airbrake::Rack::Middleware',
|
29
|
-
)
|
30
|
-
else
|
31
|
-
# Insert after DebugExceptions for apps without ActiveRecord.
|
32
|
-
app.config.middleware.insert_after(
|
33
|
-
ActionDispatch::DebugExceptions,
|
34
|
-
'Airbrake::Rack::Middleware',
|
35
|
-
)
|
36
|
-
end
|
9
|
+
initializer('airbrake.middleware') do |app|
|
10
|
+
require 'airbrake/rails/railties/middleware_tie'
|
11
|
+
Railties::MiddlewareTie.new(app).call
|
37
12
|
end
|
38
13
|
|
39
14
|
rake_tasks do
|
@@ -44,81 +19,14 @@ module Airbrake
|
|
44
19
|
require 'airbrake/rake/tasks'
|
45
20
|
end
|
46
21
|
|
47
|
-
# rubocop:disable Metrics/BlockLength
|
48
22
|
initializer('airbrake.action_controller') do
|
49
|
-
|
50
|
-
|
51
|
-
# interesting request data. Appends that information to notices.
|
52
|
-
require 'airbrake/rails/action_controller'
|
53
|
-
include Airbrake::Rails::ActionController
|
54
|
-
|
55
|
-
if Airbrake::Config.instance.performance_stats
|
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
|
-
)
|
62
|
-
|
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
|
-
)
|
69
|
-
|
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
|
-
)
|
76
|
-
|
77
|
-
require 'airbrake/rails/net_http' if defined?(Net) && defined?(Net::HTTP)
|
78
|
-
|
79
|
-
if defined?(Curl) && defined?(Curl::CURB_VERSION)
|
80
|
-
require 'airbrake/rails/curb'
|
81
|
-
end
|
82
|
-
|
83
|
-
require 'airbrake/rails/http' if defined?(HTTP) && defined?(HTTP::Client)
|
84
|
-
require 'airbrake/rails/http_client' if defined?(HTTPClient)
|
85
|
-
require 'airbrake/rails/typhoeus' if defined?(Typhoeus)
|
86
|
-
|
87
|
-
if defined?(Excon)
|
88
|
-
require 'airbrake/rails/excon_subscriber'
|
89
|
-
ActiveSupport::Notifications.subscribe(/excon/, Airbrake::Rails::Excon.new)
|
90
|
-
::Excon.defaults[:instrumentor] = ActiveSupport::Notifications
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
23
|
+
require 'airbrake/rails/railties/action_controller_tie'
|
24
|
+
Railties::ActionControllerTie.new.call
|
94
25
|
end
|
95
|
-
# rubocop:enable Metrics/BlockLength
|
96
26
|
|
97
27
|
initializer('airbrake.active_record') do
|
98
|
-
|
99
|
-
|
100
|
-
# Applicable only to the versions of Rails lower than 4.2.
|
101
|
-
if defined?(::Rails) &&
|
102
|
-
Gem::Version.new(::Rails.version) <= Gem::Version.new('4.2')
|
103
|
-
require 'airbrake/rails/active_record'
|
104
|
-
include Airbrake::Rails::ActiveRecord
|
105
|
-
end
|
106
|
-
|
107
|
-
if defined?(ActiveRecord) && Airbrake::Config.instance.query_stats
|
108
|
-
# Send SQL queries.
|
109
|
-
require 'airbrake/rails/active_record_subscriber'
|
110
|
-
ActiveSupport::Notifications.subscribe(
|
111
|
-
'sql.active_record', Airbrake::Rails::ActiveRecordSubscriber.new
|
112
|
-
)
|
113
|
-
|
114
|
-
# Filter out parameters from SQL body.
|
115
|
-
Airbrake.add_performance_filter(
|
116
|
-
Airbrake::Filters::SqlFilter.new(
|
117
|
-
::ActiveRecord::Base.connection_config[:adapter],
|
118
|
-
),
|
119
|
-
)
|
120
|
-
end
|
121
|
-
end
|
28
|
+
require 'airbrake/rails/railties/active_record_tie'
|
29
|
+
Railties::ActiveRecordTie.new.call
|
122
30
|
end
|
123
31
|
|
124
32
|
initializer('airbrake.active_job') do
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'airbrake/rails/action_controller'
|
4
|
+
require 'airbrake/rails/action_controller_route_subscriber'
|
5
|
+
require 'airbrake/rails/action_controller_notify_subscriber'
|
6
|
+
require 'airbrake/rails/action_controller_performance_breakdown_subscriber'
|
7
|
+
|
8
|
+
module Airbrake
|
9
|
+
module Rails
|
10
|
+
module Railties
|
11
|
+
# Ties Airbrake APM (routes) and HTTP clients with Rails.
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
# @since v13.0.1
|
15
|
+
class ActionControllerTie
|
16
|
+
def initialize
|
17
|
+
@route_subscriber = Airbrake::Rails::ActionControllerRouteSubscriber.new
|
18
|
+
@notify_subscriber = Airbrake::Rails::ActionControllerNotifySubscriber.new
|
19
|
+
@performance_breakdown_subscriber =
|
20
|
+
Airbrake::Rails::ActionControllerPerformanceBreakdownSubscriber.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def call
|
24
|
+
ActiveSupport.on_load(:action_controller, run_once: true, yield: self) do
|
25
|
+
# Patches ActionController with methods that allow us to retrieve
|
26
|
+
# interesting request data. Appends that information to notices.
|
27
|
+
::ActionController::Base.include(Airbrake::Rails::ActionController)
|
28
|
+
|
29
|
+
tie_routes_apm
|
30
|
+
tie_http_integrations
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def tie_routes_apm
|
37
|
+
[
|
38
|
+
# Cache route information for the duration of the request.
|
39
|
+
['start_processing.action_controller', @route_subscriber],
|
40
|
+
|
41
|
+
# Send route stats.
|
42
|
+
['process_action.action_controller', @notify_subscriber],
|
43
|
+
|
44
|
+
# Send performance breakdown: where a request spends its time.
|
45
|
+
['process_action.action_controller', @performance_breakdown_subscriber],
|
46
|
+
].each do |(event, callback)|
|
47
|
+
ActiveSupport::Notifications.subscribe(event, callback)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def tie_http_integrations
|
52
|
+
tie_net_http
|
53
|
+
tie_curl
|
54
|
+
tie_http
|
55
|
+
tie_http_client
|
56
|
+
tie_typhoeus
|
57
|
+
tie_excon
|
58
|
+
end
|
59
|
+
|
60
|
+
def tie_net_http
|
61
|
+
require 'airbrake/rails/net_http' if defined?(Net) && defined?(Net::HTTP)
|
62
|
+
end
|
63
|
+
|
64
|
+
def tie_curl
|
65
|
+
require 'airbrake/rails/curb' if defined?(Curl) && defined?(Curl::CURB_VERSION)
|
66
|
+
end
|
67
|
+
|
68
|
+
def tie_http
|
69
|
+
require 'airbrake/rails/http' if defined?(HTTP) && defined?(HTTP::Client)
|
70
|
+
end
|
71
|
+
|
72
|
+
def tie_http_client
|
73
|
+
require 'airbrake/rails/http_client' if defined?(HTTPClient)
|
74
|
+
end
|
75
|
+
|
76
|
+
def tie_typhoeus
|
77
|
+
require 'airbrake/rails/typhoeus' if defined?(Typhoeus)
|
78
|
+
end
|
79
|
+
|
80
|
+
def tie_excon
|
81
|
+
return unless defined?(Excon)
|
82
|
+
|
83
|
+
require 'airbrake/rails/excon_subscriber'
|
84
|
+
ActiveSupport::Notifications.subscribe(/excon/, Airbrake::Rails::Excon.new)
|
85
|
+
::Excon.defaults[:instrumentor] = ActiveSupport::Notifications
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'airbrake/rails/active_record'
|
4
|
+
require 'airbrake/rails/active_record_subscriber'
|
5
|
+
|
6
|
+
module Airbrake
|
7
|
+
module Rails
|
8
|
+
module Railties
|
9
|
+
# Ties Airbrake APM (queries) with Rails.
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since v13.0.1
|
13
|
+
class ActiveRecordTie
|
14
|
+
def initialize
|
15
|
+
@active_record_subscriber = Airbrake::Rails::ActiveRecordSubscriber.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def call
|
19
|
+
ActiveSupport.on_load(:active_record, run_once: true, yield: self) do
|
20
|
+
tie_activerecord_callback_fix
|
21
|
+
tie_activerecord_apm
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def tie_activerecord_callback_fix
|
28
|
+
# Reports exceptions occurring in some bugged ActiveRecord callbacks.
|
29
|
+
# Applicable only to the versions of Rails lower than 4.2.
|
30
|
+
return unless defined?(::Rails)
|
31
|
+
return if Gem::Version.new(::Rails.version) > Gem::Version.new('4.2')
|
32
|
+
|
33
|
+
ActiveRecord::Base.include(Airbrake::Rails::ActiveRecord)
|
34
|
+
end
|
35
|
+
|
36
|
+
def tie_activerecord_apm
|
37
|
+
# Some Rails apps don't use ActiveRecord.
|
38
|
+
return unless defined?(::ActiveRecord)
|
39
|
+
|
40
|
+
# However, some dependencies might still require it, so we need an
|
41
|
+
# extra check. Apps that don't need ActiveRecord will likely have no
|
42
|
+
# AR configurations defined. We will skip APM integration in that
|
43
|
+
# case. See: https://github.com/airbrake/airbrake/issues/1222
|
44
|
+
configurations = ::ActiveRecord::Base.configurations
|
45
|
+
return unless configurations.any?
|
46
|
+
|
47
|
+
# Send SQL queries.
|
48
|
+
ActiveSupport::Notifications.subscribe(
|
49
|
+
'sql.active_record',
|
50
|
+
@active_record_subscriber,
|
51
|
+
)
|
52
|
+
|
53
|
+
# Filter out parameters from SQL body.
|
54
|
+
sql_filter = Airbrake::Filters::SqlFilter.new(
|
55
|
+
detect_activerecord_adapter(configurations),
|
56
|
+
)
|
57
|
+
Airbrake.add_performance_filter(sql_filter)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Rails 6+ introduces the `configs_for` API instead of the deprecated
|
61
|
+
# `#[]`, so we need an updated call.
|
62
|
+
def detect_activerecord_adapter(configurations)
|
63
|
+
unless configurations.respond_to?(:configs_for)
|
64
|
+
return configurations[::Rails.env]['adapter']
|
65
|
+
end
|
66
|
+
|
67
|
+
cfg = configurations.configs_for(env_name: ::Rails.env).first
|
68
|
+
# Rails 7+ API : Rails 6 API.
|
69
|
+
cfg.respond_to?(:adapter) ? cfg.adapter : cfg.config['adapter']
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Rails
|
5
|
+
module Railties
|
6
|
+
# Ties Airbrake Rails Middleware with Rails (error sending).
|
7
|
+
#
|
8
|
+
# Since Rails 3.2 the ActionDispatch::DebugExceptions middleware is
|
9
|
+
# responsible for logging exceptions and showing a debugging page in case
|
10
|
+
# the request is local. We want to insert our middleware after
|
11
|
+
# DebugExceptions, so we don't notify Airbrake about local requests.
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
# @since v13.0.1
|
15
|
+
class MiddlewareTie
|
16
|
+
def initialize(app)
|
17
|
+
@app = app
|
18
|
+
@middleware = app.config.middleware
|
19
|
+
end
|
20
|
+
|
21
|
+
def call
|
22
|
+
return tie_rails_5_or_above if ::Rails.version.to_i >= 5
|
23
|
+
|
24
|
+
if defined?(::ActiveRecord::ConnectionAdapters::ConnectionManagement)
|
25
|
+
return tie_rails_4_or_below_with_active_record
|
26
|
+
end
|
27
|
+
|
28
|
+
tie_rails_4_or_below_without_active_record
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Avoid the warning about deprecated strings.
|
34
|
+
# Insert after DebugExceptions, since ConnectionManagement doesn't
|
35
|
+
# exist in Rails 5 anymore.
|
36
|
+
def tie_rails_5_or_above
|
37
|
+
@middleware.insert_after(
|
38
|
+
ActionDispatch::DebugExceptions,
|
39
|
+
Airbrake::Rack::Middleware,
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Insert after ConnectionManagement to avoid DB connection leakage:
|
44
|
+
# https://github.com/airbrake/airbrake/pull/568
|
45
|
+
def tie_rails_4_or_below_with_active_record
|
46
|
+
@middleware.insert_after(
|
47
|
+
::ActiveRecord::ConnectionAdapters::ConnectionManagement,
|
48
|
+
'Airbrake::Rack::Middleware',
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Insert after DebugExceptions for apps without ActiveRecord.
|
53
|
+
def tie_rails_4_or_below_without_active_record
|
54
|
+
@middleware.insert_after(
|
55
|
+
ActionDispatch::DebugExceptions,
|
56
|
+
'Airbrake::Rack::Middleware',
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
Typhoeus::Request.prepend(Airbrake::Rails::TyphoeusRequest)
|
data/lib/airbrake/rails.rb
CHANGED
@@ -6,16 +6,14 @@ module Airbrake
|
|
6
6
|
# Rails namespace holds all Rails-related functionality.
|
7
7
|
module Rails
|
8
8
|
def self.logger
|
9
|
+
# Rails.logger is not set in some Rake tasks such as
|
10
|
+
# 'airbrake:deploy'. In this case we use a sensible fallback.
|
11
|
+
level = (::Rails.logger ? ::Rails.logger.level : Logger::ERROR)
|
12
|
+
|
9
13
|
if ENV['RAILS_LOG_TO_STDOUT'].present?
|
10
|
-
Logger.new(
|
14
|
+
Logger.new($stdout, level: level)
|
11
15
|
else
|
12
|
-
Logger.new(
|
13
|
-
::Rails.root.join('log', 'airbrake.log'),
|
14
|
-
|
15
|
-
# Rails.logger is not set in some Rake tasks such as
|
16
|
-
# 'airbrake:deploy'. In this case we use a sensible fallback.
|
17
|
-
level: (::Rails.logger ? ::Rails.logger.level : Logger::ERROR),
|
18
|
-
)
|
16
|
+
Logger.new(::Rails.root.join('log', 'airbrake.log'), level: level)
|
19
17
|
end
|
20
18
|
end
|
21
19
|
end
|
data/lib/airbrake/rake/tasks.rb
CHANGED
@@ -53,11 +53,11 @@ namespace :airbrake do
|
|
53
53
|
raise Airbrake::Error, 'airbrake-ruby is not configured' unless Airbrake.configured?
|
54
54
|
|
55
55
|
deploy_params = {
|
56
|
-
environment: ENV
|
57
|
-
username: ENV
|
58
|
-
revision: ENV
|
59
|
-
repository: ENV
|
60
|
-
version: ENV
|
56
|
+
environment: ENV.fetch('ENVIRONMENT', nil),
|
57
|
+
username: ENV.fetch('USERNAME', nil),
|
58
|
+
revision: ENV.fetch('REVISION', nil),
|
59
|
+
repository: ENV.fetch('REPOSITORY', nil),
|
60
|
+
version: ENV.fetch('VERSION', nil),
|
61
61
|
}
|
62
62
|
promise = Airbrake.notify_deploy(deploy_params)
|
63
63
|
promise.then do
|
@@ -68,10 +68,10 @@ namespace :airbrake do
|
|
68
68
|
|
69
69
|
desc 'Install a Heroku deploy hook to notify Airbrake of deploys'
|
70
70
|
task :install_heroku_deploy_hook do
|
71
|
-
app = ENV
|
71
|
+
app = ENV.fetch('HEROKU_APP', nil)
|
72
72
|
|
73
73
|
config = Bundler.with_clean_env do
|
74
|
-
`heroku config --shell#{
|
74
|
+
`heroku config --shell#{" --app #{app}" if app}`
|
75
75
|
end
|
76
76
|
|
77
77
|
heroku_env = config.each_line.with_object({}) do |line, h|
|
@@ -85,11 +85,11 @@ namespace :airbrake do
|
|
85
85
|
|
86
86
|
unless (env = heroku_env['RAILS_ENV'])
|
87
87
|
env = 'production'
|
88
|
-
puts "Airbrake couldn't identify your app's environment,
|
89
|
-
" environment will be used."
|
88
|
+
puts "Airbrake couldn't identify your app's environment, " \
|
89
|
+
"so the '#{env}' environment will be used."
|
90
90
|
end
|
91
91
|
|
92
|
-
unless (repo = ENV
|
92
|
+
unless (repo = ENV.fetch('REPOSITORY_URL', nil))
|
93
93
|
repo = `git remote get-url origin 2>/dev/null`.chomp
|
94
94
|
if repo.empty?
|
95
95
|
puts "Airbrake couldn't identify your app's repository."
|
data/lib/airbrake/rake.rb
CHANGED
@@ -5,61 +5,62 @@
|
|
5
5
|
# See: https://goo.gl/ksn6PE
|
6
6
|
Rake::TaskManager.record_task_metadata = true
|
7
7
|
|
8
|
-
module
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
# rubocop:enable Lint/RescueException
|
8
|
+
module Airbrake
|
9
|
+
module Rake
|
10
|
+
# Redefine +Rake::Task#execute+, so it can report errors to Airbrake.
|
11
|
+
module Task
|
12
|
+
# A wrapper around the original +#execute+, that catches all errors and
|
13
|
+
# notifies Airbrake.
|
14
|
+
#
|
15
|
+
# rubocop:disable Lint/RescueException
|
16
|
+
def execute(args = nil)
|
17
|
+
super(args)
|
18
|
+
rescue Exception => ex
|
19
|
+
notify_airbrake(ex, args)
|
20
|
+
raise ex
|
21
|
+
end
|
22
|
+
# rubocop:enable Lint/RescueException
|
25
23
|
|
26
|
-
|
24
|
+
private
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
26
|
+
def notify_airbrake(exception, args)
|
27
|
+
notice = Airbrake.build_notice(exception)
|
28
|
+
notice[:context][:component] = 'rake'
|
29
|
+
notice[:context][:action] = name
|
30
|
+
notice[:params].merge!(
|
31
|
+
rake_task: task_info,
|
32
|
+
execute_args: args,
|
33
|
+
argv: ARGV.join(' '),
|
34
|
+
)
|
37
35
|
|
38
|
-
|
39
|
-
|
36
|
+
Airbrake.notify_sync(notice)
|
37
|
+
end
|
40
38
|
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
40
|
+
def task_info
|
41
|
+
info = {}
|
44
42
|
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
info[:name] = name
|
44
|
+
info[:timestamp] = timestamp.to_s
|
45
|
+
info[:investigation] = investigation
|
48
46
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
47
|
+
info[:full_comment] = full_comment if full_comment
|
48
|
+
info[:arg_names] = arg_names if arg_names.any?
|
49
|
+
info[:arg_description] = arg_description if arg_description
|
50
|
+
info[:locations] = locations if locations.any?
|
51
|
+
info[:sources] = sources if sources.any?
|
54
52
|
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
if prerequisite_tasks.any?
|
54
|
+
info[:prerequisite_tasks] = prerequisite_tasks.map do |p|
|
55
|
+
p.__send__(:task_info)
|
56
|
+
end
|
58
57
|
end
|
59
|
-
end
|
60
58
|
|
61
|
-
|
59
|
+
info
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
62
62
|
end
|
63
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
64
63
|
end
|
65
64
|
end
|
65
|
+
|
66
|
+
Rake::Task.prepend(Airbrake::Rake::Task)
|
data/lib/airbrake/resque.rb
CHANGED
@@ -30,32 +30,33 @@ module Resque
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
module
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
33
|
+
module Airbrake
|
34
|
+
module Resque
|
35
|
+
# Measures elapsed time of a job and notifies Airbrake of the execution
|
36
|
+
# status.
|
37
|
+
#
|
38
|
+
# @since v9.6.0
|
39
|
+
module Job
|
40
|
+
def perform
|
41
|
+
timing = Airbrake::Benchmark.measure do
|
42
|
+
super
|
43
|
+
end
|
44
|
+
rescue StandardError => exception
|
45
|
+
Airbrake.notify_queue_sync(
|
46
|
+
queue: payload['class'],
|
47
|
+
error_count: 1,
|
48
|
+
timing: 0.01,
|
49
|
+
)
|
50
|
+
raise exception
|
51
|
+
else
|
52
|
+
Airbrake.notify_queue_sync(
|
53
|
+
queue: payload['class'],
|
54
|
+
error_count: 0,
|
55
|
+
timing: timing,
|
56
|
+
)
|
45
57
|
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
58
|
end
|
60
59
|
end
|
61
60
|
end
|
61
|
+
|
62
|
+
Resque::Job.prepend(Airbrake::Resque::Job)
|
data/lib/airbrake/shoryuken.rb
CHANGED
@@ -5,10 +5,8 @@ module Airbrake
|
|
5
5
|
# Provides integration with Shoryuken.
|
6
6
|
class ErrorHandler
|
7
7
|
# rubocop:disable Lint/RescueException
|
8
|
-
def call(worker, queue, _sqs_msg, body)
|
9
|
-
timing = Airbrake::Benchmark.measure
|
10
|
-
yield
|
11
|
-
end
|
8
|
+
def call(worker, queue, _sqs_msg, body, &block)
|
9
|
+
timing = Airbrake::Benchmark.measure(&block)
|
12
10
|
rescue Exception => exception
|
13
11
|
notify_airbrake(exception, worker, queue, body)
|
14
12
|
Airbrake.notify_queue(
|
@@ -6,17 +6,20 @@ module Airbrake
|
|
6
6
|
# by Sidekiq
|
7
7
|
# @since v7.3.0
|
8
8
|
class RetryableJobsFilter
|
9
|
-
|
9
|
+
SIDEKIQ_GTE_5_0_0 = Gem::Version.new(::Sidekiq::VERSION) >= Gem::Version.new('5.0.0')
|
10
|
+
SIDEKIQ_GTE_7_0_0 = Gem::Version.new(::Sidekiq::VERSION) >= Gem::Version.new('7.0.0')
|
11
|
+
|
12
|
+
if SIDEKIQ_GTE_5_0_0
|
13
|
+
require 'sidekiq/job_retry'
|
14
|
+
DEFAULT_MAX_RETRY_ATTEMPTS = ::Sidekiq::JobRetry::DEFAULT_MAX_RETRY_ATTEMPTS
|
15
|
+
else
|
10
16
|
require 'sidekiq/middleware/server/retry_jobs'
|
11
17
|
DEFAULT_MAX_RETRY_ATTEMPTS = \
|
12
18
|
::Sidekiq::Middleware::Server::RetryJobs::DEFAULT_MAX_RETRY_ATTEMPTS
|
13
|
-
else
|
14
|
-
require 'sidekiq/job_retry'
|
15
|
-
DEFAULT_MAX_RETRY_ATTEMPTS = ::Sidekiq::JobRetry::DEFAULT_MAX_RETRY_ATTEMPTS
|
16
19
|
end
|
17
20
|
|
18
21
|
def initialize(max_retries: nil)
|
19
|
-
@
|
22
|
+
@retries_before_notify = max_retries
|
20
23
|
end
|
21
24
|
|
22
25
|
def call(notice)
|
@@ -36,8 +39,8 @@ module Airbrake
|
|
36
39
|
end
|
37
40
|
|
38
41
|
def max_attempts_for(job)
|
39
|
-
if @
|
40
|
-
@
|
42
|
+
if @retries_before_notify
|
43
|
+
@retries_before_notify
|
41
44
|
elsif job['retry'].is_a?(Integer)
|
42
45
|
job['retry']
|
43
46
|
else
|
@@ -46,7 +49,10 @@ module Airbrake
|
|
46
49
|
end
|
47
50
|
|
48
51
|
def max_retries
|
49
|
-
@max_retries ||=
|
52
|
+
@max_retries ||= begin
|
53
|
+
config = SIDEKIQ_GTE_7_0_0 ? ::Sidekiq.default_configuration : ::Sidekiq.options
|
54
|
+
config[:max_retries] || DEFAULT_MAX_RETRY_ATTEMPTS
|
55
|
+
end
|
50
56
|
end
|
51
57
|
end
|
52
58
|
end
|