Rails.loggerをSemantic Loggerで置き換えるgem。 Rails.loggerを個別で呼び出す際はもちろんだが、RackやControllerのAction呼び出し、ActiveJobの実行などRailsの標準ログ機構を網羅的にSemantic Loggerで置き換えてくれる。
何がどのように置き換えられているのか気になったので、Semantic Loggerを導入することで、Rails.loggerや各ログ出力箇所をどのように置き換えているのかを調べてみることにする。
rails_semantic_loggerのソースコードを見ていく。
lib/rails_semantic_logger/engine.rb
に::Rails::Engine
を継承したクラスで諸々の置き換えが定義されていることがわかる。
Rails::Engine
クラスを継承すると、gemのパス上にEngineが存在することをRails側から把握することができ、起動時にマウントされる仕組みになっている。
rails_semantic_loggerではこの仕組みを利用して、Railsアプリケーションの初期化フローの中で、Rails.loggerと各ログ出力箇所の置き換えを行っている。
参考: Rails Engine
以下は該当箇所
...
initializer :initialize_logger, group: :all do
...
Rails.logger = config.logger =
begin
...
end
end
...
DelayedJobのloggerの置き換え
以下は該当箇所
...
# Replace the DelayedJob logger
if defined?(Delayed::Worker)
Delayed::Worker.logger = SemanticLogger[Delayed::Worker]
Delayed::Worker.plugins << RailsSemanticLogger::DelayedJob::Plugin
end
...
lib/rails_semantic_logger/extensions
配下にあるパッチを当てることで、ログ機能の拡張を行っている。
以下は該当箇所
config.after_initialize do
# Rails Patches
...
require("rails_semantic_logger/extensions/active_job/logging") if defined?(::ActiveJob)
...
end
# Patch ActiveJob logger
require "active_job/logging"
module ActiveJob
module Logging
include SemanticLogger::Loggable
private
undef_method :tag_logger
def tag_logger(*tags, &block)
if logger.respond_to?(:tagged)
logger.tagged(*tags, &block)
else
yield
end
end
end
end
ActiveSupport::LogSubscriber
の継承クラスが存在する場合(ActiveRecord::LogSubscriber
など)については、Rails Semantic Loggerで定義されたLogSubscriber
クラスに置き換える。
lib/rails_semantic_logger
配下に各内部フレームワークのLog Subscriberを置き換えるためのLog Subscriberクラスが配置されている。
以下は該当箇所
config.after_initialize do
...
if defined?(::ActiveRecord)
require "active_record/log_subscriber"
RailsSemanticLogger.swap_subscriber(
::ActiveRecord::LogSubscriber,
RailsSemanticLogger::ActiveRecord::LogSubscriber,
:active_record
)
end
...
end