用户报错排查手册

当客户说"页面报错了",按这个流程 5 分钟内定位根因

整体排查流程

收集信息 查用户ID 搜日志 找traceId 查完整链路 定位代码 修复

Phase 0: 从用户处收集信息

跟用户确认以下三个信息(能拿到几个算几个):

信息示例用途
用户账号邮箱 / 手机号 / 用户名查 userId,锁定日志范围
大概时间"刚才" / "今天上午10点左右"缩小搜索的时间窗口
哪个页面 / 什么操作"预约页面点确认按钮" / "结账时"确认 API 路径,加速定位
如果用户截图了错误页面:注意看是否有 traceId 显示(错误响应 JSON 里会包含)。 如果有 traceId,直接跳到 Phase 3。

Phase 1: 查找用户 ID

1 通过账号信息查数据库

根据用户类型选择对应的表:

-- 客户(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';
注意:这些查询需要在对应租户的 schema 下执行。 如果知道租户,先 SET search_path TO tenant_spa001;

假设查出 userId = 42

Phase 2: 搜索用户日志

2 使用 CLI 排查工具(推荐)
# 最快方式:一键排查
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

脚本会自动做以下事情:

  1. 查询数据库中该用户的日志
  2. 同时 grep Winston 日志文件中匹配的 traceId
  3. 合并结果按时间排序,输出格式化的排查报告
  4. 高亮 error 级别日志和 5xx 状态码
3 手动 API 调用方式

如果脚本不可用,直接调 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 3: 通过 traceId 查完整请求链路

4 找到可疑的 traceId

从 Phase 2 的结果中找到 level=errorstatusCode=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"
}
5 用 traceId 拉取完整链路
# 通过脚本
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

这一步能看到同一个请求从进入到完成的所有记录,包括:

Phase 4: 定位代码位置

6 从日志信息定位源码

日志中的关键字段对应关系:

日志字段对应代码位置查找方法
path: POST /api/public/booking/confirmAPI 路由文件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"

Winston 日志文件位置

文件内容
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 帮你排查的标准话术

以后直接跟 Claude 说:

帮我查一下用户报错:
- 用户:xxx@email.com(或手机号 / userId)
- 时间:大概今天上午10点
- 页面:预约页面
- 租户:spa001

Claude 会按以下自动化流程执行:

  1. 运行 investigate-error.js 脚本搜索日志
  2. 从结果中找出 error 级别的条目和对应 traceId
  3. 用 traceId 查完整链路
  4. grep Winston 日志获取堆栈信息
  5. 根据堆栈定位源码文件和行号
  6. 读取相关代码,分析根因
  7. 提出修复建议或直接修复

Last updated: 2026-02-05 · Celoria Observability Playbook