airbrake 3.1.6 → 11.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/airbrake.rb +23 -150
- data/lib/airbrake/capistrano.rb +6 -42
- data/lib/airbrake/capistrano/capistrano2.rb +40 -0
- data/lib/airbrake/capistrano/capistrano3.rb +23 -0
- data/lib/airbrake/delayed_job.rb +66 -0
- data/lib/airbrake/logger.rb +103 -0
- data/lib/airbrake/rack.rb +30 -45
- data/lib/airbrake/rack/context_filter.rb +65 -0
- data/lib/airbrake/rack/http_headers_filter.rb +44 -0
- data/lib/airbrake/rack/http_params_filter.rb +27 -0
- data/lib/airbrake/rack/instrumentable.rb +136 -0
- data/lib/airbrake/rack/middleware.rb +102 -0
- data/lib/airbrake/rack/request_body_filter.rb +33 -0
- data/lib/airbrake/rack/request_store.rb +34 -0
- data/lib/airbrake/rack/route_filter.rb +51 -0
- data/lib/airbrake/rack/session_filter.rb +25 -0
- data/lib/airbrake/rack/user.rb +74 -0
- data/lib/airbrake/rack/user_filter.rb +25 -0
- data/lib/airbrake/rails.rb +25 -31
- data/lib/airbrake/rails/action_cable.rb +35 -0
- data/lib/airbrake/rails/action_cable/notify_callback.rb +22 -0
- data/lib/airbrake/rails/action_controller.rb +40 -0
- data/lib/airbrake/rails/action_controller_notify_subscriber.rb +32 -0
- data/lib/airbrake/rails/action_controller_performance_breakdown_subscriber.rb +51 -0
- data/lib/airbrake/rails/action_controller_route_subscriber.rb +33 -0
- data/lib/airbrake/rails/active_job.rb +50 -0
- data/lib/airbrake/rails/active_record.rb +36 -0
- data/lib/airbrake/rails/active_record_subscriber.rb +46 -0
- data/lib/airbrake/rails/app.rb +78 -0
- data/lib/airbrake/rails/backtrace_cleaner.rb +23 -0
- data/lib/airbrake/rails/curb.rb +32 -0
- data/lib/airbrake/rails/event.rb +81 -0
- data/lib/airbrake/rails/excon_subscriber.rb +25 -0
- data/lib/airbrake/rails/http.rb +14 -0
- data/lib/airbrake/rails/http_client.rb +16 -0
- data/lib/airbrake/rails/net_http.rb +18 -0
- data/lib/airbrake/rails/railtie.rb +151 -0
- data/lib/airbrake/rails/typhoeus.rb +16 -0
- data/lib/airbrake/rake.rb +65 -0
- data/lib/airbrake/rake/tasks.rb +112 -0
- data/lib/airbrake/resque.rb +61 -0
- data/lib/airbrake/shoryuken.rb +54 -0
- data/lib/airbrake/sidekiq.rb +55 -0
- data/lib/airbrake/sidekiq/retryable_jobs_filter.rb +53 -0
- data/lib/airbrake/sneakers.rb +72 -0
- data/lib/airbrake/version.rb +5 -1
- data/lib/generators/airbrake_generator.rb +25 -0
- data/lib/generators/airbrake_initializer.rb.erb +80 -0
- metadata +206 -259
- data/CHANGELOG +0 -944
- data/Gemfile +0 -3
- data/Guardfile +0 -6
- data/INSTALL +0 -20
- data/MIT-LICENSE +0 -22
- data/README.md +0 -556
- data/README_FOR_HEROKU_ADDON.md +0 -94
- data/Rakefile +0 -223
- data/SUPPORTED_RAILS_VERSIONS +0 -38
- data/TESTING.md +0 -41
- data/airbrake.gemspec +0 -40
- data/bin/airbrake +0 -12
- data/features/metal.feature +0 -18
- data/features/rack.feature +0 -60
- data/features/rails.feature +0 -272
- data/features/rails_with_js_notifier.feature +0 -97
- data/features/rake.feature +0 -27
- data/features/sinatra.feature +0 -29
- data/features/step_definitions/file_steps.rb +0 -10
- data/features/step_definitions/metal_steps.rb +0 -23
- data/features/step_definitions/rack_steps.rb +0 -23
- data/features/step_definitions/rails_application_steps.rb +0 -478
- data/features/step_definitions/rake_steps.rb +0 -17
- data/features/support/airbrake_shim.rb.template +0 -16
- data/features/support/env.rb +0 -18
- data/features/support/matchers.rb +0 -35
- data/features/support/rails.rb +0 -201
- data/features/support/rake/Rakefile +0 -68
- data/features/support/terminal.rb +0 -107
- data/features/user_informer.feature +0 -63
- data/generators/airbrake/airbrake_generator.rb +0 -94
- data/generators/airbrake/lib/insert_commands.rb +0 -34
- data/generators/airbrake/lib/rake_commands.rb +0 -24
- data/generators/airbrake/templates/airbrake_tasks.rake +0 -25
- data/generators/airbrake/templates/capistrano_hook.rb +0 -6
- data/generators/airbrake/templates/initializer.rb +0 -6
- data/install.rb +0 -1
- data/lib/airbrake/backtrace.rb +0 -108
- data/lib/airbrake/cli/client.rb +0 -68
- data/lib/airbrake/cli/options.rb +0 -41
- data/lib/airbrake/cli/printer.rb +0 -30
- data/lib/airbrake/cli/project.rb +0 -17
- data/lib/airbrake/cli/project_factory.rb +0 -36
- data/lib/airbrake/cli/runner.rb +0 -48
- data/lib/airbrake/cli/validator.rb +0 -8
- data/lib/airbrake/configuration.rb +0 -311
- data/lib/airbrake/extensions/blank.rb +0 -73
- data/lib/airbrake/notice.rb +0 -390
- data/lib/airbrake/rails/action_controller_catcher.rb +0 -30
- data/lib/airbrake/rails/controller_methods.rb +0 -87
- data/lib/airbrake/rails/error_lookup.rb +0 -33
- data/lib/airbrake/rails/javascript_notifier.rb +0 -47
- data/lib/airbrake/rails/middleware/exceptions_catcher.rb +0 -33
- data/lib/airbrake/rails3_tasks.rb +0 -98
- data/lib/airbrake/railtie.rb +0 -48
- data/lib/airbrake/rake_handler.rb +0 -71
- data/lib/airbrake/sender.rb +0 -128
- data/lib/airbrake/shared_tasks.rb +0 -47
- data/lib/airbrake/tasks.rb +0 -83
- data/lib/airbrake/user_informer.rb +0 -27
- data/lib/airbrake_tasks.rb +0 -64
- data/lib/rails/generators/airbrake/airbrake_generator.rb +0 -100
- data/lib/templates/javascript_notifier.erb +0 -15
- data/lib/templates/rescue.erb +0 -91
- data/rails/init.rb +0 -1
- data/resources/README.md +0 -34
- data/resources/ca-bundle.crt +0 -3376
- data/script/integration_test.rb +0 -38
- data/test/airbrake_2_3.xsd +0 -88
- data/test/airbrake_tasks_test.rb +0 -170
- data/test/backtrace_test.rb +0 -162
- data/test/capistrano_test.rb +0 -34
- data/test/catcher_test.rb +0 -333
- data/test/configuration_test.rb +0 -233
- data/test/helper.rb +0 -263
- data/test/javascript_notifier_test.rb +0 -51
- data/test/logger_test.rb +0 -79
- data/test/notice_test.rb +0 -490
- data/test/notifier_test.rb +0 -276
- data/test/rack_test.rb +0 -58
- data/test/rails_initializer_test.rb +0 -36
- data/test/recursion_test.rb +0 -10
- data/test/sender_test.rb +0 -288
- data/test/user_informer_test.rb +0 -29
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Rack
|
5
|
+
# A filter that appends Rack request body to the notice.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# # Read and append up to 512 bytes from Rack request's body.
|
9
|
+
# Airbrake.add_filter(Airbrake::Rack::RequestBodyFilter.new(512))
|
10
|
+
#
|
11
|
+
# @since v5.7.0
|
12
|
+
# @note This filter is *not* used by default.
|
13
|
+
class RequestBodyFilter
|
14
|
+
# @return [Integer]
|
15
|
+
attr_reader :weight
|
16
|
+
|
17
|
+
# @param [Integer] length The maximum number of bytes to read
|
18
|
+
def initialize(length = 4096)
|
19
|
+
@length = length
|
20
|
+
@weight = 95
|
21
|
+
end
|
22
|
+
|
23
|
+
# @see Airbrake::FilterChain#refine
|
24
|
+
def call(notice)
|
25
|
+
return unless (request = notice.stash[:rack_request])
|
26
|
+
return unless request.body
|
27
|
+
|
28
|
+
notice[:environment][:body] = request.body.read(@length)
|
29
|
+
request.body.rewind
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Rack
|
5
|
+
# RequestStore is a thin (and limited) wrapper around *Thread.current* that
|
6
|
+
# allows writing and reading thread-local variables under the +:airbrake+
|
7
|
+
# key.
|
8
|
+
# @api private
|
9
|
+
# @since v8.1.3
|
10
|
+
module RequestStore
|
11
|
+
class << self
|
12
|
+
# @return [Hash] a hash for all request-related data
|
13
|
+
def store
|
14
|
+
Thread.current[:airbrake] ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [void]
|
18
|
+
def []=(key, value)
|
19
|
+
store[key] = value
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Object]
|
23
|
+
def [](key)
|
24
|
+
store[key]
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [void]
|
28
|
+
def clear
|
29
|
+
Thread.current[:airbrake] = {}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'airbrake/rails/app'
|
4
|
+
|
5
|
+
module Airbrake
|
6
|
+
module Rack
|
7
|
+
# Adds route slugs to context/route.
|
8
|
+
# @since v7.5.0
|
9
|
+
class RouteFilter
|
10
|
+
attr_reader :weight
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@weight = 100
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(notice)
|
17
|
+
return unless (request = notice.stash[:rack_request])
|
18
|
+
|
19
|
+
notice[:context][:route] =
|
20
|
+
if action_dispatch_request?(request)
|
21
|
+
rails_route(request)
|
22
|
+
elsif sinatra_request?(request)
|
23
|
+
sinatra_route(request)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def rails_route(request)
|
30
|
+
return unless (route = Airbrake::Rails::App.recognize_route(request))
|
31
|
+
|
32
|
+
route.path
|
33
|
+
end
|
34
|
+
|
35
|
+
def sinatra_route(request)
|
36
|
+
return unless (route = request.env['sinatra.route'])
|
37
|
+
|
38
|
+
route.split(' ').drop(1).join(' ')
|
39
|
+
end
|
40
|
+
|
41
|
+
def action_dispatch_request?(request)
|
42
|
+
defined?(ActionDispatch::Request) &&
|
43
|
+
request.instance_of?(ActionDispatch::Request)
|
44
|
+
end
|
45
|
+
|
46
|
+
def sinatra_request?(request)
|
47
|
+
defined?(Sinatra::Request) && request.instance_of?(Sinatra::Request)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Rack
|
5
|
+
# Adds HTTP session.
|
6
|
+
#
|
7
|
+
# @since v5.7.0
|
8
|
+
class SessionFilter
|
9
|
+
# @return [Integer]
|
10
|
+
attr_reader :weight
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@weight = 96
|
14
|
+
end
|
15
|
+
|
16
|
+
# @see Airbrake::FilterChain#refine
|
17
|
+
def call(notice)
|
18
|
+
return unless (request = notice.stash[:rack_request])
|
19
|
+
|
20
|
+
session = request.session
|
21
|
+
notice[:session] = session if session
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Rack
|
5
|
+
# Represents an authenticated user, which can be converted to Airbrake's
|
6
|
+
# payload format. Supports Warden and Omniauth authentication frameworks.
|
7
|
+
class User
|
8
|
+
# Finds the user in the Rack environment and creates a new user wrapper.
|
9
|
+
#
|
10
|
+
# @param [Hash{String=>Object}] rack_env The Rack environment
|
11
|
+
# @return [Airbrake::Rack::User, nil]
|
12
|
+
def self.extract(rack_env)
|
13
|
+
# Warden support (including Devise).
|
14
|
+
if (warden = rack_env['warden'])
|
15
|
+
user = warden.user(run_callbacks: false)
|
16
|
+
# Early return to prevent unwanted possible authentication via
|
17
|
+
# calling the `current_user` method later.
|
18
|
+
# See: https://github.com/airbrake/airbrake/issues/641
|
19
|
+
return user ? new(user) : nil
|
20
|
+
end
|
21
|
+
|
22
|
+
# Fallback mode (OmniAuth support included). Works only for Rails.
|
23
|
+
user = try_current_user(rack_env)
|
24
|
+
new(user) if user
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.try_current_user(rack_env)
|
28
|
+
controller = rack_env['action_controller.instance']
|
29
|
+
return unless controller.respond_to?(:current_user, true)
|
30
|
+
return unless [-1, 0].include?(controller.method(:current_user).arity)
|
31
|
+
|
32
|
+
begin
|
33
|
+
controller.__send__(:current_user)
|
34
|
+
rescue Exception => _e # rubocop:disable Lint/RescueException
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
private_class_method :try_current_user
|
39
|
+
|
40
|
+
def initialize(user)
|
41
|
+
@user = user
|
42
|
+
end
|
43
|
+
|
44
|
+
def as_json
|
45
|
+
user = {}
|
46
|
+
|
47
|
+
user[:id] = try_to_get(:id)
|
48
|
+
user[:name] = full_name
|
49
|
+
user[:username] = try_to_get(:username)
|
50
|
+
user[:email] = try_to_get(:email)
|
51
|
+
|
52
|
+
user = user.delete_if { |_key, val| val.nil? }
|
53
|
+
user.empty? ? user : { user: user }
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def try_to_get(key)
|
59
|
+
return unless @user.respond_to?(key)
|
60
|
+
# try methods with no arguments or with variable number of arguments,
|
61
|
+
# where none of them are required
|
62
|
+
return unless @user.method(key).arity.between?(-1, 0)
|
63
|
+
|
64
|
+
String(@user.__send__(key))
|
65
|
+
end
|
66
|
+
|
67
|
+
def full_name
|
68
|
+
# Try to get first and last names. If that fails, try to get just 'name'.
|
69
|
+
name = [try_to_get(:first_name), try_to_get(:last_name)].compact.join(' ')
|
70
|
+
name.empty? ? try_to_get(:name) : name
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Rack
|
5
|
+
# Adds current user information.
|
6
|
+
#
|
7
|
+
# @since v8.0.1
|
8
|
+
class UserFilter
|
9
|
+
# @return [Integer]
|
10
|
+
attr_reader :weight
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@weight = 99
|
14
|
+
end
|
15
|
+
|
16
|
+
# @see Airbrake::FilterChain#refine
|
17
|
+
def call(notice)
|
18
|
+
return unless (request = notice.stash[:rack_request])
|
19
|
+
|
20
|
+
user = Airbrake::Rack::User.extract(request.env)
|
21
|
+
notice[:context].merge!(user.as_json) if user
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/airbrake/rails.rb
CHANGED
@@ -1,40 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'airbrake/rails/
|
4
|
-
require 'airbrake/rails/error_lookup'
|
5
|
-
require 'airbrake/rails/javascript_notifier'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'airbrake/rails/railtie'
|
6
4
|
|
7
5
|
module Airbrake
|
6
|
+
# Rails namespace holds all Rails-related functionality.
|
8
7
|
module Rails
|
9
|
-
def self.
|
10
|
-
if
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
rails_logger = if defined?(::Rails.logger)
|
18
|
-
::Rails.logger
|
19
|
-
elsif defined?(RAILS_DEFAULT_LOGGER)
|
20
|
-
RAILS_DEFAULT_LOGGER
|
21
|
-
end
|
22
|
-
|
23
|
-
if defined?(::Rails.configuration) && ::Rails.configuration.respond_to?(:middleware)
|
24
|
-
::Rails.configuration.middleware.insert_after 'ActionController::Failsafe',
|
25
|
-
Airbrake::Rack
|
26
|
-
::Rails.configuration.middleware.insert_after 'Rack::Lock',
|
27
|
-
Airbrake::UserInformer
|
28
|
-
end
|
8
|
+
def self.logger
|
9
|
+
if ENV['RAILS_LOG_TO_STDOUT'].present?
|
10
|
+
Logger.new(STDOUT, level: ::Rails.logger.level)
|
11
|
+
else
|
12
|
+
Logger.new(
|
13
|
+
::Rails.root.join('log', 'airbrake.log'),
|
29
14
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
config.framework = defined?(::Rails.version) && "Rails: #{::Rails.version}" || defined?(::Rails::VERSION::STRING) && "Rails: #{::Rails::VERSION::STRING}"
|
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
|
+
)
|
35
19
|
end
|
36
20
|
end
|
37
21
|
end
|
38
22
|
end
|
39
23
|
|
40
|
-
|
24
|
+
if defined?(ActionController::Metal)
|
25
|
+
require 'airbrake/rails/action_controller'
|
26
|
+
module ActionController
|
27
|
+
# Adds support for Rails API/Metal for Rails < 5. Rails 5+ uses standard
|
28
|
+
# hooks.
|
29
|
+
# @see https://github.com/airbrake/airbrake/issues/821
|
30
|
+
class Metal
|
31
|
+
include Airbrake::Rails::ActionController
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'airbrake/rails/action_cable/notify_callback'
|
4
|
+
|
5
|
+
%i[subscribe unsubscribe].each do |callback_name|
|
6
|
+
ActionCable::Channel::Base.set_callback(
|
7
|
+
callback_name, :around, prepend: true
|
8
|
+
) do |channel, inner|
|
9
|
+
Airbrake::Rails::ActionCable::NotifyCallback.call(channel, inner)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ActionCable
|
14
|
+
module Channel
|
15
|
+
# @since v8.3.0
|
16
|
+
# @api private
|
17
|
+
# @see https://github.com/rails/rails/blob/master/actioncable/lib/action_cable/channel/base.rb
|
18
|
+
class Base
|
19
|
+
alias perform_action_without_airbrake perform_action
|
20
|
+
|
21
|
+
def perform_action(*args, &block)
|
22
|
+
perform_action_without_airbrake(*args, &block)
|
23
|
+
rescue Exception => ex # rubocop:disable Lint/RescueException
|
24
|
+
Airbrake.notify(ex) do |notice|
|
25
|
+
notice.stash[:action_cable_connection] = connection
|
26
|
+
notice[:context][:component] = self.class
|
27
|
+
notice[:context][:action] = args.first['action']
|
28
|
+
notice[:params].merge!(args.first)
|
29
|
+
end
|
30
|
+
|
31
|
+
raise ex
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Rails
|
5
|
+
module ActionCable
|
6
|
+
# @since v8.3.0
|
7
|
+
# @api private
|
8
|
+
class NotifyCallback
|
9
|
+
def self.call(channel, block)
|
10
|
+
block.call
|
11
|
+
rescue Exception => ex # rubocop:disable Lint/RescueException
|
12
|
+
notice = Airbrake.build_notice(ex)
|
13
|
+
notice[:context][:component] = 'action_cable'
|
14
|
+
notice[:context][:action] = channel.channel_name
|
15
|
+
Airbrake.notify(notice)
|
16
|
+
|
17
|
+
raise ex
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Airbrake
|
4
|
+
module Rails
|
5
|
+
# Contains helper methods that can be used inside Rails controllers to send
|
6
|
+
# notices to Airbrake. The main benefit of using them instead of the direct
|
7
|
+
# API is that they automatically add information from the Rack environment
|
8
|
+
# to notices.
|
9
|
+
module ActionController
|
10
|
+
private
|
11
|
+
|
12
|
+
# A helper method for sending notices to Airbrake *asynchronously*.
|
13
|
+
# Attaches information from the Rack env.
|
14
|
+
# @see Airbrake#notify, #notify_airbrake_sync
|
15
|
+
def notify_airbrake(exception, params = {}, &block)
|
16
|
+
return unless (notice = build_notice(exception, params))
|
17
|
+
|
18
|
+
Airbrake.notify(notice, params, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# A helper method for sending notices to Airbrake *synchronously*.
|
22
|
+
# Attaches information from the Rack env.
|
23
|
+
# @see Airbrake#notify_sync, #notify_airbrake
|
24
|
+
def notify_airbrake_sync(exception, params = {}, &block)
|
25
|
+
return unless (notice = build_notice(exception, params))
|
26
|
+
|
27
|
+
Airbrake.notify_sync(notice, params, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param [Exception] exception
|
31
|
+
# @return [Airbrake::Notice] the notice with information from the Rack env
|
32
|
+
def build_notice(exception, params = {})
|
33
|
+
return unless (notice = Airbrake.build_notice(exception, params))
|
34
|
+
|
35
|
+
notice.stash[:rack_request] = request
|
36
|
+
notice
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'airbrake/rails/event'
|
4
|
+
|
5
|
+
module Airbrake
|
6
|
+
module Rails
|
7
|
+
# ActionControllerNotifySubscriber sends route stat information, including
|
8
|
+
# performance data.
|
9
|
+
#
|
10
|
+
# @since v8.0.0
|
11
|
+
class ActionControllerNotifySubscriber
|
12
|
+
def call(*args)
|
13
|
+
return unless Airbrake::Config.instance.performance_stats
|
14
|
+
|
15
|
+
routes = Airbrake::Rack::RequestStore[:routes]
|
16
|
+
return if !routes || routes.none?
|
17
|
+
|
18
|
+
event = Airbrake::Rails::Event.new(*args)
|
19
|
+
|
20
|
+
routes.each do |route, _params|
|
21
|
+
Airbrake.notify_request(
|
22
|
+
method: event.method,
|
23
|
+
route: route,
|
24
|
+
status_code: event.status_code,
|
25
|
+
timing: event.duration,
|
26
|
+
time: event.time,
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|