2025-09-03

ロガーインターフェースについて思いを馳せる

pinoのロガーインターフェースを変更する という記事を書いたが、そもそもロガーインターフェースって各言語 / FWどんな感じになってたっけ?というのを気になって調べたのでメモ。

自分が馴染みのある PHP Ruby Go Python Node.js が比較対象。

(string), (string, object) パターン

PHP / MonoLog

$log = new Logger('name');
$log->info('message');
$log->info('message', ['number' => 3]);

Python / logging

# extraを表示するにはformatterを調整する必要あり
logger.info('message', extra={'number': 3})

Go / slog

slog.Info("message")
slog.Info("message", slog.Int("number", 3))

(string) のみパターン

Ruby / Logger

logger.info('message')

ちなみにActiveSupportのTaggedLoggingを使うとタグ(コンテキスト)を付与したロガーを生成できる

logger = logger.tagged('context');

その他

(string), (object), (object, string) パターン

Node.js / pino

logger.info('string message');
logger.info({ message: 'json message' });
logger.info({ message: 'json message' }, 'string message');

(string, object), (object) パターン

winston

logger.info('string message');
logger.info('string message', { message: 'json' });
logger.info({ message: 'json' });

個人的に好んでいるロガーインターフェース

好みの問題かもしれないが (string, object) をサポートしていると嬉しいなと思っている。

というのが意図。

第1引数がオブジェクトだけのパターンだとログメッセージのフォーマットが揃わなくなる可能性がある(例えばあるログはmessageというキーがあるが他のログは無い、など)。

また、リクエストIDやURLを共通コンテキストとして持たせたいことが多いので、コンテキスト伝搬ができると良い。ここは各言語・ライブラリで機能としては持ってそうだった 👍️