主题
20 · 监控与可观测性
目标:前端不只会
console.log;能设计错误上报、性能埋点,并用 RequestId 把前后端日志串起来。
产出:一份可落地的「上线前可观测性检查清单」。
背景
用户说「刚才保存失败了」——没有 RequestId、没有 release 版本、没有面包屑,你只能猜。
Journal 的 client/src/utils/request.js 为每次请求生成 X-Request-Id,控制台打 🚀 / ✅ / ❌ [requestId],后端响应也带回 requestId——这是最小可用的可观测性,不是完整 APM。
概念:三支柱(前端视角)
| 支柱 | 问什么 | 前端常见手段 |
|---|---|---|
| Logs | 发生了什么、顺序如何 | 结构化 console、上报服务、与 RequestId 关联 |
| Metrics | 多快、多频繁、错误率 | Web Vitals、自定义计时、采样 |
| Traces | 一次操作跨哪些服务 | RequestId / traceparent 传递(全链路需网关配合) |
前端往往先做 错误 + 核心性能指标;全链路 Trace 是进阶,但 RequestId 是零成本起步。
RequestId 关联模型
text
用户点击保存
→ 前端生成 requestId = front_1739..._abc
→ Header: X-Request-Id: front_1739..._abc
→ 后端日志 [requestId] POST /notes 201
→ 响应 body.requestId 或 header 回传
→ 前端 toast / 错误页展示「错误码 + requestId」供客服查询1
2
3
4
5
6
2
3
4
5
6
原则:同一用户操作链上的重试、Token 刷新,要么继承同一 id,要么在日志里显式记录 parentRequestId——Journal 刷新 token 会单独打 refresh 的 id,排查时注意对照。
实践
1. 错误上报(最小字段)
上报 payload 建议包含:
message/stack(生产可脱敏)requestId(若有)url、userAgent、release(git sha 或 semver)breadcrumbs:最近 5~10 条用户操作(路由、点击、API 失败)
js
// 伪代码:全局捕获 + 上报
window.addEventListener('unhandledrejection', (e) => {
reportError({
type: 'unhandledrejection',
message: String(e.reason),
release: import.meta.env.VITE_APP_VERSION,
})
})1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
可选服务:Sentry、自建 /api/client-log、云厂商前端监控——选型看合规与成本;字段规范比选型更重要。
2. 性能指标(别只看 Lighthouse 总分)
| 指标 | 含义 | 何时采 |
|---|---|---|
| LCP | 最大内容绘制 | 首屏 |
| INP / FID | 交互响应 | 关键按钮 |
| CLS | 布局偏移 | 列表 / 图片加载 |
| 自定义 | API P95、长列表滚动 FPS | 业务瓶颈页 |
js
// 自定义:笔记列表首屏 API 耗时
const t0 = performance.now()
await fetchNotes()
reportMetric('notes_first_load_ms', performance.now() - t0)1
2
3
4
2
3
4
采样:生产 1%~10% 即可,避免拖慢弱网用户。
3. 与后端对齐
- 约定 header 名:
X-Request-Id(Journal 已用) - 错误响应体统一:
{ code, message, requestId }(client 的apiError.js已解析) - 管理后台、小程序共用同一套 id 生成规则文档
踩坑
- PII 进日志:把 JWT、手机号、笔记正文打进 Sentry——合规事故。
- 无限上报:循环
throw或 resize 监听未节流 → 账单爆炸。 - 只有前端没有 release:无法对应哪次部署引入的 bug。
- RequestId 只在 console:用户截图没有 id,客服仍无法查。
- 把监控当测试:监控发现已影响用户;测试应更早拦截。
验收清单
错误
- [ ] 全局
error/unhandledrejection有统一入口 - [ ] API 失败 toast 或错误页可展示
requestId(至少 dev / staging) - [ ] 上报含
release版本号
性能
- [ ] 至少 1 个业务自定义指标(如首屏列表加载)
- [ ] 知道 Web Vitals 三项各代表什么
关联
- [ ] 前端请求带
X-Request-Id - [ ] 能在后端日志用同一 id 搜到对应请求
- [ ] 文档写清:用户报障时要什么信息(时间、操作、requestId)
下一步
参考
- Web Vitals
- Sentry for JavaScript
- Journal:
client/src/utils/request.js、client/src/utils/apiError.js - OpenTelemetry(全链路进阶):https://opentelemetry.io/docs/
