airbrake 6.0.0 → 6.1.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake.rb +8 -14
  3. data/lib/airbrake/delayed_job.rb +49 -0
  4. data/lib/airbrake/delayed_job/plugin.rb +4 -50
  5. data/lib/airbrake/logger.rb +102 -0
  6. data/lib/airbrake/logger/airbrake_logger.rb +4 -105
  7. data/lib/airbrake/rack.rb +7 -0
  8. data/lib/airbrake/rack/context_filter.rb +5 -0
  9. data/lib/airbrake/rack/http_headers_filter.rb +9 -1
  10. data/lib/airbrake/rack/http_params_filter.rb +9 -1
  11. data/lib/airbrake/rack/request_body_filter.rb +5 -0
  12. data/lib/airbrake/rack/session_filter.rb +8 -0
  13. data/lib/airbrake/rails.rb +79 -0
  14. data/lib/airbrake/rails/active_record.rb +1 -1
  15. data/lib/airbrake/rails/railtie.rb +4 -78
  16. data/lib/airbrake/rake.rb +64 -0
  17. data/lib/airbrake/rake/task_ext.rb +4 -65
  18. data/lib/airbrake/rake/tasks.rb +12 -1
  19. data/lib/airbrake/resque.rb +17 -0
  20. data/lib/airbrake/resque/failure.rb +4 -17
  21. data/lib/airbrake/shoryuken.rb +41 -0
  22. data/lib/airbrake/shoryuken/error_handler.rb +4 -43
  23. data/lib/airbrake/sidekiq.rb +37 -0
  24. data/lib/airbrake/sidekiq/error_handler.rb +4 -37
  25. data/lib/airbrake/version.rb +1 -1
  26. data/spec/apps/rack/dummy_app.rb +1 -1
  27. data/spec/apps/rails/dummy_app.rb +30 -1
  28. data/spec/apps/rails/logs/40.log +4 -895
  29. data/spec/apps/rails/logs/42.log +19 -5438
  30. data/spec/apps/rails/logs/50.log +6611 -10
  31. data/spec/apps/rails/logs/51.log +743 -0
  32. data/spec/apps/rails/logs/52.log +249 -0
  33. data/spec/integration/rails/rails_spec.rb +16 -12
  34. data/spec/integration/shared_examples/rack_examples.rb +14 -20
  35. data/spec/spec_helper.rb +3 -3
  36. data/spec/unit/{logger/airbrake_logger_spec.rb → logger_spec.rb} +0 -0
  37. data/spec/unit/rack/context_filter_spec.rb +2 -2
  38. data/spec/unit/rack/http_headers_filter_spec.rb +7 -7
  39. data/spec/unit/rack/http_params_filter_spec.rb +8 -2
  40. data/spec/unit/rake/tasks_spec.rb +5 -5
  41. data/spec/unit/{shoryuken/error_handler_spec.rb → shoryuken_spec.rb} +12 -7
  42. data/spec/unit/{sidekiq/error_handler_spec.rb → sidekiq_spec.rb} +12 -8
  43. metadata +32 -18
  44. data/spec/apps/rails/logs/32.log +0 -852
  45. data/spec/apps/rails/logs/41.log +0 -453
@@ -5,6 +5,14 @@ module Airbrake
5
5
  #
6
6
  # @since v5.7.0
7
7
  class SessionFilter
8
+ ##
9
+ # @return [Integer]
10
+ attr_reader :weight
11
+
12
+ def initialize
13
+ @weight = 96
14
+ end
15
+
8
16
  ##
9
17
  # @see {Airbrake::FilterChain#refine}
10
18
  def call(notice)
