Skip to content
Go back

pino-pretty を試してみた - 開発時に読みやすいログを出力する

はと🐤テック

Disclaimer: This article was written by AI and may contain inaccuracies or errors.

Table of contents

Open Table of contents

はじめに

Node.js で高速なロギングライブラリとして知られている Pino は、本番環境でのパフォーマンスを重視して JSON 形式でログを出力します。

しかし、開発中にこの JSON ログをターミナルで見るのは少し読みづらいものです。

{
  "level": 30,
  "time": 1761276937425,
  "pid": 3115,
  "hostname": "runsc",
  "msg": "Starting application"
}

このような JSON の羅列を眺めるよりも、もっと読みやすい形式で表示できたら便利です。

そこで登場するのが pino-pretty です。このライブラリは、Pino が出力する JSON ログを開発者にとって読みやすい形式に整形してくれます。

今回、実際に動かして試してみたので、その体験をレポートします。

pino-pretty とは

pino-pretty は、ndjson(改行区切りの JSON)形式のログを人間が読みやすい形式に変換してくれるフォーマッターです。Pino のログ専用に設計されており、ログレベルや タイムスタンプなどを考慮した整形を行ってくれます。

主な特徴

用途

公式ドキュメントでも明記されていますが、pino-pretty は 開発環境での使用を想定 しています。本番環境では、パフォーマンスを重視して JSON のまま出力し、ログ収集システムで処理することが推奨されています。

セットアップ

pino-pretty のインストール方法はいくつかあります。

グローバルインストール

CLI ツールとして使う場合:

npm install -g pino-pretty

開発用依存関係として

プロジェクトごとに管理する場合(推奨):

npm install --save-dev pino pino-pretty

または

pnpm install --save-dev pino pino-pretty

実際に試してみる

実際にどのように動作するか確かめるため、いくつかのパターンで試してみました。

1. transport として使う(Pino v7+)

最もシンプルな方法は、Pino の transport 機能を使う方法です。

// basic-usage.js
const pino = require("pino");

const logger = pino({
  transport: {
    target: "pino-pretty",
    options: {
      colorize: true,
    },
  },
});

// 様々なログレベル
logger.trace("This is a trace message");
logger.debug("This is a debug message");
logger.info("This is an info message");
logger.warn("This is a warning message");
logger.error("This is an error message");
logger.fatal("This is a fatal message");

// 追加データと一緒にログ
logger.info({ user: "john", id: 123 }, "User logged in");

// エラーをログ
const error = new Error("Something went wrong!");
logger.error({ err: error }, "An error occurred");

// カスタムフィールド
logger.info(
  {
    requestId: "req-001",
    method: "GET",
    url: "/api/users",
    duration: 45,
  },
  "HTTP request completed"
);

このコードを実行すると、以下のような出力が得られます:

[03:35:29.337] INFO (2698): This is an info message
[03:35:29.337] WARN (2698): This is a warning message
[03:35:29.337] ERROR (2698): This is an error message
[03:35:29.337] FATAL (2698): This is a fatal message
[03:35:29.426] INFO (2698): User logged in
    user: "john"
    id: 123
[03:35:29.426] ERROR (2698): An error occurred
    err: {
      "type": "Error",
      "message": "Something went wrong!",
      "stack":
          Error: Something went wrong!
              at Object.<anonymous> (/tmp/pino-pretty-test/my-test-app/basic-usage.js:25:15)
              at Module._compile (node:internal/modules/cjs/loader:1706:14)
              ...
    }
[03:35:29.427] INFO (2698): HTTP request completed
    requestId: "req-001"
    method: "GET"
    url: "/api/users"
    duration: 45

ログレベルごとに色分けされ(実際のターミナルでは色がつきます)、オブジェクトのフィールドがインデントされて見やすく表示されます。エラーのスタックトレースも整形されています。

2. CLI パイプとして使う

従来の方法として、標準の Pino ロガーの出力をパイプする使い方もあります。

// cli-usage.js
const pino = require("pino");

const logger = pino();

logger.info("Starting application");
logger.info(
  { database: "postgresql", host: "localhost", port: 5432 },
  "Database connected"
);
logger.warn({ memory: "80%" }, "High memory usage detected");
logger.info({ users: 42, active: 38 }, "Active users summary");
logger.error(
  { code: "ECONNREFUSED", attempt: 3 },
  "Failed to connect to service"
);
logger.info("Application shutting down");

このコードを pino-pretty なしで実行すると、JSON がそのまま出力されます:

$ node cli-usage.js
{"level":30,"time":1761276937425,"pid":3115,"hostname":"runsc","msg":"Starting application"}
{"level":30,"time":1761276937426,"pid":3115,"hostname":"runsc","database":"postgresql","host":"localhost","port":5432,"msg":"Database connected"}
{"level":40,"time":1761276937426,"pid":3115,"hostname":"runsc","memory":"80%","msg":"High memory usage detected"}

これを pino-pretty にパイプすると:

