'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