@@ -0,0 +1,79 @@
1
+ module Airbrake
2
+ module Rails
3
+ ##
4
+ # This railtie works for any Rails application that supports railties (Rails
5
+ # 3.2+ apps). It makes Airbrake Ruby work with Rails and report errors
6
+ # occurring in the application automatically.
7
+ class Railtie < ::Rails::Railtie
8
+ initializer('airbrake.middleware') do |app|
9
+ # Since Rails 3.2 the ActionDispatch::DebugExceptions middleware is
10
+ # responsible for logging exceptions and showing a debugging page in
11
+ # case the request is local. We want to insert our middleware after
12
+ # DebugExceptions, so we don't notify Airbrake about local requests.
13
+
14
+ if ::Rails.version.start_with?('5.')
15
+ # Avoid the warning about deprecated strings.
16
+ # Insert after DebugExceptions, since ConnectionManagement doesn't
17
+ # exist in Rails 5 anymore.
18
+ app.config.middleware.insert_after(
19
+ ActionDispatch::DebugExceptions,
20
+ Airbrake::Rack::Middleware
21
+ )
22
+ elsif defined?(ActiveRecord)
23
+ # Insert after ConnectionManagement to avoid DB connection leakage:
24
+ # https://github.com/airbrake/airbrake/pull/568
25
+ app.config.middleware.insert_after(
26
+ ActiveRecord::ConnectionAdapters::ConnectionManagement,
27
+ 'Airbrake::Rack::Middleware'
28
+ )
29
+ else
30
+ # Insert after DebugExceptions for apps without ActiveRecord.
31
+ app.config.middleware.insert_after(
32
+ ActionDispatch::DebugExceptions,
33
+ 'Airbrake::Rack::Middleware'
34
+ )
35
+ end
36
+ end
37
+
38
+ rake_tasks do
39
+ # Report exceptions occurring in Rake tasks.
40
+ require 'airbrake/rake'
41
+
42
+ # Defines tasks such as `airbrake:test` & `airbrake:deploy`.
43
+ require 'airbrake/rake/tasks'
44
+ end
45
+
46
+ initializer('airbrake.action_controller') do
47
+ ActiveSupport.on_load(:action_controller) do
48
+ # Patches ActionController with methods that allow us to retrieve
49
+ # interesting request data. Appends that information to notices.
50
+ require 'airbrake/rails/action_controller'
51
+ include Airbrake::Rails::ActionController
52
+ end
53
+ end
54
+
55
+ initializer('airbrake.active_record') do
56
+ ActiveSupport.on_load(:active_record) do
57
+ # Reports exceptions occurring in some bugged ActiveRecord callbacks.
58
+ # Applicable only to the versions of Rails lower than 4.2.
59
+ require 'airbrake/rails/active_record'
60
+ include Airbrake::Rails::ActiveRecord
61
+ end
62
+ end
63
+
64
+ initializer('airbrake.active_job') do
65
+ ActiveSupport.on_load(:active_job) do
66
+ # Reports exceptions occurring in ActiveJob jobs.
67
+ require 'airbrake/rails/active_job'
68
+ include Airbrake::Rails::ActiveJob
69
+ end
70
+ end
71
+
72
+ runner do
73
+ at_exit do
74
+ Airbrake.notify_sync($ERROR_INFO) if $ERROR_INFO
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -19,7 +19,7 @@ module Airbrake
19
19
  # rubocop:disable Lint/RescueException
20
20
  def run_callbacks(kind, *args, &block)
21
21
  # Let the post process handle the exception if it's not a bugged hook.
22
- return super unless [:commit, :rollback].include?(kind)
22
+ return super unless %i[commit rollback].include?(kind)
23
23
 
24
24
  # Handle the exception ourselves. The 'ex' exception won't be
25
25
  # propagated, therefore we must notify it here.
@@ -1,79 +1,5 @@
1
- module Airbrake
2
- module Rails
3
- ##
4
- # This railtie works for any Rails application that supports railties (Rails
5
- # 3.2+ apps). It makes Airbrake Ruby work with Rails and report errors
6
- # occurring in the application automatically.
7
- class Railtie < ::Rails::Railtie
8
- initializer('airbrake.middleware') do |app|
9
- # Since Rails 3.2 the ActionDispatch::DebugExceptions middleware is
10
- # responsible for logging exceptions and showing a debugging page in
11
- # case the request is local. We want to insert our middleware after
12
- # DebugExceptions, so we don't notify Airbrake about local requests.
1
+ require 'airbrake/rails'
13
2
 
