Claude Media
Claude Codeの--debugと--debug-fileでログ出力先を切り替える

Claude Codeの--debugと--debug-fileでログ出力先を切り替える

Claude Codeの--debugはカテゴリ別ログ、--debug-fileは出力先の指定に使うフラグです。既定の保存先やCLAUDE_CODE_DEBUG_LOGS_DIRとの優先順位を扱います。

Claude Codeの--debugは、セッション内部の動作をログファイルに書き出すデバッグモードを有効にするフラグです。カテゴリを絞った出力に対応し、mcpstartupのような対象だけを拾えます。--debug-fileは出力先のパスを直接指定するフラグで、指定するだけでデバッグモードも暗黙に有効になります。既定の保存先や環境変数との優先順位、カテゴリを絞ったログの指定方法をこの記事で具体的に扱います。

--debugと--debug-fileの役割の違い

--debugはデバッグモードを有効にするだけで、出力先は既定値の~/.claude/debug/<session-id>.txtになります。--debug-file <path>は出力先を指定した場所に固定し、その指定自体がデバッグモードの有効化も兼ねます。つまり--debug-fileだけを付ければ十分で、--debugと併用する必要はありません。

似た働きをするものが、ほかに2つあります。1つは環境変数DEBUGで、1を設定すると--debugと同等になります。ただし有効になるのは1trueyesonの4値だけです。他のツール向けにDEBUG=express:*のような名前空間フィルタをシェルに設定していても、Claude Codeのデバッグモードは誤って有効になりません。

もう1つはセッション内スラッシュコマンドの/debugです。既に起動しているセッションの途中からログ収集を始められます。claude --debugを付けずに起動したセッションでは、/debugを実行した時点から先のログしか残りません。起動前の挙動を追いたいなら、最初から--debug--debug-fileを付ける必要があります。

--debugclaude --helpが明示するオプションで、ターミナルには何も表示しません。ログはすべてファイルに書かれます。この挙動は初めて使うときに戸惑いやすいポイントです。

似た名前の--verboseと混同しないよう注意します。--verboseはターミナルの表示をターン単位の詳細出力に切り替えるフラグで、ログファイルを書き出すわけではありません。画面上で今の動きを詳しく見たいなら--verbose、あとから追跡できる記録を残したいなら--debug--debug-file、という役割分担になります。

カテゴリを絞ってログを出す書き方

--debugは値なしでも使えますが、=で値を結合するとカテゴリでログを絞り込めます。公式ドキュメントが挙げる例は--debug='mcp,startup'(mcpとstartupに関するログだけを出す)と--debug='!1p'(先頭に!を付けたカテゴリを除外する)です。

claude --debug='mcp,startup'

ここで注意が必要なのは結合の仕方です。フィルタが効くのは=で値を結合した場合だけで、スペース区切りでclaude --debug mcp,startupのように書くと、mcp,startupはフィルタとして紐づきません。この場合はカテゴリを絞らないデバッグモードが有効になるだけで、後ろの文字列は別の引数として扱われます。カテゴリで絞りたいときは必ず=を使い、シェルの解釈を避けるためクォートで囲みます。

--debug-fileで出力先を指定する

--debug-file <path>は指定したファイルパスにログを書き出します。CLAUDE_CODE_DEBUG_LOGS_DIRという環境変数も出力先を上書きできますが、両方を設定した場合は--debug-fileが優先されます。

claude --debug-file /tmp/claude-debug.log

CLAUDE_CODE_DEBUG_LOGS_DIRには注意点があります。名前にDIRと付いていますが、実際に受け取るのはディレクトリではなくファイルパスです。さらに、この変数を設定するだけではログは出ません。デバッグモード自体を--debug/debugDEBUG環境変数のいずれかで別途有効にする必要があります。--debug-fileはパス指定と有効化を1つのフラグで済ませられる分、単体で完結する書き方です。

出力先を指定する場面としてよくあるのが、フックの起動確認です。--init-onlyと組み合わせると、セッションを開始せずにSetupフックとSessionStartフックだけを実行して終了できます。

claude --debug-file /tmp/claude-init.log --init-only

このコマンドは何も画面に表示しません。フックが実際に走ったかどうかは、指定したログファイルを開いてSetupとSessionStartのイベント行を確認します。

ログレベルをCLAUDE_CODE_DEBUG_LOG_LEVELで変える

デバッグログに書き込む最小のログレベルはCLAUDE_CODE_DEBUG_LOG_LEVELで調整します。既定はdebugです。

レベル詳細度使いどころ
verbose詳細度最大使いどころステータスラインコマンドの出力全文など、高頻度な診断情報まで見たいとき
debug(既定)詳細度標準使いどころ通常のトラブルシューティング
info / warn詳細度抑制使いどころノイズを減らしたいが警告以上は残したいとき
error詳細度最小使いどころエラーだけを追いたいとき

verboseにすると、フックのマッチャーがどのイベントで何個ヒットしたかといった細かい行まで出るようになります。逆にログが多すぎて追えないときはerrorまで絞り込めます。

MCPとHooksの調査で使う具体例

カテゴリ絞り込みが実際に効くのは、原因の見当がついている場面です。MCPサーバーが接続済みなのにツールを1つも返さないときは、次のように絞ります。

claude --debug=mcp

サーバー起動時のstderrがそのままデバッグログに残るため、ハンドシェイクの失敗理由をここで確認できます。MCP接続そのものが失敗している場合の切り分け手順は、MCPサーバーに接続できないときの切り分け手順で層ごとに扱っています。

