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を共通コンテキストとして持たせたいことが多いので、コンテキスト伝搬ができると良い。ここは各言語・ライブラリで機能としては持ってそうだった 👍️