kakudooo docs

Rails.loggerのJSON Formatterを自作してみる | その①

Rails.loggerを拡張してJSON形式の構造化ロギングを自作してみるシリーズの1回目

スコープ

Rails.loggerでJSON形式のログが出力されるところまで。

JSON Formatterの作成

Formatterの作成

Ruby標準ライブラリのLogger::Formatterを継承してサブクラスを作成する。 callメソッドで受け取れる各パラメーターをJSON文字列に変換する。

config/json_formatter.rb

class JsonFormatter < ::Logger::Formatter
  def call(severity, timestamp, progname, msg)
    {
      severity:,
      timestamp:,
      progname:,
      msg:
    }.to_json
  end
end

Rails.loggerの差し替え

  1. Ruby標準ライブラリのLoggerクラスのオブジェクトを作成して、formatterを作成したJsonFormatterクラスのオブジェクトに設定する
  2. config.loggerに作成したloggerを渡す

config/environments/development.rb

...
require_relative "../json_formatter"
...

logger = Logger.new("development.log")
logger.formatter = JsonFormatter.new
config.logger = logger

結果

構造化ログが出力されることを確認できた。

{"severity":"INFO","timestamp":"2025-09-07T09:10:11.188+00:00","progname":null,"msg":"Completed 200 OK in 162ms (Views: 25.5ms | ActiveRecord: 0.0ms (0 queries, 0 cached) | GC: 1.3ms)\n\n"}

ただし、msg(ログの本文)は構造化されておらず、このままだと構造化ログとして不完全である。 Loggerクラスを拡張して、ログの本文が構造化された状態でFormatterに受け渡しできるようにしたい。

次回は、Rails.logger.infoなどseverity毎のメソッドにメッセージに加えて、hashとしてログの本文を渡せるようにしていく。

参考