Railsのログに関連する機能を整理しておく。
config/application.rb
または、config/environments/
配下の環境毎の設定ファイルで設定する。
config.logger = Logger.new(STDOUT)
config.logger = Log4r::Logger.new("Application Log")
または、config/initializers
配下のファイルで
Rails.logger = Logger.new(STDOUT)
Rails.logger = Log4r::Logger.new("Application Log")
初期化後もアプリケーション実行中にRails.logger
や設定を変更することが可能
Rails.logger.level = 0
参考: Rails Loggerについて
Railsからログ出力するためのloggerインスタンスを保持するグローバルなクラス変数。
基本的には、後述するActiveSupport::Logger
クラス(もしくはその継承クラス)のインスタンスが設定される。
railties/lib/rails.rbに定義されている。
module Rails
...
class << self
...
attr_accessor :app_class, :cache, :logger
...
end
...
end
railties/lib/rails/application/bootstrap.rbでRails.logger
が初期化される。
config/application.rb
やconfig/environments/
配下の設定ファイルActiveSupport::TaggedLogging
のインスタンスが指定されるするようになっている
module Rails
module Bootstrap
...
initializer :initialize_logger, group: :all do
Rails.logger ||= config.logger || begin
...
end
...
end
...
end
end
Ruby標準のLoggerクラスを継承したクラス。 Ruby標準のLoggerクラスの薄いWrapperという理解が正しそう。スレッドセーフにログレベルを設定することができる拡張などがされている。
activesupport/lib/active_support/logger.rb
Rails.loggerに指定するloggerはRuby標準のLoggerクラスのインターフェースに準拠することで、独自のものを作成することも可能。 また、互換性を保つために、以下のようなルールで作成する必要がある。
- フォーマッターをサポートする場合は、config.log_formatterの値を手動でロガーに代入しなければなりません。
- タグ付きログをサポートする場合は、そのログのインスタンスをActiveSupport::TaggedLoggingでラップしなければなりません。
- ログ出力の抑制をサポートするには、LoggerSilenceモジュールをincludeしなければなりません。ActiveSupport::Loggerクラスは既にこれらのモジュールをincludeしています。
例
class MyLogger < ::Logger
include ActiveSupport::LoggerSilence
end
mylogger = MyLogger.new(STDOUT)
mylogger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(mylogger)
参考: https://railsguides.jp/configuring.html#config-logger
複数のIOに向けてログを出力するために、別々のLoggerインスタンスを統合する機能を提供するクラス.
stdout_logger = Logger.new(STDOUT)
file_logger = Logger.new("development.log")
broadcast = BroadcastLogger.new(stdout_logger, file_logger)
broadcast.info("Hello world!") # Writes the log to STDOUT and the development.log file.
扱いとしては、ActiveSupport::Logger
クラスと同じで、標準のLoggerクラスと同じメソッドを使うことができる。
実際のところは、登録されたLoggerインスタンスに処理を移譲しているだけ。
activesupport/lib/active_support/broadcast_logger.rb
参考: https://api.rubyonrails.org/classes/ActiveSupport/BroadcastLogger.html
Ruby標準のLoggerクラスを継承したクラスのオブジェクトをWrapし、ログに対してのタグ付け機能を追加するためのクラス。
ブロックを使う方法
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff"
logger.tagged('BCX', "Jason") { |tagged_logger| tagged_logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff"
logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
ブロックなし
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
logger.tagged("BCX").info "Stuff" # Logs "[BCX] Stuff"
logger.tagged("BCX", "Jason").info "Stuff" # Logs "[BCX] [Jason] Stuff"
logger.tagged("BCX").tagged("Jason").info "Stuff" # Logs "[BCX] [Jason] Stuff"
参考: TaggedLogging
activesupport/lib/active_support/tagged_logging.rbでloggerが拡張される。
ActiveSupport::TaggedLogging::Formatter
にActiveSupport::TaggedLogging
モジュールで拡張しているそれぞれ拡張している。
module ActiveSupport
module TaggedLogging
module Formatter
...
end
...
def self.new(logger)
...
logger.formatter.extend Formatter
logger.extend(self)
end
...
end
end
ActiveSupport::Notification
イベントをログとして出力するためのSubscriberクラス。
loggerそのものではなく、フレームワークやアプリケーション上のイベントを購読してログ出力をするなど、ログ出力にあたっての後工程のカスタマイズを容易にする。
attach_to
でactive_record
namespaceをActiveSupport::Notifications
(Publisher)に登録することで、該当のイベントを購読することができる。
例
module ActiveRecord
class LogSubscriber < ActiveSupport::LogSubscriber
attach_to :active_record
def sql(event)
info "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
end
end
end
ActiveSupport::Notifications
の仕組みについては、また別で取り上げることにする。