高速・低オーバーヘッドのロガー
インストール
pnpm add pino pino-pretty
使い方
ロガーインスタンスの定義
pino 関数は2つの引数 options と destination を取り、ロガーインスタンスを返します。
src/lib/logger.ts
import pino from 'pino';
const isDev = process.env.NODE_ENV === 'development';
export const logger = pino({
// ログレベル
// level: https://getpino.io/#/docs/api?id=level-string
level: process.env.LOG_LEVEL || 'info',
// 時刻をISO形式にする
// timestamp: https://getpino.io/#/docs/api?id=timestamp-boolean-function
timestamp: pino.stdTimeFunctions.isoTime,
// センシティブな情報のマスキング
// redact: https://getpino.io/#/docs/api?id=redact-array-object
redact: {
paths: ['req.headers.authorization', 'password', 'email', '*.password'],
censor: '********', # pathsにマッチするキーの値をこの値に置換
},
// コンテナ環境でpid, hostnameは不要なので出力しない
// base: https://getpino.io/#/docs/api?id=base-object
base: {
pid: undefined, // プロセスIDを出力しない
hostname: undefined, // ホスト名を出力しない
},
// クライアント側のログはサーバーへ送信せず、コンソールに表示するだけ
// browser: https://getpino.io/#/docs/api?id=browser-object
// - BrowserAPI: https://getpino.io/#/docs/browser
browser: {
asObject: true // ブラウザのコンソールでもオブジェクトとして表示
},
// 開発時は見やすく、本番環境ではjson形式
// transport: https://getpino.io/#/docs/api?id=transport-object
// - pino.transport(options): https://getpino.io/#/docs/api?id=pino-transport
...(isDev && {
transport: {
// Pretty Printing: https://getpino.io/#/docs/pretty
// pino-pretty: https://github.com/pinojs/pino-pretty
target: 'pino-pretty',
// pino-pretty options: https://github.com/pinojs/pino-pretty?tab=readme-ov-file#options
options: {
colorize: true, // 色
translateTime: 'SYS:standard', // エポックタイム値を人間が読みやすい日付と時刻の文字列に変換
ignore: 'pid,hostname', // pretty上でもpid, hostname項目を無視
},
},
}),
});
ロガーインスタンスを使用する
ロガーインスタンスには trace, debug, info, warn, error, fatal といったメソッドがあります。
これらのメソッドは ([mergingObject], [message], [...interpolationValues]) という引数を取ります。
-
mergingObject(object)- 任意のオブジェクトで、個々に定義したキーと値はJSONログにマージされます。
-
message(string)- JSONログの
msgキーの値となります。 - (
%s文字列) (%d数値) (%O%o%jオブジェクト) といったプレースホルダを設定可能です
- JSONログの
-
...interpolationValues(any)-
message以降の引数にはmessageに設定したプレースホルダの値を指定できます。
-
src/main.ts
import {logger} from '@/logger'
// logger.info: https://getpino.io/#/docs/api?id=info
logger.info(
// mergingObject
{userId: "keita.midorikawa", req: {headers: {authorization: "hoge"}}, password: "hogehoge"},
// message
'ユーザーデータを取得しました。 %s %d %O',
// ...interpolationValues
"hello", 100, {a: "hoge"}
);
実行
本番環境
pnpm tsx src/main.ts
# {"level":30,"time":"2026-01-31T14:43:35.591Z","userId":"keita.midorikawa","req":{"headers":{"authorization":"********"}},"password":"********","msg":"ユーザーデータを取得しました。 hello 100 {\"a\":\"hoge\"}"}
開発環境
NODE_ENV=development pnpm tsx src/main.ts
# [2026-01-31 23:43:51.627 +0900] INFO: ユーザーデータを取得しました。 hello 100 {"a":"hoge"}
# userId: "keita.midorikawa"
# req: {
# "headers": {
# "authorization": "********"
# }
# }
# password: "********"