可观测性
线上服务出问题时,唯一能依赖的就是它吐出来的信息。可观测性三支柱——日志(发生了什么)、指标(趋势与告警)、剖析(为什么慢)——在 Go 生态中均有标准或事实标准方案。
结构化日志:log/slog
Go 1.21 引入的标准库 log/slog 取代了 log 与各路第三方日志库,核心思想是日志即结构化数据:每条日志由消息 + 键值对属性构成,输出为 JSON,可直接被采集系统索引。
示例需 import "encoding/json"。输出的每条日志形如:
Tip
slog 使用要点:
- 请求路径中的日志用
InfoContext/ErrorContext,携带 ctx 以支持链路追踪字段透传。 - 分组与复用:
logger := slog.Default().With("service", "shortener"),公共字段只写一次。 - 敏感信息(密码、token、手机号全文)绝不入日志。
- 旧代码迁移:
slog.SetDefault后,log.Printf也会走 slog handler。 :::
请求日志中间件
把日志埋在中间件里,统一记录方法、路径、状态码与耗时:
指标:Prometheus
Prometheus 是指标监控的事实标准。Go 服务只需暴露 /metrics 端点:
在中间件中记录指标(与日志中间件同构):
:::warning
标签基数控制:path 标签应使用路由模板(如 /api/users/{id})而非原始路径,否则每个不同的 id 都会生成一个新时间序列,导致 Prometheus 内存暴涨。高频接口的四类黄金指标:延迟、流量、错误率、饱和度。
剖析:pprof
排查 CPU、内存、goroutine 泄漏问题,使用标准库 pprof:
链路追踪:OpenTelemetry
跨服务排障需要 trace id 串联。Go 生态标准是 OpenTelemetry(otel),核心用法:
Tip
otel 的 SDK 初始化(导出器、采样率、与采集器对接)依赖具体部署环境,篇幅较长。入门阶段记住两点即可:所有跨层调用传递 context.Context,日志中间件将 trace id 写入日志字段——有了这两条,接入 otel 只是配置问题。完整接入参考 opentelemetry-go 官方文档。
小结
log/slog+ JSON handler 是 Go 结构化日志的标准答案,请求日志收敛到中间件。- Prometheus 四类黄金指标 +
/metrics端点,标签基数必须可控。 - pprof 内网常开,是 CPU/内存/goroutine 问题的最终手段。
- ctx 全链路传递是未来接入追踪的前置条件,从第一天就坚持。