14
- if ::Rails.version.start_with?('5.')
15
- # Avoid the warning about deprecated strings.
16
- # Insert after DebugExceptions, since ConnectionManagement doesn't
17
- # exist in Rails 5 anymore.
18
- app.config.middleware.insert_after(
19
- ActionDispatch::DebugExceptions,
20
- Airbrake::Rack::Middleware
21
- )
22
- elsif defined?(ActiveRecord)
23
- # Insert after ConnectionManagement to avoid DB connection leakage:
24
- # https://github.com/airbrake/airbrake/pull/568
25
- app.config.middleware.insert_after(
26
- ActiveRecord::ConnectionAdapters::ConnectionManagement,
27
- 'Airbrake::Rack::Middleware'
28
- )
29
- else
30
- # Insert after DebugExceptions for apps without ActiveRecord.
31
- app.config.middleware.insert_after(
32
- ActionDispatch::DebugExceptions,
33
- 'Airbrake::Rack::Middleware'
34
- )
35
- end
36
- end
37
-
38
- rake_tasks do
39
- # Report exceptions occurring in Rake tasks.
40
- require 'airbrake/rake/task_ext'
41
-
42
- # Defines tasks such as `airbrake:test` & `airbrake:deploy`.
43
- require 'airbrake/rake/tasks'
44
- end
45
-
46
- initializer('airbrake.action_controller') do
47
- ActiveSupport.on_load(:action_controller) do
48
- # Patches ActionController with methods that allow us to retrieve
49
- # interesting request data. Appends that information to notices.
50
- require 'airbrake/rails/action_controller'
51
- include Airbrake::Rails::ActionController
52
- end
53
- end
54
-
55
- initializer('airbrake.active_record') do
56
- ActiveSupport.on_load(:active_record) do
57
- # Reports exceptions occurring in some bugged ActiveRecord callbacks.
58
- # Applicable only to the versions of Rails lower than 4.2.
59
- require 'airbrake/rails/active_record'
60
- include Airbrake::Rails::ActiveRecord
61
- end
62
- end
63
-
64
- initializer('airbrake.active_job') do
65
- ActiveSupport.on_load(:active_job) do
66
- # Reports exceptions occurring in ActiveJob jobs.
67
- require 'airbrake/rails/active_job'
68
- include Airbrake::Rails::ActiveJob
69
- end
70
- end
71
-
72
- runner do
73
- at_exit do
74
- Airbrake.notify_sync($ERROR_INFO) if $ERROR_INFO
75
- end
76
- end
77
- end
78
- end
79
- end
3
+ warn "DEPRECATION WARNING: Requiring 'airbrake/rails/railtie' is " \
4
+ "deprecated and will be removed in the next MAJOR release. Require " \
5
+ "'airbrake/rails' instead."
@@ -0,0 +1,64 @@
1
+ # This is not bulletproof, but if this file is executed before a task
2
+ # definition, we can grab tasks descriptions and locations.
3
+ # See: https://goo.gl/ksn6PE
4
+ Rake::TaskManager.record_task_metadata = true
5
+
6
+ module Rake
7
+ ##
8
+ # Redefine +Rake::Task#execute+, so it can report errors to Airbrake.
9
+ class Task
10
+ # Store the original method to use it later.
11
+ alias execute_without_airbrake execute
12
+
13
+ ##
14
+ # A wrapper around the original +#execute+, that catches all errors and
15
+ # notifies Airbrake.
16
+ #
17
+ # rubocop:disable Lint/RescueException
18
+ def execute(args = nil)
19
+ execute_without_airbrake(args)
20
+ rescue Exception => ex
21
+ notify_airbrake(ex, args)
22
+ raise ex
23
+ end
24
+ # rubocop:enable Lint/RescueException
25
+
26
+ private
27
+
28
+ def notify_airbrake(exception, args)
29
+ Airbrake.notify_sync(exception) do |notice|
30
+ notice[:context][:component] = 'rake'
31
+ notice[:context][:action] = name
32
+ notice[:params] = {
33
+ rake_task: task_info,
34
+ execute_args: args,
35
+ argv: ARGV.join(' ')
36
+ }
37
+ end
38
+ end
39
+
40
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
41
+ def task_info
42
+ info = {}
43
+
44
+ info[:name] = name
45
+ info[:timestamp] = timestamp.to_s
46
+ info[:investigation] = investigation
47
+
48
+ info[:full_comment] = full_comment if full_comment
49
+ info[:arg_names] = arg_names if arg_names.any?
50
+ info[:arg_description] = arg_description if arg_description
51
+ info[:locations] = locations if locations.any?
52
+ info[:sources] = sources if sources.any?
53
+
54
+ if prerequisite_tasks.any?
55
+ info[:prerequisite_tasks] = prerequisite_tasks.map do |p|
56
+ p.__send__(:task_info)
57
+ end
58
+ end
59
+
60
+ info
61
+ end
62
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
63
+ end
64
+ end
@@ -1,66 +1,5 @@
1
- # This is not bulletproof, but if this file is executed before a task
2
- # definition, we can grab tasks descriptions and locations.
3
- # See: https://goo.gl/ksn6PE
4
- Rake::TaskManager.record_task_metadata = true
1
+ require 'airbrake/rake'
5
2
 
