用 OpenTelemetry Collector tail_sampling 只保留错误或慢请求的 trace

举报
yd_250998817 发表于 2026/10/27 01:01:55 2026/10/27
【摘要】 介绍如何配置 OpenTelemetry Collector 的 tail_sampling,基于 status_code 与 latency 策略仅保留错误或慢请求的 trace,并通过 decision_wait 等待完整 trace 后决策,降低追踪后端存储成本。

用 OpenTelemetry Collector tail_sampling 只保留错误或慢请求的 trace

问题场景

在微服务架构中,OpenTelemetry 可以采集完整的调用链。全量上报 trace 会给追踪后端带来巨大的存储和索引压力。实际上,大部分正常且快速的请求在排查问题时价值有限,真正需要长期保留的是错误请求和慢请求。如果能在 Collector 侧完成筛选,只把错误或慢请求的 trace 发给后端,就能显著降低存储成本。

OpenTelemetry Collector 的 tail_sampling processor 支持在收到完整 trace 后再做采样决策,因此可以基于 trace 的最终状态(例如是否包含错误、总耗时是否超阈值)决定保留或丢弃。

配置思路

tail_sampling 的核心是“先缓存、后决策”。Collector 会等待一段时间(decision_wait),让同一 trace 的 span 尽量到齐,然后按策略判断。对于“只保留错误或慢请求”的需求,可以配置两个策略:

  • status_code 策略:只要 trace 中任一 span 的状态码为 ERROR,就保留。
  • latency 策略:只要 trace 的总耗时超过阈值(例如 500ms),就保留。

多个策略之间是“或”的关系,任一命中即保留。没有命中任何策略的 trace 会被丢弃,从而实现只保留错误或慢请求。

最小可运行示例

下面是一个 Collector 配置示例,用于接收 OTLP 数据,开启 tail_sampling,并将采样后的 trace 输出到日志(便于本地验证)。实际使用时,把 exporter 换成后端地址即可。

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  tail_sampling:
    # 等待 trace 完整的时间,需大于业务最长链路耗时
    decision_wait: 30s
    # 缓存 trace 数量,根据流量调整
    num_traces: 50000
    # 预期每秒新 trace 数,帮助分配缓存
    expected_new_traces_per_sec: 100
    policies:
      - name: errors-policy
        type: status_code
        status_code:
          status_codes: [ERROR]
      - name: slow-policy
        type: latency
        latency:
          threshold_ms: 500

exporters:
  # 本地验证用 logging;生产环境替换为 OTLP 或 APM 后端
  logging:
    verbosity: detailed

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [tail_sampling]
      exporters: [logging]

说明:

  • decision_wait:默认 30s,表示 Collector 收到首个 span 后等待多久做决策。如果业务链路最长可能超过 30s,需要调大,否则慢请求可能在决策后才结束,导致漏采。
  • num_traces:缓存中最多保留的 trace 数。根据 QPS 和 decision_wait 估算,避免内存过高。
  • expected_new_traces_per_sec:预估每秒新 trace 数,有助于内部缓存分配,可按实际流量填写。
  • status_code 策略:status_codes 列出需要保留的状态码,这里保留 ERROR。
  • latency 策略:threshold_ms 为总耗时阈值,单位毫秒,示例为 500ms。

运行方法

可以使用官方 Collector contrib 镜像运行上面的配置。假设配置文件名为 config.yaml,放在当前目录:

docker run --rm \
  -p 4317:4317 \
  -p 4318:4318 \
  -v $(pwd)/config.yaml:/etc/otelcol/config.yaml \
  otel/opentelemetry-collector-contrib:<版本>

请将 <版本> 替换为实际使用的镜像标签,例如 0.100.0 或更高兼容版本。运行后,Collector 会监听 4317(gRPC)和 4318(HTTP)。

接下来让应用通过 OTLP 发送 trace。如果已有 OpenTelemetry SDK,将 OTLP exporter 指向 http://localhost:4318 或 localhost:4317 即可。也可以使用 telemetrygen 等测试工具生成模拟 trace:

telemetrygen traces --otlp-endpoint localhost:4317 --otlp-insecure --duration 10s

然后观察 Collector 日志,只有包含 ERROR 状态或耗时超过 500ms 的 trace 会被输出。正常且快速的 trace 不会出现在日志中。

边界与限制

  1. decision_wait 与慢请求的完整性 decision_wait 必须大于业务链路的最长耗时。如果某个慢请求的总耗时超过 decision_wait,Collector 可能在它结束前就做出丢弃决策。建议先统计 P99 或最大链路耗时,再设置一个留有余量的值。

  2. 内存占用 tail_sampling 需要把 trace 缓存在内存中。num_traces 和 decision_wait 越大,内存占用越高。高流量场景下应结合 expected_new_traces_per_sec 和实际内存监控逐步调整,避免 OOM。

  3. 多 Collector 实例的负载均衡 如果部署了多个 Collector 实例,同一个 trace 的 span 可能被发送到不同实例。每个实例只看到部分 span,可能无法正确判断错误或总耗时。此时需要保证同一 trace_id 始终路由到同一个 Collector,例如在 Collector 前使用按 trace_id 的负载均衡,或使用支持一致性哈希的网关。最简单的做法是单实例部署,或让应用侧只指向一个 Collector。

  4. 状态码依赖应用正确设置 status_code 策略依赖 span 的 status 字段。应用需要在捕获异常时显式将 span 状态设为 ERROR,否则错误请求可能不会被识别。

  5. 策略匹配与丢弃 多个策略是“或”关系。没有匹配任何策略的 trace 会被丢弃。这符合“只保留错误或慢请求”的目标,但也意味着正常请求的 trace 不会进入后端,排查非错误类问题时需要临时调整策略或开启兜底采样。

  6. 版本兼容性 OpenTelemetry Collector 的配置字段可能随版本变化。本文示例基于 tail_sampling processor 的通用配置,实际部署时请以所用版本的官方文档为准。

小结

通过 tail_sampling 的 status_code 和 latency 策略,可以在 Collector 侧只保留错误或慢请求的 trace,减少追踪后端存储成本。关键是合理设置 decision_wait,确保慢请求在决策前已经完整到达;同时注意内存限制、多实例路由和状态码上报质量。对于已经使用华为云 APM 或类似可观测后端的团队,可以将 exporter 指向对应 OTLP 接入点,让后端只接收高价值 trace。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。