当客户说"页面报错了",按这个流程 5 分钟内定位根因
跟用户确认以下三个信息(能拿到几个算几个):
| 信息 | 示例 | 用途 |
|---|---|---|
| 用户账号 | 邮箱 / 手机号 / 用户名 | 查 userId,锁定日志范围 |
| 大概时间 | "刚才" / "今天上午10点左右" | 缩小搜索的时间窗口 |
| 哪个页面 / 什么操作 | "预约页面点确认按钮" / "结账时" | 确认 API 路径,加速定位 |
根据用户类型选择对应的表:
-- 客户(Guest)—— 公共预约、礼品卡等场景
SELECT id, name, email, phone
FROM guests
WHERE email = 'customer@example.com'
OR phone = '1234567890';
-- 员工(Employee)—— 管理后台场景
SELECT id, name, email
FROM employees
WHERE email = 'employee@qqnails.com';
SET search_path TO tenant_spa001;
假设查出 userId = 42
# 最快方式:一键排查
node scripts/tools/investigate-error.js --user 42 --from "2026-02-05T10:00:00Z" --to "2026-02-05T11:00:00Z"
# 只看错误
node scripts/tools/investigate-error.js --user 42 --level error
# 如果有 traceId,直接查链路
node scripts/tools/investigate-error.js --trace 1738750000000-a3f2b1
脚本会自动做以下事情:
如果脚本不可用,直接调 API:
# 用户 + 时间范围
curl -s "http://localhost:3000/api/logs/search?userId=42&startTime=2026-02-05T10:00:00Z&endTime=2026-02-05T11:00:00Z" | jq .
# 用户的所有错误日志(默认最近50条)
curl -s "http://localhost:3000/api/logs/search?userId=42&level=error" | jq .
# 某个租户最近的错误
curl -s "http://localhost:3000/api/logs?tenantId=spa001&level=error&limit=20" | jq .
从 Phase 2 的结果中找到 level=error 或 statusCode=500 的日志条目,
记下它的 trace_id 字段值。
示例结果:
{
"timestamp": "2026-02-05T10:32:18Z",
"level": "error",
"message": "POST /api/public/booking/confirm 500 1205ms",
"trace_id": "1738750003000-b7c4d2", ← 就是这个
"user_id": "42",
"tenant_id": "spa001",
"page": "/zh/qqnails/booking/spa001/verify"
}
# 通过脚本
node scripts/tools/investigate-error.js --trace 1738750003000-b7c4d2
# 通过 API
curl -s "http://localhost:3000/api/logs/search?traceId=1738750003000-b7c4d2" | jq .
# 通过 grep Winston 日志文件(能看到完整堆栈)
grep "1738750003000-b7c4d2" backend/logs/application-*.log
这一步能看到同一个请求从进入到完成的所有记录,包括:
日志中的关键字段对应关系:
| 日志字段 | 对应代码位置 | 查找方法 |
|---|---|---|
path: POST /api/public/booking/confirm | API 路由文件 | grep -r "booking/confirm" backend/api/ |
page: /zh/.../booking/.../verify | 前端页面文件 | booking/[store]/verify/page.tsx |
| Winston 日志中的 stack trace | 报错的具体行号 | 直接看堆栈中的文件路径和行号 |
data 中的错误消息 | throw 语句位置 | grep -r "错误消息关键词" backend/ |
| 已知信息 | CLI 命令 |
|---|---|
| 用户账号 + 大概时间 | node scripts/tools/investigate-error.js --user 42 --from "..." --to "..." |
| 只有用户账号 | node scripts/tools/investigate-error.js --user 42 --level error |
| 用户截图中有 traceId | node scripts/tools/investigate-error.js --trace 1738750000000-a3f2b1 |
| 只知道某租户最近出问题 | node scripts/tools/investigate-error.js --tenant spa001 --level error |
| 只知道页面路径 | curl "http://localhost:3000/api/logs?search=booking/confirm&level=error&limit=20" |
| 文件 | 内容 |
|---|---|
backend/logs/application-*.log | 所有应用日志(含 traceId) |
backend/logs/error-*.log | 仅错误日志(含完整堆栈) |
backend/logs/exceptions.log | 未捕获异常 |
backend/logs/rejections.log | 未处理的 Promise 拒绝 |
# 按 traceId 查 Winston 日志
grep "1738750003000-b7c4d2" backend/logs/application-*.log
# 查最近的 500 错误
grep '"statusCode":500' backend/logs/application-*.log | tail -20
# 查最近的错误级别日志
grep '"level":"error"' backend/logs/error-*.log | tail -20
以后直接跟 Claude 说:
帮我查一下用户报错:
- 用户:xxx@email.com(或手机号 / userId)
- 时间:大概今天上午10点
- 页面:预约页面
- 租户:spa001
Claude 会按以下自动化流程执行:
investigate-error.js 脚本搜索日志Last updated: 2026-02-05 · Celoria Observability Playbook