6
- module Rake
7
- ##
8
- # Redefine +Rake::Task#execute+, so it can report errors to Airbrake.
9
- class Task
10
- # Store the original method to use it later.
11
- alias execute_without_airbrake execute
12
-
13
- ##
14
- # A wrapper around the original +#execute+, that catches all errors and
15
- # notifies Airbrake.
16
- #
17
- # rubocop:disable Lint/RescueException
18
- def execute(args = nil)
19
- execute_without_airbrake(args)
20
- rescue Exception => ex
21
- notify_airbrake(ex, args)
22
- raise ex
23
- end
24
- # rubocop:enable Lint/RescueException
25
-
26
- private
27
-
28
- def notify_airbrake(exception, args)
29
- return unless (notice = Airbrake.build_notice(exception))
30
-
31
- notice[:context][:component] = 'rake'
32
- notice[:context][:action] = name
33
- notice[:params] = {
34
- rake_task: task_info,
35
- execute_args: args,
36
- argv: ARGV.join(' ')
37
- }
38
-
39
- Airbrake.notify_sync(notice)
40
- end
41
-
42
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
43
- def task_info
44
- info = {}
45
-
46
- info[:name] = name
47
- info[:timestamp] = timestamp.to_s
48
- info[:investigation] = investigation
49
-
50
- info[:full_comment] = full_comment if full_comment
51
- info[:arg_names] = arg_names if arg_names.any?
52
- info[:arg_description] = arg_description if arg_description
53
- info[:locations] = locations if locations.any?
54
- info[:sources] = sources if sources.any?
55
-
56
- if prerequisite_tasks.any?
57
- info[:prerequisite_tasks] = prerequisite_tasks.map do |p|
58
- p.__send__(:task_info)
59
- end
60
- end
61
-
62
- info
63
- end
64
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
65
- end
66
- end
3
+ warn "DEPRECATION WARNING: Requiring 'airbrake/rake/task_ext' is " \
4
+ "deprecated and will be removed in the next MAJOR release. Require " \
5
+ "'airbrake/rake' instead."
@@ -68,7 +68,7 @@ namespace :airbrake do
68
68
  # Avoid loading the environment to speed up the deploy task and try guess
69
69
  # the initializer file location.
70
70
  if initializer.exist?
71
- load initializer
71
+ load(initializer) unless Airbrake[:default]
72
72
  else
73
73
  Rake::Task[:environment].invoke
74
74
  end
@@ -106,8 +106,19 @@ namespace :airbrake do
106
106
  " environment will be used."
107
107
  end
108
108
 
109
+ unless (repo = ENV['REPOSITORY_URL'])
110
+ repo = `git remote get-url origin 2>/dev/null`.chomp
111
+ if repo.empty?
112
+ puts "Airbrake couldn't identify your app's repository."
113
+ else
114
+ puts "Airbrake couldn't identify your app's repository, so the " \
115
+ "'origin' remote url '#{repo}' will be used."
116
+ end
117
+ end
118
+
109
119
  url = "https://airbrake.io/api/v3/projects/#{id}/heroku-deploys?key=#{key}"
110
120
  url << "&environment=#{env}"
121
+ url << "&repository=#{repo}" unless repo.empty?
111
122
 
112
123
  command = %(heroku addons:create deployhooks:http --url="#{url}")
113
124
  command << " --app #{app}" if app
