Article

2026-07-02-襷の系譜-日志与缓存指标第一版

个人项目

2026-07-02 襷の系譜 日志与缓存指标第一版

一、结论

这个事情不需要先出一份很重的方案。

更适合当前阶段的做法是:

  • 先写一份一页纸级别的实现边界
  • 直接进入第一版开发
  • 先解决“线上出问题时能看懂、能回放、能定位”的问题

当前不建议一开始就引入完整可观测平台,也不建议把日志、指标、告警、链路追踪一次做满。

二、第一版目标

第一版只解决四件事:

  • Web 应用和脚本有统一日志入口
  • 日志可以保留最近 3 天
  • 线上报错时可以从日志快速定位问题
  • 可以看到服务端缓存的命中情况

第一版不是为了做企业级 observability,而是为了支撑当前的线上排障和 bug 修复协作。

三、第一版范围

3.1 要做的内容

  • 统一 logger,替代分散的 console.log / console.error
  • 输出结构化日志,格式优先采用 JSON
  • 为 Web 请求记录基础上下文
  • 为脚本任务记录任务名、run id、处理结果摘要
  • 为未捕获异常和 Promise rejection 记录错误日志
  • 为服务端缓存记录 hit / miss / set / stale
  • 日志保留 3 天

3.2 暂时不做的内容

  • Sentry
  • Datadog
  • OpenTelemetry
  • Prometheus + Grafana
  • 分布式 tracing
  • 告警平台联动
  • 复杂仪表盘

四、日志设计

4.1 基本原则

  • 应用代码不再直接零散打印日志
  • Web 和脚本使用同一套 logger 封装
  • 日志默认机器可读,方便后续筛选和聚合

4.2 每条日志至少包含

  • timestamp
  • level
  • message
  • module
  • env

错误日志额外包含:

  • error_name
  • error_message
  • stack

4.3 Web 场景建议附带

  • path
  • locale
  • slug
  • duration_ms
  • cache_namespace

4.4 脚本场景建议附带

  • script
  • run_id
  • job
  • target
  • processed_count
  • success_count
  • failed_count

4.5 建议日志级别

  • debug
  • info
  • warn
  • error

其中:

  • 本地开发默认可看 debug
  • 线上默认以 info 及以上为主

五、请求日志建议

第一版不必上复杂中间件体系,但建议 Web 请求至少记录一进一出两类信息。

5.1 请求开始

建议记录:

  • 请求方法
  • 路径
  • 查询参数摘要
  • request id

5.2 请求结束

建议记录:

  • 请求方法
  • 路径
  • status code
  • duration
  • 是否命中缓存

如果是渲染型页面,还可以补:

  • page_type
  • entity_type
  • entity_slug

六、错误日志建议

6.1 必须统一错误入口

第一版至少要覆盖:

  • API handler 抛错
  • 服务端组件或 server action 抛错
  • 脚本顶层未捕获异常
  • Promise rejection

6.2 错误日志不能只打一行字符串

错误日志建议至少输出:

  • 错误类型
  • 错误消息
  • stack
  • 所在模块
  • 请求上下文或任务上下文

否则线上很容易出现“知道报错了,但不知道是哪里报的”。

七、缓存指标第一版

7.1 当前需要的不是完整 metrics 系统

第一版可以先把缓存行为作为结构化事件记录到日志里,而不是立刻建设完整监控系统。

也就是说,先做到:

  • 每次缓存 hit / miss / set / stale 都有日志
  • 通过日志检索可以快速判断某个缓存是否正常工作

7.2 缓存日志建议字段

  • cache_namespace
  • cache_key
  • cache_event
  • ttl_seconds
  • stale_at
  • regenerated

7.3 第一版关注的核心问题

通过这些日志,至少能回答:

  • 某页面慢,是不是因为缓存没命中
  • 某缓存是否一直 miss
  • 某缓存是否频繁重建
  • 某缓存的 stale 逻辑是否按预期工作

八、落地方式建议

8.1 统一 logger 封装

建议建立一个统一 logger 模块,例如:

  • lib/logger

由它统一暴露:

  • logger.debug
  • logger.info
  • logger.warn
  • logger.error

避免业务代码继续各自直接打日志。

8.2 缓存封装层统一埋点

如果当前已经有服务端缓存封装,优先在缓存封装层加入日志,而不是散落到业务页面里。

这样好处是:

  • 接入成本低
  • 不容易漏
  • 后续切换到真正 metrics 体系时也更平滑

8.3 脚本入口统一 run id

所有导入、同步、修复脚本建议在启动时生成:

  • run_id

后续整个脚本过程的日志都带同一个 run_id,方便回放一次任务执行过程。

九、日志存储建议

第一版不建议上远程平台,先走本机或服务器本地文件即可。

建议:

  • JSON 行日志
  • 按天滚动
  • 保留最近 3 天

如果当前运行在 Docker 环境,也可以先结合 stdout/stderr 收集,但仍建议日志格式结构化。

十、这版为什么够用

因为当前阶段真正缺的不是“高阶观测平台”,而是最基础的三种能力:

  • 能知道请求发生了什么
  • 能知道脚本做了什么
  • 能知道缓存到底有没有工作

只要这三件事能做到,很多现在线上排障成本就会明显下降。

十一、最终结论

第一版日志与缓存指标建设应采用“轻量先行”策略:

  1. 建统一 logger。
  2. 统一请求日志与错误日志。
  3. 在缓存封装层记录 hit/miss/set/stale
  4. 脚本统一带 run_id
  5. 日志本地保留 3 天即可。

这版不追求平台化,而是优先解决当前线上协作、排障、缓存验证的最低可用问题。