Node.jsのロガーライブラリの pino は以下のようなインターフェースでログ出力できる。
const pino = require('pino');
const logger = pino();
logger.info('string message');
logger.info({ message: 'json message' });
logger.info({ message: 'json message' }, 'string message');
見てもらえるとわかるように
- 第1引数が文字列のみ
- 第1引数がオブジェクトのみ
- 第1引数がオブジェクトで第2引数が文字列
に対応しているが、 第1引数が文字列で第2引数がオブジェクト(メタデータ・コンテキスト)
には対応していない。
他の言語のロガーはだいたいこの方式に対応していたりするので、pinoもこのインターフェースに対応したい。ということで以下のような感じでカスタマイズできる。
import pino from "pino";
const logger = pino({
hooks: {
logMethod(inputArgs, method) {
// 第1引数が文字列, 第2引数がオブジェクトの場合
if (
inputArgs.length === 2 &&
typeof inputArgs[0] === "string" &&
typeof inputArgs[1] === "object"
) {
const msg = inputArgs[0];
const context = inputArgs[1];
// @ts-expect-error
return method.apply(this, [{ ...context, msg }]);
}
// @ts-expect-error
return method.apply(this, inputArgs);
},
},
});
これで
logger.info("string message", { userId: 123 });
という感じで呼び出すと
{"level":30,"time":1756819989743,"pid":27639,"hostname":"xxxx","userId":123,"msg":"string message"}
という感じな出力になる。