$ node cli-usage.js | npx pino-pretty
[03:35:44.243] INFO (3532): Starting application
[03:35:44.244] INFO (3532): Database connected
    database: "postgresql"
    host: "localhost"
    port: 5432
[03:35:44.244] WARN (3532): High memory usage detected
    memory: "80%"
[03:35:44.244] INFO (3532): Active users summary
    users: 42
    active: 38
[03:35:44.244] ERROR (3532): Failed to connect to service
    code: "ECONNREFUSED"
    attempt: 3
[03:35:44.244] INFO (3532): Application shutting down

JSON がきれいに整形され、ログの内容が把握しやすくなりました。

3. カスタム設定を使う

pino-pretty は様々な設定オプションを提供しています。タイムスタンプのフォーマットや表示フィールドをカスタマイズできます。

// custom-config.js
const pino = require("pino");

const logger = pino({
  transport: {
    target: "pino-pretty",
    options: {
      colorize: true,
      translateTime: "SYS:yyyy-mm-dd HH:MM:ss",
      ignore: "pid,hostname",
      levelFirst: true,
    },
  },
});

logger.info("Custom formatted message");
logger.info({ userId: 100, action: "login" }, "User action tracked");
logger.warn(
  { temperature: 85, threshold: 80 },
  "Temperature threshold exceeded"
);
logger.error({ code: 404, path: "/api/missing" }, "Resource not found");

実行結果:

INFO [2025-10-24 03:35:52]: Custom formatted message
INFO [2025-10-24 03:35:52]: User action tracked
    userId: 100
    action: "login"
WARN [2025-10-24 03:35:52]: Temperature threshold exceeded
    temperature: 85
    threshold: 80
ERROR [2025-10-24 03:35:52]: Resource not found
    code: 404
    path: "/api/missing"

設定によって出力フォーマットが変わりました:

主な設定オプション

pino-pretty には 40 以上の設定オプションがありますが、特によく使いそうなものをいくつか紹介します。

表示関連

タイムスタンプ関連

フィルタリング関連

メッセージフォーマット

良かった点

1. 開発体験の向上

JSON の羅列を読むよりも、整形された形式の方が圧倒的に読みやすいです。特にオブジェクトのフィールドがインデントされて表示されるのは、ログの内容を素早く把握するのに役立つと感じました。

2. 色分けによる視認性

ログレベルごとに色が変わるので、WARNING や ERROR がすぐに目に入ります。大量のログが流れる中でも、重要な情報を見逃しにくくなると思います。

3. 柔軟な使い方

transport として組み込む方法と、パイプで使う方法の両方が用意されています。既存のコードを変更せずに使いたい場合はパイプ、新規プロジェクトや本格的に導入したい場合は transport、という使い分けができます。

4. エラー表示の工夫

エラーオブジェクトのスタックトレースが見やすく整形されます。開発中のデバッグ作業が楽になると感じました。

5. カスタマイズ性

タイムスタンプのフォーマットや表示フィールドなど、細かくカスタマイズできます。チームやプロジェクトの好みに合わせて調整できるのは良いと思います。

6. シンプルな導入

設定なしでも動作するため、まず試してみることができます。必要に応じて徐々にカスタマイズしていけるのは学習コストが低くて助かります。

気づいた点

1. 開発環境専用

公式ドキュメントにも明記されていますが、本番環境での使用は推奨されていません。フォーマット処理のオーバーヘッドがあるため、本番では JSON のまま出力することが想定されています。

この点は制限というよりも、適切な使い分けを促すための設計思想だと感じます。

2. transport のパフォーマンス

transport として組み込んだ場合、ログ出力のたびにフォーマット処理が走ります。開発環境では問題になりませんが、大量のログを出力する場合は、パイプ方式の方がパフォーマンスが良いかもしれません。

3. カスタムフォーマットの学習

messageFormat などの高度なカスタマイズを行う場合は、少し学習が必要です。ただし、基本的な使い方だけなら特に学ぶべきことは少ないので、必要になってから調べても十分だと思います。

まとめ

私が感じたこと

pino-pretty は、開発時のログの読みやすさを劇的に改善してくれるツールだと感じました。特に以下の点が印象的でした:

どんな場合に使えそうか

以下のような場面で特に有用だと思います:

逆に、以下のような場合は不要かもしれません:

個人的な感想

実際に動かしてみて、JSON ログと整形されたログの読みやすさの差を体感できたのは良かったです。特に、エラーオブジェクトのスタックトレースがきれいに表示される点は、ドキュメントを読むだけでは伝わりにくい部分だと思いました。

開発中のログの読みづらさに悩んでいる方や、Pino を使い始めた方には、ぜひ試してみることをお勧めします。

参考リンク

検証環境

本記事で使用したパッケージのバージョン:


pino-pretty を実際に試してみて、開発時のログの読みやすさが大きく向上することが分かりました。

この記事が、Node.js でのロギングを改善したい方の参考になれば幸いです。


Share this post on:

Previous Post
remark-callout を試してみた - Obsidian風のコールアウト記法をマークダウンで
Next Post
nuqs を試してみた - URL のクエリパラメータを React の state のように扱えるライブラリ