mcpField
D
debug-local

debug-local

github.com/lightdash開発6.2k371 回インストール今日更新
リポジトリ

debug-local について

Lightdash開発者向けのローカルデバッグガイドです。修正前にログ、トレース、再現による根拠で原因を確認し、PM2、Maple、ブラウザツール、データベースを使った調査手順をまとめています。

主な機能

  1. 01証拠を集めて根本原因を確認
  2. 02Mapleでトレースとエラーを検索
  3. 03既知のパターンに沿って調査
  4. 04仮説を検証して回帰テストを作成
  5. 05修正を確認してデバッグ報告を作成

活用シーン

  1. 01APIエラーや応答遅延を調査
  2. 02権限、キャッシュ、移行の問題を診断
  3. 03フロントエンドやスケジューラーの障害を調査
  4. 04修正を検証し根拠を記録

MCP 対応

ブラウザー自動化にはChrome DevTools MCPツールを使用します。ページ移動、スナップショット、操作、スクリーンショット、ネットワーク調査に対応します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lightdash/lightdash --skill debug-local

インストール後、Claude Code で/debug-localを入力して読み込まれたか確認します。

詳細

Lightdash のデバッグ

鉄則

根本原因を調査する前に、修正してはいけません。

証拠(ログ、トレース、再現)に裏付けられた根本原因の仮説を確認するまで、アプリケーションコードを編集しないでください。症状だけを修正すると、いたちごっこのようなデバッグになります。


フェーズ 1:証拠を集める

仮説を立てる前に、事実を集めてください。

1. 症状を収集する

エラーメッセージ、スタックトレース、再現手順を確認してください。ユーザーから十分なコンテキストが提供されていない場合は、確認の質問を 1 つだけしてください。

2. 最近の変更を確認する
git log --oneline -20 -- <affected-files>

以前は動作していましたか?リグレッションであれば、根本原因は差分にあります。

3. ログとトレースを確認する
pnpm exec pm2 logs lightdash-api --lines 50 --nostream

次に Maple を照会します(ローカルモードでは、API とスケジューラーからの OTLP トレースを取り込みます)。

maple services --format table       # per-service throughput and error rate
maple errors --since 5m             # errors grouped by fingerprint
maple traces --since 5m --errors    # recent traces containing errors
maple trace <trace-id>              # full span tree + correlated logs
maple slow-traces --since 15m       # slowest traces

CLI のデフォルトポートは 4318 なので、まずこのインスタンスを指定します。 export MAPLE_LOCAL_URL="http://127.0.0.1:${MAPLE_PORT:-4320}"。すべてのフィルターについては トレース検索を参照してください。

4. 再現する

バグを確実に再現できますか?ブラウザー自動化または curl を使って再現してください。再現できない場合は、先に進む前に証拠をさらに集めてください。

5. コードを読む

症状から潜在的な原因まで、コードの実行経路をたどってください。Grep で関連箇所をすべて検索し、Read でロジックを理解してください。

出力: 根本原因の仮説を述べてください。何が、なぜ問題なのかを具体的かつ検証可能な主張として示します。


フェーズ 2:パターン照合

バグが Lightdash の既知のパターンに当てはまるか確認してください。

パターン兆候調査箇所
権限エラー403 ForbiddenprojectMemberAbility.ts、organizationMemberAbility.ts の CASL アビリティ
クエリの遅延/N+1応答が 1 秒超、DB スパンが多数maple trace <id> のスパンツリー — db.* スパンを数え、ループを確認
古い Explore キャッシュ古い列/メトリクスが表示されるcached_explores テーブル、CompileService
マイグレーションの問題列が見つからない、スキーマが一致しないpackages/backend/src/database/migrations/、ロールバックを確認
スケジューラージョブの失敗ジョブが実行されない、停止しているPM2 スケジューラーログ、graphile_worker.jobs テーブル
フロントエンドの古いデータミューテーション後も UI に古いデータが表示されるTanStack Query のキャッシュ無効化、queryClient.invalidateQueries を確認
競合状態発生が断続的、タイミングに依存する共有状態への同時アクセス、await の不足
サービス間のファイルの問題ワーカー/ヘッドレスでファイルが見つからないローカルファイルシステムではなく、FileStorageClient を介して S3 を使用する必要がある
設定の不整合ローカルでは動作するが、CI/ステージングでは失敗する環境変数、.env.development.local とコンテナー環境変数の違い
null の伝播TypeError、プロパティを読み取れないオプション値に対するガードの不足、Knex の .first() が undefined を返す

