OpenTelemetry 落地:统一 Trace、Metric 与日志上下文

OpenTelemetry 不是一个监控后端,而是一套生成、传播、采集和导出遥测数据的标准。它最大的价值是让应用不绑定某个厂商,并通过统一 Context 把 HTTP、gRPC、数据库、消息队列和日志串成一次完整请求。

从 Trace 开始,而不是一次接全

先选择一个跨服务关键链路,例如登录或文章发布。入口创建 Server Span,下游 HTTP/gRPC 自动传播 Context,数据库和消息队列增加 Client/Producer Span。每个 Span 只记录对排障有用的属性:

  • 服务名、版本和部署环境。
  • RPC 方法、HTTP 路由模板和状态码。
  • 数据库系统与操作类型,不记录完整敏感 SQL。
  • 消息系统、Destination 和消息 ID。
  • 业务稳定 ID,避免邮箱、手机号等个人信息。

不要把用户输入、Token 或整段响应放进 Attribute,遥测系统同样需要数据最小化。

Go 服务的基本接入

应用创建全局 TracerProvider,通过 OTLP 导出到 Collector,并在退出时 Flush:

resource := resource.NewWithAttributes(
    semconv.SchemaURL,
    semconv.ServiceName("wr-article"),
    attribute.String("deployment.environment", "production"),
)

provider := sdktrace.NewTracerProvider(
    sdktrace.WithResource(resource),
    sdktrace.WithBatcher(exporter),
)
otel.SetTracerProvider(provider)
defer provider.Shutdown(ctx)

实际包路径和 Semantic Convention 版本应按当前 OTel SDK 文档选择。优先使用维护良好的 HTTP、gRPC 和数据库 Instrumentation,手工 Span 只补充领域步骤。

Collector 作为稳定边界

应用统一发给本地或集群 Collector,再由 Collector 做批处理、重试、采样、脱敏和多后端导出。这样更换可观测平台不需要重发所有服务。

Collector 自身必须监控队列、丢弃、导出失败和内存。它不是无限缓冲,后端长时间不可用时必须有明确降级策略,不能反向拖垮业务进程。

采样策略

全量 Trace 成本高。Head Sampling 简单但可能丢掉低频错误;Tail Sampling 可以在看到完整 Trace 后保留错误和慢请求,但需要 Collector 缓存和更多资源。常见组合是:基础比例采样 + 错误全保留 + 慢请求高保留。

采样决定应沿调用链传播,避免上游不采样、下游却生成孤立 Span。

日志关联

日志中加入 trace_idspan_id 和请求 ID。用户从错误日志可以跳到 Trace,Trace 也能定位同一请求日志。不要把 Trace 的所有 Attribute 再复制进每条日志,避免体积和字段基数失控。

上线步骤

  1. 为服务定义统一 Resource 属性。
  2. 打通一条关键链路并验证 Context 跨进程传播。
  3. 检查敏感字段与高基数属性。
  4. 设置采样、批处理、超时和导出重试。
  5. 监控 SDK 与 Collector 自身开销。
  6. 用故障演练确认能从告警定位到具体调用。

参考资料