Hooksが発火しない・期待通りに終了コードを返さないときは、カテゴリを絞らない--debugでイベントごとのマッチャー照合と終了コードを見るのが早道です。ログには[DEBUG] Hook output does not start with {, treating as plain textのような行が出て、Claude Codeがフックの出力をどう解釈したかが分かります。フックの種類ごとの挙動やイベント一覧はClaude Code Hooks完全ガイドにまとめてあります。

このほかにも、Windows環境でCLAUDE_CODE_GIT_BASH_PATHに指定したパスが認識されないときや、OpenTelemetryのエクスポーターがPrometheusのポート衝突などでエラーを出さずに失敗するときも、--debugを付けるとその場では表示されない警告がログに残ります。スペルチェッカーが期待した辞書を使っているか調べるときも同様で、[spellcheck]のログ行を--debug付きで起動してから確認する手順が公式に示されています。

フックのJSON出力が期待するスキーマに合わないケースも同じ扱いです。非同期フックが返したJSONのうち、systemMessageのように型が違うフィールドがあると、Claude Codeはそのフィールドだけを黙って捨てて処理を続けます。--debugを付けていれば、どのフィールドが捨てられたかを警告として確認できます。PowerShellで書いたフックに$CLAUDE_PROJECT_DIRをそのまま書いてしまい、未定義のローカル変数として$nullに解決されるためパスが壊れる、という取り違えも同様にデバッグログへ警告が残ります。

settings.jsonまわりの無言の読み飛ばしも--debugで表に出ます。プロジェクト設定やローカル設定には、リポジトリの持ち主が制御すべきでない環境変数を書けないようになっており、該当する値は黙って読み飛ばされますが、--debugを付けて起動すればその警告が確認できます。ステータスラインのtips設定に不正なエントリが混ざっていた場合も、設定ファイルごとは無効にならず、該当エントリだけがデバッグログへの警告付きで読み飛ばされます。設定ファイルの値がどのスコープで上書きされているかまで含めた切り分けは、Claude Code設定が反映されない原因の探し方がより広い範囲をカバーしています。

フックイベントの中には、失敗情報がデバッグログにしか残らないものもあります。ConfigChangeフックが設定変更をブロックしたとき、理由はユーザーにもClaudeにも表示されず、デバッグログに一行だけ記録されます。register_repo_rootフックのsystemMessageや失敗時の出力も同様にデバッグログ止まりで、--debugなしでは何が起きたか分かりません。デバッグログはgrep前提の生テキストなので、grep '\[ERROR\]'のようにレベル名で絞り込むと目的の行を拾いやすくなります。

なお/doctorclaude doctorは起動できるかどうか・設定ファイルが壊れていないかを診断するコマンドで、実行中のセッションが何をしているかを追う--debugとは目的が異なります。設定が読み込まれているか自体を疑うときは/doctor、読み込まれた後の挙動を追うときは--debug、と使い分けます。

4つの有効化手段の使い分け早見表

デバッグログを出す手段は--debug--debug-fileDEBUG環境変数・/debugの4つに分かれます。それぞれ出力先の決め方と向く場面が違います。

手段出力先向く場面制約
--debug出力先既定パス(~/.claude/debug/<session-id>.txt)向く場面起動時からカテゴリを絞って調べたい制約ターミナル非表示、フィルタは=結合のみ有効
--debug-file <path>出力先指定したパス(既定・環境変数より優先)向く場面フックの起動確認など決まった場所にログを残したい制約指定するだけでデバッグモードも暗黙に有効
DEBUG=1出力先既定パスまたはCLAUDE_CODE_DEBUG_LOGS_DIR向く場面フラグを渡しにくいスクリプトやCIから有効化したい制約1/true/yes/on以外の値では有効化されない
/debug [説明]出力先既定パス(実行時点から記録開始)向く場面対話セッションの途中で急に記録を取りたい制約--debug付きで起動していない限りそれ以前のログは残らない

起動前から追いたいなら--debug--debug-file、セッションの途中で気づいたら/debug、CIやラッパースクリプトからはDEBUG=1、という住み分けになります。

よくあるつまずき

フィルタが効かない: claude --debug mcp,startupのようにスペースで区切ると、mcp,startupはフィルタとして扱われません。--debug='mcp,startup'=で結合してください。

CLAUDE_CODE_DEBUG_LOGS_DIRだけ設定してもログが出ない: この変数は出力先を上書きするだけで、デバッグモード自体は有効化しません。--debug/debugDEBUG=1のいずれかと組み合わせる必要があります。

--debugを付けたのに画面に何も出ない: 想定どおりの挙動です。--debugはログをファイルにだけ書き込み、ターミナルには表示しません。ログは~/.claude/debug/<session-id>.txt(または指定したパス)を開いて確認します。

セッションIDでファイルが分かれて追いづらい: セッションを再開するたびにログファイルの場所を探し直すのが面倒なら、--debug-fileで固定パスを指定しておくと同じファイルを開き続けられます。

まとめ

--debugはカテゴリを絞れるデバッグモードの有効化フラグで、--debug-fileは出力先を固定しつつ有効化も兼ねるフラグです。カテゴリ指定は=結合のときだけ効き、出力先の優先順位は--debug-file > CLAUDE_CODE_DEBUG_LOGS_DIR > 既定パスの順になります。ログの詳細度はCLAUDE_CODE_DEBUG_LOG_LEVELで、記録開始のタイミングは--debug起動か/debug実行かで変わります。MCPやHooksの不具合を追うときは、まずカテゴリを絞った--debugで当たりを付け、再現条件が固まったら--debug-fileで証跡を残す、という流れが扱いやすい組み合わせです。設定ファイルが読み込まれているか自体を疑うなら/doctor、読み込まれたあとの実際の挙動を疑うなら--debug系のログ、と入口を分けておくと調査が早く進みます。

この記事を共有:XはてブLinkedIn