以下も確認してください:

  • 同じ領域で過去に修正があったか git log で確認します。同じファイルでバグが繰り返し発生するのは、アーキテクチャ上の問題の兆候です。
  • 問題が common、backend、frontend のどの層にあるかを確認します。層を誤って特定すると時間を浪費します。

フェーズ 3:仮説を検証する

修正を 1 つでも書く前に、仮説を検証してください。

  1. 確認: 一時的なログやアサーションを追加するか、Maple/PM2 を使って疑わしい根本原因を確認します。再現させ、証拠が一致するか確認してください。

  2. 誤りの場合: フェーズ 1 に戻ってください。証拠をさらに集めます。推測してはいけません。

  3. 3 回までのルール: 3 つの仮説が失敗したら、停止してください。ユーザーに次の選択肢を尋ねます:

    • 新しい仮説で続ける(内容を説明する)
    • 人によるレビューにエスカレーションする
    • インストルメンテーションを追加し、次回発生時に捕捉できるよう待つ

フェーズ 4:修正する

根本原因を確認したら、次の手順に進みます。

  1. 症状ではなく、根本原因を修正します。 実際の問題を解消する、最小限の変更にしてください。

  2. 差分を最小限にします。 変更するファイル数と行数を最小限にしてください。隣接するコードをリファクタリングしてはいけません。

  3. 修正がなければ失敗し、修正があれば成功するリグレッションテストを作成してください。

  4. 関連するテストスイートを実行してください。出力を貼り付けます。

  5. 影響範囲を確認: 修正が 5 ファイルを超えて変更する場合は、一時停止し、続行する前にユーザーに確認してください。


フェーズ 5:検証と報告

元のバグのシナリオを再現し、修正されたことを確認してください。 これは必須です。

構造化されたデバッグレポートを出力してください。

DEBUG REPORT
════════════════════════════════════════
Symptom:         [what the user observed]
Root cause:      [what was actually wrong]
Fix:             [what was changed, with file:line references]
Evidence:        [test output, trace showing fix works]
Regression test: [file:line of the new test]
Status:          DONE | DONE_WITH_CONCERNS | BLOCKED
════════════════════════════════════════

ステータスの定義:

  • DONE — 根本原因を特定し、修正を適用し、回帰テストを作成して、テストに合格した
  • DONE_WITH_CONCERNS — 修正済みですが、完全には検証できない(例:断続的に発生するバグ、ステージング環境での確認が必要)
  • BLOCKED — 調査後も根本原因が不明で、ユーザーにエスカレーションした

前提条件

開発環境が実行中であることを確認してください。

/docker-dev              # Start Docker services (postgres, minio, etc.)
pnpm pm2:start           # Start all PM2 processes including Maple
pnpm pm2:status          # Verify all processes are online

サービス:

ツールのリファレンス

サーバーログ(PM2)
pnpm pm2:logs              # Stream all logs (Ctrl+C to exit)
pnpm pm2:logs:api          # API server logs only
pnpm pm2:logs:scheduler    # Background job scheduler logs
pnpm pm2:logs:frontend     # Vite dev server logs
pnpm pm2:logs:maple        # Maple tracing server logs

ブロッキングなしでログを表示する場合(最後の N 行):

pnpm exec pm2 logs lightdash-api --lines 20 --nostream
ログ形式

Lightdash のログには、関連付け用の 32 文字のトレース ID が含まれています。

[700aa55e784a437aa97de9b8c5c3ed3a] GET /api/v1/health 200 - 37 ms
[4d40816e5a7d433e88f99008de5f4be5] GET /api/v1/user/login-options 200 - 2 ms

maple trace に 32 文字の ID 全体を渡すと、リクエストを表示できます。

トレースの検索(Maple CLI)

Maple のローカルモードでは、埋め込み ClickHouse にトレース、ログ、メトリクスが保存され、maple CLI を通じて公開されます。各コマンドでは、対象期間として --since <30m|1h|24h|7d> を指定します。出力は JSON 形式です。対象を絞るには jq をパイプでつなぎます。 --format table は、フラットな行セット(services、query)にのみ適用されます。他のコマンドではその旨が示され、JSON にフォールバックします。

シェルごとに対象を一度設定してください。CLI のデフォルトはポート 4318 で、各ワークツリーはそれぞれのスロットポートで独自のサーバーを実行します。

export MAPLE_LOCAL_URL="http://127.0.0.1:${MAPLE_PORT:-4320}"
サービス一覧の表示
maple services --format table

