mcpField
D
debug-local

debug-local

github.com/lightdash开发6.2k371 次安装今天更新
代码仓库

关于 debug-local

面向 Lightdash 开发者的本地调试指南,要求先基于日志、追踪和复现确认根因,再修复并验证。指南汇集 PM2、Maple、浏览器和数据库的调查方法。

主要功能

  1. 01先收集证据并确认根因
  2. 02通过 Maple 查询追踪与错误
  3. 03按常见模式定位故障
  4. 04验证假设后编写回归测试
  5. 05检查修复并生成调试报告

适用场景

  1. 01调查 API 错误或响应缓慢
  2. 02排查权限、缓存或迁移问题
  3. 03定位前端显示和调度器故障
  4. 04确认修复有效并记录证据

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/debug-local确认已加载。

详细介绍

调试 Lightdash

铁律

未先调查根本原因,不得修复。

在获得证据(日志、跟踪记录、复现结果)支持的明确根因假设之前,不要编辑应用代码。修复表面症状会导致反复调试。


阶段 1:收集证据

形成任何假设之前,先收集事实。

1. 收集症状

阅读错误消息、堆栈跟踪和复现步骤。如果用户提供的上下文不足,只问一个澄清问题。

2. 检查近期变更
git log --oneline -20 -- <affected-files>

之前能正常工作吗?如果是回归问题,根本原因就在差异中。

3. 检查日志和跟踪记录
pnpm exec pm2 logs lightdash-api --lines 50 --nostream

然后查询 Maple(本地模式会从 API 和 scheduler 接收 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响应时间 >1s,数据库跟踪片段较多maple trace <id> 跟踪片段树——统计 db.* 跟踪片段,检查是否存在循环
Explore 缓存过期显示旧列/指标cached_explores 表、CompileService
迁移问题找不到列、架构不匹配packages/backend/src/database/migrations/,检查回滚
调度器任务失败任务未运行或卡住PM2 scheduler 日志、graphile_worker.jobs 表
前端数据过期变更后 UI 仍显示旧数据TanStack Query 缓存失效,检查 queryClient.invalidateQueries
竞态条件间歇性出现,依赖时序对共享状态的并发访问、缺少 await
跨服务文件问题在 worker/headless 中找不到文件必须通过 FileStorageClient 使用 S3,而非本地文件系统
配置漂移本地运行正常,但在 CI/staging 中失败环境变量、.env.development.local 与容器环境的差异
空值传播TypeError、无法读取属性可选值缺少保护、Knex .first() 返回 undefined

另请检查:

  • 使用 git log 查看同一区域之前的修复——同一文件反复出现的问题是架构层面的隐患
  • 确认问题出在 common、backend 还是 frontend——错误归因到其他层会浪费时间

阶段 3:检验假设

编写任何修复代码之前,先验证你的假设。

  1. **确认:**添加临时日志、断言,或使用 Maple/PM2 检查怀疑的根因。然后复现。证据是否吻合?

  2. **如果假设错误:**返回阶段 1。收集更多证据。不要猜测。

  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

将完整的 32 字符 ID 传给 maple trace,即可查看请求。

跟踪查询(Maple CLI)

Maple 本地模式会将跟踪、日志和指标存储在内嵌的 ClickHouse 中, 并通过 maple CLI 提供访问。每条命令都可使用 --since <30m|1h|24h|7d> 指定时间范围。输出为 JSON,可通过管道传给 jq 进行筛选。 --format table 仅适用于扁平行集(services、query);其他命令会说明这一点,并回退为 JSON 输出。

每个 Shell 中只需设置一次目标服务——CLI 默认使用 4318 端口,而每个工作树 都会在其对应的槽位端口上运行自己的服务:

export MAPLE_LOCAL_URL="http://127.0.0.1:${MAPLE_PORT:-4320}"
列出服务
maple services --format table

每个服务的吞吐量、错误率和 P95 延迟。API 报告为 $LD_INSTANCE_ID(默认为 lightdash),Worker 报告为 $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

返回完整的 Span 树,以及与该跟踪关联的日志。

搜索错误
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 未授权跟踪身份验证中间件,检查会话/JWT Span
403 禁止访问检查跟踪属性中的用户能力/权限,查看 CASL 能力
404 未找到确认路由存在,检查资源查找 Span
400 错误请求在验证错误或错误日志中查找问题
响应缓慢检查 Span 明细,找出缓慢的 db.* 或外部调用;统计 db Span 以排查 N+1 问题
结果为空验证查询参数,检查 db 查询 Span
500 服务器错误使用 search_errors 查找堆栈跟踪和上下文
UI 未更新检查 TanStack Query 开发者工具,确认变更后缓存已失效
Scheduler 未运行检查 pnpm pm2:logs:scheduler,查询 graphile_worker.jobs 表

快速命令参考

操作命令
查看所有日志pnpm pm2:logs
查看 API 日志(非阻塞)pnpm exec pm2 logs lightdash-api --lines 20 --nostream
检查进程状态pnpm pm2:status
重启 APIpnpm pm2:restart:api
最近的跟踪记录maple traces --since 5m
跟踪记录详情maple trace <full-trace-id>
最近的错误maple errors --since 5m
浏览器快照mcp__chrome-devtools__take_snapshot
打开 Maple 跟踪记录界面http://localhost:4320

跨 Agent 验证

使用另一个 AI Agent 验证你的发现、质疑你的结论,并提供独立证据。这不仅适用于你遇到困难时——在整个调试过程中都应主动寻求验证,确保分析可靠。

检测你的环境
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>"
何时咨询
  • 验证假设:在确定根本原因之前,询问另一个 Agent,现有证据是否支持你的理论,或是否存在其他解释
  • 核实你对数据的解读:阅读跟踪记录、日志或查询输出时,确认你对内容的理解是否正确
  • 质疑你的修复方案:建议修改代码之前,询问该修复是否真的解决了根本原因,还是只掩盖了症状
  • 交叉检查复杂逻辑:如果问题涉及多个系统(前端 + API + 数据库 + 权限),请另一个 Agent 独立分析它们之间的交互
  • 为结论提供依据:如果你准备告诉用户“X 是原因”,请先确认另一个视角也认同,或说明存在分歧
指南
  • 设置 5 分钟超时:Codex 可能需要一些时间才能响应。通过 Bash 工具运行 codex exec 时,将 Bash 超时设为 300000ms(5 分钟),以免过早终止。不要向 codex exec 本身传递 --timeout——它不支持该标志。
  • 具体说明:提供实际错误、跟踪输出或代码片段,不要只给出模糊描述
  • 请求验证,而不只是答案:“这些证据是否支持我关于 X 的结论?”比“哪里出了问题?”更好
  • 说明你当前的假设:让另一个 Agent 确认或质疑你的假设,而不是从头开始分析
  • 说明你已经排除的情况:避免重复调查,让咨询聚焦于尚未解决的问题
  • 务必向用户反馈:咨询另一个 Agent 后,要告知用户。总结你提出的问题、另一个 Agent 的发现,以及你是否认同其判断。如果存在分歧,呈现双方观点及各自支持证据。绝不能让用户不知道你曾咨询另一个 Agent。

测试用户凭据

用于测试需要身份验证的流程:

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]),且永不过期。

评论

支持 Markdown