Skip to content

Commit

Permalink
railties/active_record: read 'adapter' without requiring a DB conn
Browse files Browse the repository at this point in the history
Fixes #1222
(Airbrake Gem Attempts to Connect to Database in Databaseless App in Rails 6)

Good article:
https://www.bigbinary.com/blog/rails-6-changed-activerecord-base-configurations-result-to-an-object

We also add a guard that makes sure there's an ActiveRecord configuration
present (it can be that ActiveRecord is required but not configured; why? I have
no idea but it did happen to our customer and he's got no clue either).
  • Loading branch information
kyrylo committed May 13, 2022
1 parent a1d79ed commit d4a2eff
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Airbrake Changelog
* Fixed support of APM on Rails 7+, where the reported time of a route was
malformed, resulting in the complete rejection of the route stats by the
backend ([#1223](https://github.com/airbrake/airbrake/issues/1223))
* Fixed bug where Rails 6+ apps that don't require ActiveRecord crash when
Airbrake is installed
([#1224](https://github.com/airbrake/airbrake/pull/1224))

### [v13.0.0][v13.0.0] (January 18, 2022)

Expand Down
39 changes: 24 additions & 15 deletions lib/airbrake/rails/railties/active_record_tie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,15 @@ def tie_activerecord_callback_fix
end

def tie_activerecord_apm
return unless defined?(ActiveRecord)
# Some Rails apps don't use ActiveRecord.
return unless defined?(::ActiveRecord)

# However, some dependencies might still require it, so we need an
# extra check. Apps that don't need ActiveRecord will likely have no
# AR configurations defined. We will skip APM integration in that
# case. See: https://github.com/airbrake/airbrake/issues/1222
configurations = ::ActiveRecord::Base.configurations
return unless configurations.any?

# Send SQL queries.
ActiveSupport::Notifications.subscribe(
Expand All @@ -43,21 +51,22 @@ def tie_activerecord_apm
)

# 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],
),
)
sql_filter = Airbrake::Filters::SqlFilter.new(
detect_activerecord_adapter(configurations),
)
Airbrake.add_performance_filter(sql_filter)
end

# Rails 6+ introduces the `configs_for` API instead of the deprecated
# `#[]`, so we need an updated call.
def detect_activerecord_adapter(configurations)
unless configurations.respond_to?(:configs_for)
return configurations[::Rails.env]['adapter']
end

cfg = configurations.configs_for(env_name: ::Rails.env).first
# Rails 7+ API : Rails 6 API.
cfg.respond_to?(:adapter) ? cfg.adapter : cfg.config['adapter']
end
end
end
Expand Down

0 comments on commit d4a2eff

Please sign in to comment.