11.14 可观测性与日志
Tip
当代码在本地运行时,你能直接看终端报错;但当代码跑在云端 Serverless 时,你看不见终端,就像在一个没有窗户的房间里开飞机。可观测性 (Observability) 就是给你的飞机装上仪表盘(指标)、黑匣子(日志)和航线追踪器(链路追踪),让你在千米高空也能知道由于什么原因导致引擎熄火。
1. 为什么要学这个?
你正在开发一个电商下单功能。用户突然投诉说:"刚才下单失败了!" 你问:"报什么错?" 用户说:"没报错,就是点不动。"
你打开 Vercel 后台,面对每秒几千行的滚动日志,不仅找不到报错那一行,甚至连这个用户的请求都找不到(既定事实)。 你只能盲目猜测是数据库超时了?还是支付接口挂了?(痛苦迷茫)。 最终因为无法定位问题,导致由于一个隐藏 Bug 让这天的订单全部流失(必然恶果)。
掌握可观测性,就是给每个请求发一张"身份证",让你在报错的瞬间就能通过 ID 直接调出案发现场的所有监控录像。
2. 核心概念
我们要把"系统挂了"这个模糊的感觉,拆解成三个看得见的东西(三大支柱):
2.1 Logs (日志) —— "系统的日记本"
物理定义:它通常是一行行文本或 JSON 对象,记录了系统在某时某刻干了什么。
就像船长的航海日志。 "14:00 启航","15:00 遇到风暴","15:30 引擎故障"。 当出事时,你需要翻看日记才知道发生了什么。
2.2 Metrics (指标) —— "汽车仪表盘"
物理定义:它是一组随时间变化的数字(图表)。
就像你车上的时速表和油表。 你不需要知道每一脚油门喷了多少油(那是日志),你只需要知道"现在的车速是 120km/h"(高负载),或者"油箱虽然只剩 10%"(内存不足)。它是宏观的健康体检。
2.3 Tracing (链路追踪) —— "快递物流号"
物理定义:它是一个唯一的字符串 ID(Trace ID),在这个请求经过的所有服务中传递。
就像你查快递时用的运单号。
一个请求下单,可能经过了:前端 -> 网关 -> 订单服务 -> 库存服务 -> 数据库。
如果没有追踪号,你只知道"发货失败",但不知道是仓库没货了,还是快递员没来取件。有了 Trace ID,你能看到:
[网关 ✅] -> [订单服务 ✅] -> [库存服务 ❌ 超时]。
凶手直接现形。
3. 核心解决方案
3.1 告别 console.log,拥抱结构化日志
❌ 错误做法 (给人类看的):
console.log("用户登录失败", userId);
// 这是一个纯字符串。
// 机器即使读了,也不知道 userId 在哪,更没法按 userId 搜索。
✅ 正确做法 (给机器看的):
// 使用 JSON 格式 (Structured Logging)
console.log(JSON.stringify({
level: "error",
event: "login_failed",
userId: "user_123",
reason: "password_mismatch",
timestamp: new Date().toISOString()
}));
// 这是一个对象。日志系统可以索引 "event" 和 "userId" 字段。
// 你可以直接搜: `event="login_failed" AND userId="user_123"`
3.2 观测流程全景图
graph TD
App["Next.js App"] -->|"Step 1: 产生 JSON 日志"| Collector["日志收集器 (Log Collector)"]
Collector -->|"存储日志"| LogSystem["日志库 (Axiom)"]
Collector -->|"聚合指标"| Dashboard["仪表盘 (Grafana)"]
Collector -->|"标记链路"| TraceSystem["Sentry / Jaeger"]
LogSystem -->|"搜索 Error"| Developer["👨💻 开发者"]
Dashboard -->|"CPU > 90% 报警"| Developer
TraceSystem -->|"定位慢请求"| Developer
style Developer fill:#fff9c4,stroke:#fbc02d
style LogSystem fill:#e1f5fe,stroke:#0277bd
3.3 推荐工具:Axiom (Vercel 的最佳拍档)
Vercel 自带的日志虽然能看,但只能存很短时间。对于生产环境,我们需要专业的日志仓库。 Axiom 是一个专门处理 Serverless 海量日志的平台。它可以:
- 一键集成:在 Vercel 插件市场点一下,不用改代码,日志自动流转过去。
- 永久存储:哪怕 Vercel 的日志刷没了,Axiom 里还有。
- SQL 查询:像查数据库一样查日志。
4. 避坑指南
| ❌ 不要这样做 | ✅ 应该这样做 | 为什么 |
|---|---|---|
| 打印敏感信息 | 脱敏处理 | 把用户的密码、手机号打印到日志里,是严重的合规事故,日志系统通常也是黑客眼中的肥肉。 |
All in console.log |
区分日志级别 | 生产环境要过滤掉 debug 和 info,只保留 warn 和 error,否则你会像特斯拉一样被垃圾信息淹没。 |
| 100% 链路追踪 | 采样 (Sampling) | 记录每一个请求的完整链路会极度消耗性能。通常只随机采样 5% 的请求,或者只记录报错的请求。 |
5. 真实案例
Story
2019年,特斯拉因"日志写太猛"导致中控黑屏
2019年,大量特斯拉 Model S 和 Model X 车主发现原本好好的中控大屏突然黑屏死机,空调、导航全废。原因竟然是特斯拉的系统日志记录得太详细、太频繁了。这些海量的垃圾日志疯狂写入 eMMC (车机内存芯片),硬生生把芯片的读写寿命给"磨损"光了。物理硬件直接报废,特斯拉被迫召回数十万辆车,损失惨重。
Vibe 心法:日志不是免费的,它消耗存储、消耗带宽、甚至消耗硬件寿命。只记录有用的信息,生产环境严禁开启 Debug 级别的废话日志。
6. 本章小结
- 🔦 告别盲猜:不要靠直觉修 Bug,要靠证据(日志)。
- 🆔 身份证:给关键流程打上 Trace ID,串联请求的一生。
- 🧹 克制记录:以此为戒,不要把日志当成垃圾桶,只记以后查问题时真正用得上的数据。