-
Notifications
You must be signed in to change notification settings - Fork 390
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1225 from airbrake/railtie-refactor
Refactor railties so that every railtie is a separate class
- Loading branch information
Showing
4 changed files
with
225 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'airbrake/rails/action_controller' | ||
require 'airbrake/rails/action_controller_route_subscriber' | ||
require 'airbrake/rails/action_controller_notify_subscriber' | ||
require 'airbrake/rails/action_controller_performance_breakdown_subscriber' | ||
|
||
module Airbrake | ||
module Rails | ||
module Railties | ||
# Ties Airbrake APM (routes) and HTTP clients with Rails. | ||
# | ||
# @api private | ||
# @since v13.0.1 | ||
class ActionControllerTie | ||
def initialize | ||
@route_subscriber = Airbrake::Rails::ActionControllerRouteSubscriber.new | ||
@notify_subscriber = Airbrake::Rails::ActionControllerNotifySubscriber.new( | ||
::Rails.version, | ||
) | ||
@performance_breakdown_subscriber = | ||
Airbrake::Rails::ActionControllerPerformanceBreakdownSubscriber.new | ||
end | ||
|
||
def call | ||
ActiveSupport.on_load(:action_controller, run_once: true, yield: self) do | ||
# Patches ActionController with methods that allow us to retrieve | ||
# interesting request data. Appends that information to notices. | ||
::ActionController::Base.include(Airbrake::Rails::ActionController) | ||
|
||
tie_routes_apm | ||
tie_http_integrations | ||
end | ||
end | ||
|
||
private | ||
|
||
def tie_routes_apm | ||
[ | ||
# Cache route information for the duration of the request. | ||
['start_processing.action_controller', @route_subscriber], | ||
|
||
# Send route stats. | ||
['process_action.action_controller', @notify_subscriber], | ||
|
||
# Send performance breakdown: where a request spends its time. | ||
['process_action.action_controller', @performance_breakdown_subscriber], | ||
].each do |(event, callback)| | ||
ActiveSupport::Notifications.subscribe(event, callback) | ||
end | ||
end | ||
|
||
def tie_http_integrations | ||
tie_net_http | ||
tie_curl | ||
tie_http | ||
tie_http_client | ||
tie_typhoeus | ||
tie_excon | ||
end | ||
|
||
def tie_net_http | ||
require 'airbrake/rails/net_http' if defined?(Net) && defined?(Net::HTTP) | ||
end | ||
|
||
def tie_curl | ||
require 'airbrake/rails/curb' if defined?(Curl) && defined?(Curl::CURB_VERSION) | ||
end | ||
|
||
def tie_http | ||
require 'airbrake/rails/http' if defined?(HTTP) && defined?(HTTP::Client) | ||
end | ||
|
||
def tie_http_client | ||
require 'airbrake/rails/http_client' if defined?(HTTPClient) | ||
end | ||
|
||
def tie_typhoeus | ||
require 'airbrake/rails/typhoeus' if defined?(Typhoeus) | ||
end | ||
|
||
def tie_excon | ||
return unless defined?(Excon) | ||
|
||
require 'airbrake/rails/excon_subscriber' | ||
ActiveSupport::Notifications.subscribe(/excon/, Airbrake::Rails::Excon.new) | ||
::Excon.defaults[:instrumentor] = ActiveSupport::Notifications | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'airbrake/rails/active_record' | ||
require 'airbrake/rails/active_record_subscriber' | ||
|
||
module Airbrake | ||
module Rails | ||
module Railties | ||
# Ties Airbrake APM (queries) with Rails. | ||
# | ||
# @api private | ||
# @since v13.0.1 | ||
class ActiveRecordTie | ||
def initialize | ||
@active_record_subscriber = Airbrake::Rails::ActiveRecordSubscriber.new | ||
end | ||
|
||
def call | ||
ActiveSupport.on_load(:active_record, run_once: true, yield: self) do | ||
tie_activerecord_callback_fix | ||
tie_activerecord_apm | ||
end | ||
end | ||
|
||
private | ||
|
||
def tie_activerecord_callback_fix | ||
# Reports exceptions occurring in some bugged ActiveRecord callbacks. | ||
# Applicable only to the versions of Rails lower than 4.2. | ||
return unless defined?(::Rails) | ||
return if Gem::Version.new(::Rails.version) > Gem::Version.new('4.2') | ||
|
||
ActiveRecord::Base.include(Airbrake::Rails::ActiveRecord) | ||
end | ||
|
||
def tie_activerecord_apm | ||
return unless defined?(ActiveRecord) | ||
|
||
# Send SQL queries. | ||
ActiveSupport::Notifications.subscribe( | ||
'sql.active_record', | ||
@active_record_subscriber, | ||
) | ||
|
||
# Filter out parameters from SQL body. | ||
if ::ActiveRecord::Base.respond_to?(:connection_db_config) | ||
# Rails 6.1+ deprecates "connection_config" in favor of | ||
# "connection_db_config", so we need an updated call. | ||
Airbrake.add_performance_filter( | ||
Airbrake::Filters::SqlFilter.new( | ||
::ActiveRecord::Base.connection_db_config.configuration_hash[:adapter], | ||
), | ||
) | ||
else | ||
Airbrake.add_performance_filter( | ||
Airbrake::Filters::SqlFilter.new( | ||
::ActiveRecord::Base.connection_config[:adapter], | ||
), | ||
) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# frozen_string_literal: true | ||
|
||
module Airbrake | ||
module Rails | ||
module Railties | ||
# Ties Airbrake Rails Middleware with Rails (error sending). | ||
# | ||
# Since Rails 3.2 the ActionDispatch::DebugExceptions middleware is | ||
# responsible for logging exceptions and showing a debugging page in case | ||
# the request is local. We want to insert our middleware after | ||
# DebugExceptions, so we don't notify Airbrake about local requests. | ||
# | ||
# @api private | ||
# @since v13.0.1 | ||
class MiddlewareTie | ||
def initialize(app) | ||
@app = app | ||
@middleware = app.config.middleware | ||
end | ||
|
||
def call | ||
return tie_rails_5_or_above if ::Rails.version.to_i >= 5 | ||
|
||
if defined?(::ActiveRecord::ConnectionAdapters::ConnectionManagement) | ||
return tie_rails_4_or_below_with_active_record | ||
end | ||
|
||
tie_rails_4_or_below_with_active_record | ||
end | ||
|
||
private | ||
|
||
# Avoid the warning about deprecated strings. | ||
# Insert after DebugExceptions, since ConnectionManagement doesn't | ||
# exist in Rails 5 anymore. | ||
def tie_rails_5_or_above | ||
@middleware.insert_after( | ||
ActionDispatch::DebugExceptions, | ||
Airbrake::Rack::Middleware, | ||
) | ||
end | ||
|
||
# Insert after ConnectionManagement to avoid DB connection leakage: | ||
# https://github.com/airbrake/airbrake/pull/568 | ||
def tie_rails_4_or_below_with_active_record | ||
@middleware.insert_after( | ||
::ActiveRecord::ConnectionAdapters::ConnectionManagement, | ||
'Airbrake::Rack::Middleware', | ||
) | ||
end | ||
|
||
# Insert after DebugExceptions for apps without ActiveRecord. | ||
def tie_rails_4_or_below_without_active_record | ||
@middleware.insert_after( | ||
ActionDispatch::DebugExceptions, | ||
'Airbrake::Rack::Middleware', | ||
) | ||
end | ||
end | ||
end | ||
end | ||
end |