@@ -0,0 +1,17 @@
1
+ module Resque
2
+ module Failure
3
+ ##
4
+ # Provides Resque integration with Airbrake.
5
+ #
6
+ # @since v5.0.0
7
+ # @see https://github.com/resque/resque/wiki/Failure-Backends
8
+ class Airbrake < Base
9
+ def save
10
+ ::Airbrake.notify_sync(exception, payload) do |notice|
11
+ notice[:context][:component] = 'resque'
12
+ notice[:context][:action] = payload['class'].to_s
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,18 +1,5 @@
1
- module Resque
2
- module Failure
3
- ##
4
- # Provides Resque integration with Airbrake.
5
- #
6
- # @since v5.0.0
7
- # @see https://github.com/resque/resque/wiki/Failure-Backends
8
- class Airbrake < Base
9
- def save
10
- return unless (notice = ::Airbrake.build_notice(exception, payload))
11
- notice[:context][:component] = 'resque'
12
- notice[:context][:action] = payload['class'].to_s
1
+ require 'airbrake/resque'
13
2
 
14
- ::Airbrake.notify_sync(notice)
15
- end
16
- end
17
- end
18
- end
3
+ warn "DEPRECATION WARNING: Requiring 'airbrake/resque/failure' is " \
4
+ "deprecated and will be removed in the next MAJOR release. Require " \
5
+ "'airbrake/resque' instead."
@@ -0,0 +1,41 @@
1
+ module Airbrake
2
+ module Shoryuken
3
+ ##
4
+ # Provides integration with Shoryuken.
5
+ class ErrorHandler
6
+ # rubocop:disable Lint/RescueException
7
+ def call(worker, queue, _sqs_msg, body)
8
+ yield
9
+ rescue Exception => exception
10
+ notify_airbrake(exception, worker, queue, body)
11
+
12
+ raise exception
13
+ end
14
+ # rubocop:enable Lint/RescueException
15
+
16
+ private
17
+
18
+ def notify_airbrake(exception, worker, queue, body)
19
+ Airbrake.notify(exception, notice_context(queue, body)) do |notice|
20
+ notice[:context][:component] = 'shoryuken'
21
+ notice[:context][:action] = worker.class.to_s
22
+ end
23
+ end
24
+
25
+ def notice_context(queue, body)
26
+ {
27
+ queue: queue,
28
+ body: body.is_a?(Array) ? { batch: body } : { body: body }
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ if defined?(::Shoryuken)
36
+ Shoryuken.configure_server do |config|
37
+ config.server_middleware do |chain|
38
+ chain.add Airbrake::Shoryuken::ErrorHandler
39
+ end
40
+ end
41
+ end
@@ -1,44 +1,5 @@
1
- module Airbrake
2
- module Shoryuken
3
- ##
4
- # Provides integration with Shoryuken.
5
- class ErrorHandler
6
- # rubocop:disable Lint/RescueException
7
- def call(worker, queue, _sqs_msg, body)
8
- yield
9
- rescue Exception => exception
10
- notify_airbrake(exception, worker, queue, body)
1
+ require 'airbrake/shoryuken'
11
2
 
12
- raise exception
13
- end
14
- # rubocop:enable Lint/RescueException
15
-
16
- private
17
-
18
- def notify_airbrake(exception, worker, queue, body)
19
- notice = Airbrake.build_notice(exception, notice_context(queue, body))
20
- return unless notice
21
-
22
- notice[:context][:component] = 'shoryuken'
23
- notice[:context][:action] = worker.class.to_s
24
-
25
- Airbrake.notify(notice)
26
- end
27
-
28
- def notice_context(queue, body)
29
- {
30
- queue: queue,
31
- body: body.is_a?(Array) ? { batch: body } : { body: body }
32
- }
33
- end
34
- end
35
- end
36
- end
37
-
38
- if defined?(::Shoryuken)
39
- Shoryuken.configure_server do |config|
40
- config.server_middleware do |chain|
41
- chain.add Airbrake::Shoryuken::ErrorHandler
42
- end
43
- end
44
- end
3
+ warn "DEPRECATION WARNING: Requiring 'airbrake/shoryuken/error_handler' is " \
4
+ "deprecated and will be removed in the next MAJOR release. Require " \
5
+ "'airbrake/shoryuken' instead."