サービスごとのスループット、エラー率、P95 レイテンシ。API は $LD_INSTANCE_ID(デフォルトは lightdash)として、ワーカーは $LD_INSTANCE_ID-scheduler として報告されます。

最近のトレース一覧の表示
maple traces --since 5m | jq '.traces[] | {traceId, spanName, durationMs}'
maple traces --since 1h --errors --min-duration-ms 500
maple slow-traces --since 15m

フィルター:--span-name <substr>、--http-method、--errors、--min-duration-ms、--max-duration-ms、--service、--limit。

トレースの詳細を取得
maple trace 700aa55e784a437aa97de9b8c5c3ed3a

トレースに関連付けられたログと、完全なスパンツリーを返します。

エラーを検索
maple errors --since 30m        # grouped by fingerprint
maple error <fingerprint-hash>  # sample traces + timeseries
ログを検索
maple logs --since 5m --severity ERROR
maple logs --trace-id 700aa55e784a437aa97de9b8c5c3ed3a
maple logs -q "compile" --since 1h
生 SQL による確認
maple query "SELECT ServiceName, count() FROM traces GROUP BY ServiceName"
ブラウザーのデバッグ(Chrome DevTools MCP)

ブラウザーの自動化には、Chrome DevTools MCP ツールを使用します。

ページを開く
mcp__chrome-devtools__new_page with url: "http://localhost:3000/login"
mcp__chrome-devtools__navigate_page with url: "http://localhost:3000", type: "url"
スナップショットを取得
mcp__chrome-devtools__take_snapshot

各要素に一意の uid 識別子が付いた、アクセシビリティツリーに基づくページのテキストスナップショットを返します。

要素を操作
mcp__chrome-devtools__click with uid: "1_5"
mcp__chrome-devtools__fill with uid: "1_4", value: "[email protected]"
mcp__chrome-devtools__hover with uid: "1_3"
スクリーンショット
mcp__chrome-devtools__take_screenshot
mcp__chrome-devtools__take_screenshot with fullPage: true
mcp__chrome-devtools__take_screenshot with filePath: "/tmp/debug.png"
コンソールとネットワーク
mcp__chrome-devtools__list_console_messages
mcp__chrome-devtools__list_network_requests
mcp__chrome-devtools__get_network_request with reqid: 123
ページ管理
mcp__chrome-devtools__list_pages
mcp__chrome-devtools__select_page with pageId: 1
mcp__chrome-devtools__close_page with pageId: 2
データベースの調査
# Check table schema
psql -c "\d <table_name>"

# Query data directly
psql -c "SELECT * FROM <table> WHERE <condition> LIMIT 5;"

# Check scheduler jobs
psql -c "SELECT id, task_identifier, attempts, last_error FROM graphile_worker.jobs WHERE last_error IS NOT NULL LIMIT 10;"

トレース属性(ワイドイベント)

トレースには、タイミング以外のコンテキスト属性も含まれます。

属性例説明
http.route/api/v1/projects/:projectUuidルートパターン
http.status_code200レスポンスステータス
http.methodGETHTTP メソッド
sentry.opdb、http.server操作の種類
db.systempostgresqlデータベースの種類

よくあるデバッグシナリオ

症状確認事項
401 Unauthorizedトレースの認証ミドルウェアを確認し、セッション/JWT のスパンを確認します
403 Forbiddenトレース属性でユーザーの権限を確認し、CASL の権限を確認します
404 Not Foundルートが存在することを確認し、リソース検索のスパンを確認します
400 Bad Request検証エラーがないか、トレース/エラーログを確認します
応答が遅い遅い db.* や外部呼び出しがないかスパンの内訳を確認し、N+1 がないか db スパンの数を確認します
結果が空クエリパラメーターを確認し、db クエリのスパンを確認します
500 Server Errorsearch_errors を使用してスタックトレースとコンテキストを確認します
UI が更新されないTanStack Query の開発ツールを確認し、ミューテーション後にキャッシュが無効化されていることを確認します
スケジューラーが実行されていないpnpm pm2:logs:scheduler を確認し、graphile_worker.jobs テーブルをクエリします

クイックコマンドリファレンス

操作コマンド
すべてのログを表示pnpm pm2:logs
API ログを表示(ブロックなし)pnpm exec pm2 logs lightdash-api --lines 20 --nostream
プロセスの状態を確認pnpm pm2:status
API を再起動pnpm pm2:restart:api
最近のトレースmaple traces --since 5m
トレースの詳細maple trace <full-trace-id>
最近のエラーmaple errors --since 5m
ブラウザーのスナップショットmcp__chrome-devtools__take_snapshot
Maple トレース UI を開くhttp://localhost:4320

