0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js】軽量ロガーpinoの導入

0
Posted at

高速・低オーバーヘッドのロガー

pino

インストール

pnpm add pino pino-pretty

使い方

ロガーインスタンスの定義

pino 関数は2つの引数 optionsdestination を取り、ロガーインスタンスを返します。

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 オブジェクト) といったプレースホルダを設定可能です
  • ...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: "********"
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?