debug の使い方 — Node.js・ブラウザ対応の軽量デバッグユーティリティ
一言でいうと
debug は、名前空間(namespace)ベースでデバッグログの出力を制御できる軽量ユーティリティです。環境変数 DEBUG を切り替えるだけで、アプリケーションやライブラリの特定部分のログを有効化・無効化できます。
どんな時に使う?
- ライブラリ開発時のデバッグログ埋め込み —
console.logを本番コードに残さず、利用者が必要な時だけログを有効化できる仕組みを提供したい場合 - 複雑なアプリケーションのモジュール別ログ制御 — HTTP層、DB層、認証層など、モジュールごとにログの出力を切り替えたい場合
- サードパーティライブラリの内部動作調査 — Express、Socket.IO、Mocha など多くの有名ライブラリが
debugを内部で使用しており、DEBUG環境変数を設定するだけで内部ログを確認できる
インストール
# npm
npm install debug
# yarn
yarn add debug
# pnpm
pnpm add debug
TypeScript で使う場合は型定義もインストールします。
npm install -D @types/debug
基本的な使い方
import createDebug from 'debug';
const debug = createDebug('myapp:server');
debug('サーバーを起動します port=%d', 3000);
debug('リクエストを受信 %O', { method: 'GET', path: '/api/users' });
実行時に環境変数 DEBUG を指定してログを有効化します。
# myapp:server のログだけ表示
DEBUG=myapp:server node dist/index.js
# myapp 配下のすべてのログを表示
DEBUG=myapp:* node dist/index.js
# すべてのデバッグログを表示
DEBUG=* node dist/index.js
DEBUG を設定しなければ、ログは一切出力されません。本番環境ではパフォーマンスへの影響がほぼゼロになります。
モジュール別に名前空間を分ける例
// src/db.ts
import createDebug from 'debug';
const debug = createDebug('myapp:db');
export function query(sql: string): void {
debug('SQL実行: %s', sql);
// ...
}
// src/auth.ts
import createDebug from 'debug';
const debug = createDebug('myapp:auth');
export function login(username: string): void {
debug('ログイン試行: user=%s', username);
// ...
}
# DB層のログだけ見たい場合
DEBUG=myapp:db node dist/index.js
# DB層と認証層の両方を見たい場合
DEBUG=myapp:db,myapp:auth node dist/index.js
よく使うAPI — debug の使い方詳細
1. デバッグインスタンスの作成
import createDebug from 'debug';
// 名前空間を指定してインスタンスを生成
const debug = createDebug('mylib:core');
debug('初期化完了');
名前空間には : 区切りの階層構造を使うのが慣例です。ライブラリ名をプレフィックスにし、機能名をサフィックスにします。
2. printf スタイルのフォーマッター
const debug = createDebug('myapp:api');
debug('文字列: %s', 'hello'); // %s — 文字列
debug('数値: %d', 42); // %d — 数値
debug('JSON: %j', { a: 1, b: 2 }); // %j — JSON(循環参照は [Circular])
debug('オブジェクト(1行): %o', { a: 1 }); // %o — 単一行で整形
debug('オブジェクト(複数行): %O', { a: 1, b: { c: 2 } }); // %O — 複数行で整形
debug('パーセント: 100%%'); // %% — リテラルの %
3. 有効・無効の動的切り替え(enable / disable)
import createDebug from 'debug';
// プログラムから動的に有効化
createDebug.enable('myapp:*');
const debug = createDebug('myapp:server');
debug('このログは表示されます');
// 無効化
createDebug.disable();
debug('このログは表示されません');
enable() は環境変数 DEBUG と同じ書式の文字列を受け取ります。テスト時やランタイムでの切り替えに便利です。
4. カスタムフォーマッターの追加
import createDebug from 'debug';
// Buffer を16進数で表示する %h フォーマッターを追加
createDebug.formatters.h = (v: Buffer) => {
return v.toString('hex');
};
const debug = createDebug('myapp:binary');
debug('データ: %h', Buffer.from('hello'));
// myapp:binary データ: 68656c6c6f +0ms
5. enabled プロパティによる条件分岐
import createDebug from 'debug';
const debug = createDebug('myapp:heavy');
// 重い処理をデバッグが有効な時だけ実行
if (debug.enabled) {
const expensiveData = JSON.stringify(someLargeObject, null, 2);
debug('詳細データ: %s', expensiveData);
}
debug.enabled は boolean を返します。コストの高いログ生成処理をガードするのに使います。
6. ブラウザでの使い方
ブラウザ環境では localStorage でログを制御します。
// ブラウザのコンソールで実行
localStorage.debug = 'myapp:*';
// 無効化
localStorage.removeItem('debug');
設定後にページをリロードすると、該当する名前空間のログがブラウザのコンソールに表示されます。
類似パッケージとの比較
| 特徴 | debug | pino | winston | console.log |
|---|---|---|---|---|
| 主な用途 | デバッグログ | 構造化ログ(本番向け) | 汎用ロガー(本番向け) | 簡易出力 |
| サイズ | 非常に軽量 | 軽量 | やや大きい | 組み込み |
| 構造化ログ(JSON) | ✕ | ◎ | ◎ | ✕ |
| 名前空間フィルタリング | ◎ | △ | △ | ✕ |
| ログレベル | ✕ | ◎ | ◎ | ✕ |
| ブラウザ対応 | ◎ | ✕ | △ | ◎ |
| ゼロコスト(無効時) | ◎ | — | — | ✕ |
| 週間DL数 | 約2.5億 | 約1,500万 | 約1,500万 | — |
使い分けの指針:
- ライブラリ開発や開発時のデバッグ →
debug - 本番環境の構造化ログ・ログレベル管理 →
pinoorwinston debugと本番ロガーは併用するのが一般的です
注意点・Tips
ワイルドカードと除外パターン
# すべて有効にしつつ、特定の名前空間を除外
DEBUG=*,-express:* node app.js
# 複数指定はカンマまたはスペース区切り
DEBUG=myapp:db,myapp:auth node app.js
- プレフィックスで除外できます。DEBUG=* で全ライブラリのログが大量に出る場合に活用してください。
名前空間の末尾に * を付けると常時有効
const debug = createDebug('myapp:critical*');
// この名前空間は DEBUG 環境変数の設定に関係なく常に出力される
重要なログを常に出したい場合に使えますが、乱用すると debug の利点が失われるので注意してください。
出力先は stderr
debug の出力先は console.error(= stderr)です。stdout ではありません。パイプやリダイレクトを使う際は注意が必要です。
# stderr だけファイルに保存
DEBUG=myapp:* node app.js 2> debug.log
環境変数による表示制御
| 環境変数 | 説明 |
|---|---|
DEBUG | 有効にする名前空間(ワイルドカード・除外対応) |
DEBUG_COLORS | 色付き出力の有効/無効(true / false) |
DEBUG_HIDE_DATE | 非TTY時の日付表示を隠す |
DEBUG_DEPTH | オブジェクトの展開深度(util.inspect の depth に対応) |
DEBUG_SHOW_HIDDEN | 隠しプロパティを表示 |
ミリ秒差分表示
各ログ行の末尾に +NNNms と表示されるのは、前回の debug() 呼び出しからの経過時間です。パフォーマンスのボトルネック調査に役立ちます。
TypeScript での型定義
import createDebug, { Debugger } from 'debug';
// 型を明示したい場合
const debug: Debugger = createDebug('myapp:server');
まとめ
debug は、環境変数ひとつでログの出力を制御できるシンプルかつ強力なデバッグツールです。Express をはじめとする多くの npm パッケージが内部で採用しており、Node.js エコシステムにおける事実上の標準デバッグ手法と言えます。本番ロガー(pino, winston など)と組み合わせて、開発時のデバッグログには debug を使うのがベストプラクティスです。