エージェント間の検証

別の AI エージェントを使って調査結果を検証し、結論に異議を唱え、独立した証拠を得てください。これは行き詰まったときだけに行うものではありません。分析が確かなものになるよう、デバッグの過程で積極的に検証を求めてください。

環境を検出する
which claude 2>/dev/null && echo "HAS_CLAUDE=true" || echo "HAS_CLAUDE=false"
which codex 2>/dev/null && echo "HAS_CODEX=true" || echo "HAS_CODEX=false"
Claude の場合 → Codex に尋ねる
codex exec "Given this context from a Lightdash debugging session:

<context>
[paste relevant logs, traces, error messages, or code snippets]
</context>

<question>
[your specific question — e.g., 'Does this trace confirm that the query cache is being bypassed?' or 'Given this stack trace, is my conclusion that the middleware short-circuits before auth correct?']
</question>"
Codex の場合 → Claude に尋ねる
claude -p "Given this context from a Lightdash debugging session:

<context>
[paste relevant logs, traces, error messages, or code snippets]
</context>

<question>
[your specific question]
</question>"
相談するタイミング
  • 仮説を検証する:根本原因を結論づける前に、証拠が自分の説を裏付けているか、別の説明がないかを他方のエージェントに尋ねます
  • データの解釈を確認する:トレース、ログ、クエリの出力を読む際に、正しく読み取れているかを確認します
  • 修正案に異議を唱えてもらう:コード変更を提案する前に、その修正が根本原因に対処しているのか、それとも症状を隠しているだけなのかを尋ねます
  • 複雑なロジックを相互確認する:問題が複数のシステム(フロントエンド + API + データベース + 権限)に関わる場合は、連携について独立した見解を得ます
  • 結論を裏付ける:ユーザーに「X が原因です」と伝える前に、別の視点からも同意が得られるか確認します。同意が得られない場合は、その相違を明らかにします
ガイドライン
  • タイムアウトを 5 分に設定する:Codex の応答には時間がかかることがあります。Bash ツール経由で codex exec を実行する場合は、早期終了を避けるため、Bash のタイムアウトを 300000ms(5 分)に設定してください。codex exec 自体に --timeout を渡してはいけません。このフラグには対応していません。
  • 具体的に伝える:曖昧な説明だけでなく、実際のエラー、トレース出力、コードスニペットを含めます
  • 単に回答を求めるのではなく、検証を依頼する:「この証拠は、X という結論を裏付けていますか?」のほうが、「何が問題ですか?」より適切です
  • 現在の仮説を伝える:最初から調査をやり直すのではなく、他方のエージェントが仮説を確認したり、異議を唱えたりできるようにします
  • すでに否定した可能性も伝える:調査の重複を避け、相談に集中できるようにします
  • 必ずユーザーに報告する:別のエージェントに相談した場合は、そのことをユーザーに伝えます。何を尋ね、相手が何を見つけ、自分がその評価に同意するかを要約します。意見が異なる場合は、それぞれの見解と根拠となる証拠を示します。別のエージェントに相談したことをユーザーが知らないままにしてはいけません。

テストユーザーの認証情報

認証が必要なフローをテストする場合:

API アクセス(パーソナルアクセストークン)

API 呼び出しでは、Chrome DevTools MCP 経由で fetch() を使うより、この方法を優先してください。 PAT を使った curl はより高速で信頼性が高く、ブラウザーセッションやページコンテキストも必要ありません。ブラウザー MCP ツールは、UI 操作と視覚的なデバッグにのみ使用してください。

シードデータによって開発用 PAT が自動的に用意されます。ブラウザーログインなしで直接 API を呼び出す場合に使用してください。

# Source the env file to get LDPAT and LIGHTDASH_API_URL
source .env.development.local

# Example: list projects
curl -s -H "Authorization: ApiKey $LDPAT" "$LIGHTDASH_API_URL/api/v1/org/projects" | jq

# Example: get user info
curl -s -H "Authorization: ApiKey $LDPAT" "$LIGHTDASH_API_URL/api/v1/user" | jq

トークン(ldpat_deadbeefdeadbeefdeadbeefdeadbeef)は @lightdash/common の SEED_PAT で定義され、データベースのシード時に挿入されます。これは管理者ユーザー([email protected])に属し、有効期限はありません。

コメント