'Include the role of Active Record queries in logs
Rails now includes support for multiple database roles (by default, writing for the primary and reading for the replica):
ActiveRecord::Base.connected_to(role: :reading) do
# all code in this block will be connected to the reading role
end
In development, Active Record queries are logged by default, for example:
> User.last
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ? [["LIMIT", 1]]
How can I include the role used for a query in the logging? For example:
> ActiveRecord::Base.connnected_to(role: :reading) { User.last }
[role: reading] User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ? [["LIMIT", 1]]
Solution 1:[1]
since all query will be logged by the method log of class AbstractAdapter at the finally step, regardless which database adapter you're using: postgresql, mysql,.. So you could override that method and prepend the role
# lib/extent_dblog.rb
ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
alias_method(:origin_log, :log)
def log(sql, name = 'SQL', binds = [],
type_casted_binds = [], statement_name = nil, &block)
# prepend the current role before the log
name = "[role: #{ActiveRecord::Base.current_role}] #{name}"
origin_log(sql, name, binds, type_casted_binds, statement_name, &block)
end
end
# config/initializers/ext_log.rb
require File.join(Rails.root, "lib", "extent_dblog.rb")
demo
# config/application.rb
...
config.active_record.reading_role = :dev
config.active_record.reading_role = :test
# app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
connects_to database: { dev: :development, test: :test }
end
ActiveRecord::Base.connected_to(role: :dev) do
Target.all
end
# [role: dev] (0.6ms) SELECT "targets".* FROM "targets"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Lam Phan |
