Grafana Tempo 内嵌 OTel Collector 组件:exporterhelper 内部遥测指标与 Feature Gate 完全指南
2026/9/20 4:40:58 网站建设 项目流程

Grafana Tempo 内嵌 OTel Collector 组件:exporterhelper 内部遥测指标与 Feature Gate 完全指南

【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo

本文以 Grafana Tempo 仓库内 vendored 的go.opentelemetry.io/collector/exporter/exporterhelper模块为对象,系统梳理其内部遥测(Internal Telemetry)的全部 17 个指标与 1 个 Feature Gate。Tempo 以库的形式内嵌 OpenTelemetry Collector 生态组件(见 go.mod 中exporter/exporterhelper v0.153.0exporter/otlpexporter v0.153.0直接依赖,以及 modules/distributor/receiver/shim.go 中通过otelcol构建 Collector 配置启动 receiver 的实现),因此 exporterhelper 的遥测语义直接适用于 Tempo 及任何集成 OTel Collector exporter 的系统。读完本文,你将掌握每个指标的含义、数据类型、稳定级别、采集实现原理,以及发送队列、重试、超时等配置与指标之间的联动关系。

exporterhelper 是什么:一类被所有 exporter 复用的基础设施

exporterhelper是 OpenTelemetry Collector 中为所有 exporter 提供通用能力的辅助包。正如其在 README.md 中所述,该包为 exporter 提供可复用的实现,当前包括**排队(queuing)、批处理(batching)、超时(timeouts)与重试(retries)**四类能力。

在 Grafana Tempo 中,Collector 生态并非以独立进程方式运行,而是被直接以 Go 库的形式编译进二进制。例如 modules/distributor/receiver/shim.go 在创建 OTLP 等 receiver 时,构造了一份包含receiversexporters(此处使用nopexporter 以避免报错)与service.pipelines的 Collector 配置,再通过otelcol.NewConfigProvider解析并启动。这意味着:

  • Tempo 的 trace 接收端就是 Collector 生态的 receiver/exporter 组件;
  • 任何被启用的 exporter(如 OTLP exporter)在发送数据时,其排队、批处理、超时、重试行为都由exporterhelper统一驱动;
  • 与之配套的内部遥测指标,全部由exporterhelper的观测层(obsReportSender)发出,命名统一以otelcol_exporter_为前缀。

内部遥测指标全景:17 个指标的分类视图

documentation.md定义的所有指标均由mdatagen从 metadata.yaml 自动生成,可在 internal/metadata/generated_telemetry.go 中看到对应的TelemetryBuilder字段声明。按功能可划分为六组:

分组指标度量类型语义
入队失败otelcol_exporter_enqueue_failed_{log_records,metric_points,profile_samples,spans}Sum未能进入发送队列而被丢弃的数据量
在途请求otelcol_exporter_in_flight_requestsSum(UpDown)当前正在导出(含重试退避)的请求数
批量发送otelcol_exporter_queue_batch_send_sizeotelcol_exporter_queue_batch_send_size_bytesHistogram每次发出的批次规模(单位数 / 字节数)
队列状态otelcol_exporter_queue_capacityotelcol_exporter_queue_sizeGauge重试队列的固定容量与当前积压
发送失败otelcol_exporter_send_failed_{log_records,metric_points,profile_samples,spans}Sum发往目标端失败的记录数
发送成功otelcol_exporter_sent_{log_records,metric_points,profile_samples,spans}Sum成功送达目标端的记录数

四类信号(traces / metrics / logs / profiles)各自的计数指标共享同一套模板,仅 unit 与稳定性等级不同。下面逐组详解,完整继承原始定义。

入队失败类:enqueue_failed_*

数据在进入发送队列之前就被拒绝时(例如队列已满、持久化队列底层存储不可写),不会进入 exporter 的重试逻辑,而是直接丢弃,并由这组指标统计。Tempo 场景下,这类指标是判断入口流量是否被背压丢数据的第一信号。

otelcol_exporter_enqueue_failed_log_records:未能加入发送队列的日志记录数。

UnitMetric TypeValue TypeMonotonicStability
{record}SumInttrueAlpha

otelcol_exporter_enqueue_failed_metric_points:未能加入发送队列的指标数据点数。

UnitMetric TypeValue TypeMonotonicStability
{datapoint}SumInttrueAlpha

otelcol_exporter_enqueue_failed_profile_samples:未能加入发送队列的 profile 样本数(该指标仍处于 Development 阶段)。

UnitMetric TypeValue TypeMonotonicStability
{sample}SumInttrueDevelopment

otelcol_exporter_enqueue_failed_spans:未能加入发送队列的 span 数。

UnitMetric TypeValue TypeMonotonicStability
{span}SumInttrueAlpha

在途请求:otelcol_exporter_in_flight_requests

当前处于“在途”状态的导出请求数,包括重试退避期间等待中的请求。它是 UpDownCounter(Monotonic 为 false),会随请求开始与结束上下波动。该指标用于评估 exporter 的并发压力:数值长期接近上限,说明目标端处理不过来。

UnitMetric TypeValue TypeMonotonicStability
{request}SumIntfalseDevelopment

批量发送直方图:queue_batch_send_size 与 _bytes

otelcol_exporter_queue_batch_send_size统计每次实际发出的批次包含的单位数(span / 指标点 / 日志记录数),可用于验证批处理配置(min_sizemax_size)是否生效。

UnitMetric TypeValue TypeStability
{unit}HistogramIntDevelopment

otelcol_exporter_queue_batch_send_size_bytes统计发出的批次序列化后的字节数,仅在 detailed 级别的遥测下可用。两个直方图的 bucket 边界定义在 metadata.yaml 中,前者覆盖 10 到 100000,后者覆盖 10 到 6000。

UnitMetric TypeValue TypeStability
ByHistogramIntDevelopment

队列状态:queue_capacity 与 queue_size

otelcol_exporter_queue_capacity:重试队列的固定容量,单位是批次(batch)。它由sending_queue.queue_size配置决定(默认 1000 批),是稳定的 Gauge。

UnitMetric TypeValue TypeStability
{batch}GaugeIntAlpha

otelcol_exporter_queue_size:重试队列当前积压的批次数量,同样是 Gauge。它反映了瞬时背压水平,queue_size / queue_capacity逼近 1 时意味着即将出现入队失败(即enqueue_failed_*开始增长)。

UnitMetric TypeValue TypeStability
{batch}GaugeIntAlpha

发送失败类:send_failed_*

记录发往目标端的失败尝试中涉及的数据量。在 detailed 遥测级别下,该组指标带有两个属性error.type(遵循语义约定)与error.permanent(标识错误是否永久性、不可重试)。error.permanent常量定义于 internal/obs_report_sender.go(ErrorPermanentKey = "error.permanent")。永久性错误(如数据格式非法)不会被重试逻辑挽回,可结合该属性对失败原因分类治理。

otelcol_exporter_send_failed_log_records:发往目标端失败的日志记录数。

UnitMetric TypeValue TypeMonotonicStability
{record}SumInttrueAlpha

otelcol_exporter_send_failed_metric_points:发往目标端失败的指标数据点数。

UnitMetric TypeValue TypeMonotonicStability
{datapoint}SumInttrueAlpha

otelcol_exporter_send_failed_profile_samples:发往目标端失败的 profile 样本数(Development 阶段)。

UnitMetric TypeValue TypeMonotonicStability
{sample}SumInttrueDevelopment

otelcol_exporter_send_failed_spans:发往目标端失败的 span 数。

UnitMetric TypeValue TypeMonotonicStability
{span}SumInttrueAlpha

发送成功类:sent_*

与失败类一一对应,统计成功送达目标端的记录数。成功率 = sent / (sent + send_failed),两个指标均为单调递增的 Counter,可在 Prometheus 中用rate()观察趋势。

otelcol_exporter_sent_log_records:成功发往目标端的日志记录数。

UnitMetric TypeValue TypeMonotonicStability
{record}SumInttrueAlpha

otelcol_exporter_sent_metric_points:成功发往目标端的指标数据点数。

UnitMetric TypeValue TypeMonotonicStability
{datapoint}SumInttrueAlpha

otelcol_exporter_sent_profile_samples:成功发往目标端的 profile 样本数(Development 阶段)。

UnitMetric TypeValue TypeMonotonicStability
{sample}SumInttrueDevelopment

otelcol_exporter_sent_spans:成功发往目标端的 span 数。

UnitMetric TypeValue TypeMonotonicStability
{span}SumInttrueAlpha

指标背后的实现:观测链路与 sender 链

理解这些指标的发出位置,有助于在实际排障时定位问题出自哪一层。

sender 链的构建顺序

在 internal/base_exporter.go 的NewBaseExporter中,发送链路按以下顺序包装(数据从内向外依次经过):

  1. Consumer Sender:真正的导出逻辑(调用目标 exporter);
  2. Timeout Sender:仅当timeout非 0 时启用,控制单次导出尝试的时间上限;
  3. Retry Sender:仅当retry_on_failure.enabled时启用,负责指数退避重试;
  4. ObsReport Sender:总是启用,负责采集发送成功 / 失败 / 在途指标;
  5. Queue Sender:仅当配置了sending_queue时启用,负责排队与批处理,并把数据交给firstSender

因此指标采集(ObsReport)位于重试与队列之间:入队失败(enqueue_failed)发生在进入 Queue Sender 之前,不会到达重试逻辑;发送失败 / 成功(send_failed / sent)与在途(in_flight)则由 ObsReport 在重试之外统计。

观测实现细节

obsReportSender(见 internal/obs_report_sender.go)为每个 exporter 与信号组合创建 span,命名格式为exporter/<exporter_id>/<signal>,并附带exporterdata_type属性。TelemetryBuilder(generated_telemetry.go)通过NewTelemetryBuilder从组件级TelemetrySettingsMeterProvider创建所有计数器、直方图与可观测 Gauge;两个队列 Gauge(queue_capacity/queue_size)通过RegisterExporterQueueCapacityCallback/RegisterExporterQueueSizeCallback注册异步回调采集。

Feature Gate:exporter.PersistRequestContext

documentation.md的 Feature Gates 部分定义了一个与持久化队列相关的开关:

Feature GateStageDescriptionFrom VersionTo Version
exporter.PersistRequestContextstable控制是否将 context 与请求一起存储进持久化队列v0.128.0v0.154.0

该开关的元数据同时登记在 metadata.yaml 中,对应 OpenTelemetry Collector PR #13188。含义要点:

  • 启用后,请求的 context(含 client metadata 与 span context)会随数据一并持久化,重启后恢复导出的数据仍能保留这些上下文信息;
  • 但需要注意,Auth 扩展写入 context 的鉴权信息不会被持久化(详见 README.md),因此持久化队列恢复出的数据不携带认证上下文;
  • 该开关从 v0.128.0 引入、v0.154.0 后行为固化(stable阶段,当前仓库 vendored 的版本为 v0.153.0,正处于该开关的有效窗口内)。更完整的 Feature Gate 机制说明见 Collector 的featuregate包文档。

配置与指标联动:从 README 继承的完整参数表

exporterhelper的 README 给出了与上述指标直接相关的全部配置项,理解它们才能正确解读指标。以下参数均可在使用 Collector exporter 的配置(或 Tempo 内嵌 collector 组件的构造代码)中设置。

失败重试 retry_on_failure

参数默认值说明
enabledtrue是否在导出失败后重试
initial_interval5s首次失败后的等待时间;enabled=false时忽略
max_interval30s退避间隔上限;enabled=false时忽略
max_elapsed_time300s发送单个批次累计花费的最大时间;设为 0 表示永不停止重试;enabled=false时忽略
multiplier1.5每次重试间隔的放大倍数;enabled=false时忽略

对应的默认值与校验逻辑位于 vendor/go.opentelemetry.io/collector/config/configretry/backoff.go:默认间隔 5s、间隔上限 30s、最大累计时间 5 分钟;校验规则要求max_elapsed_time不小于initial_intervalmax_interval。重试采用指数退避(cenkalti/backoff),并带随机化因子(randomization_factor,默认在 [0,1] 内)。这些重试行为与otelcol_exporter_in_flight_requests(退避期间仍算在途)以及send_failed_*error.permanent属性直接相关

发送队列 sending_queue

参数默认值说明
enabledtrue是否启用发送队列
num_consumers10从队列取批次的消费者数量;enabled=false时忽略
wait_for_resultfalse入队请求是否阻塞等待处理结果
block_on_overflowfalse队列满时是否阻塞等待空位;为 false 则立即拒绝数据
sizerrequests队列与批处理的计量方式:requests(按请求/批次数,性能最佳)、items(按最小数据单元数)、bytes(按序列化字节数,性能最差)
queue_size1000队列可容纳的最大批次数量,单位由sizer决定
batch禁用批处理配置,见下

失败行为:数据无法进入发送队列时通常被丢弃——包括队列达到容量上限,或持久化队列底层存储无法写入(磁盘空间不足、I/O 错误)。启用block_on_overflow后调用方可能等待空位并在超时前成功入队。被拒数据不会进入重试逻辑,由otelcol_exporter_enqueue_failed_*统计——这正是解读该组指标的关键前提(见 README.md)。

批量设置 batch(默认关闭,显式写batch: {}可启用默认值):

参数默认值说明
flush_timeout200ms批次达到该时间即发出,必须非 0
min_size8192批次的单位数下限;若batch::sizersending_queue::sizer相同,则应不大于queue_size
max_size0批次单位数上限,支持拆分超大批次;0 表示无上限
sizer继承父级itemsbytes;未设置时取父结构值,父级也未设置则默认items
partition批次分区:metadata_keysclient.Metadata键列表,按键值组合分派到不同 batcher;空值/未设置视为独立分区;键不区分大小写,重复项触发校验错误

批次的最终规模反映在otelcol_exporter_queue_batch_send_size_bytes直方图中,可用其分位数验证min_size/max_size设置的实际效果。

超时 timeout

参数默认值说明
timeout5s每次向目标端发送数据的单次尝试等待时间

initial_intervalmax_intervalmax_elapsed_timetimeout均接受 Go duration 字符串(如5s1m),合法时间单位包括nsus(或µs)、mssmh

持久化队列(Persistent Queue)

启用持久化队列只需设置sending_queue.storage指向某个 storage 扩展(如 filestorage),此时不再使用内存队列,磁盘上缓存的批次上限同样由queue_size控制(默认 1000 批)。Collector 进程被杀死时队列中残留的批次会在重启后继续导出。README 给出了完整示例配置:

receivers: otlp: protocols: grpc: exporters: otlp_grpc: endpoint: <ENDPOINT> sending_queue: storage: file_storage/otc extensions: file_storage/otc: directory: /var/lib/storage/otc timeout: 10s service: extensions: [file_storage] pipelines: metrics: receivers: [otlp] exporters: [otlp] logs: receivers: [otlp] exporters: [otlp] traces: receivers: [otlp] exporters: [otlp]

对应的队列状态(queue_capacity/queue_size)与批次大小直方图在持久化模式下同样有效,可用于监控磁盘队列积压与消费速度。

运维实践:用这些指标定位导出链路问题

综合上述定义,可形成以下排障路径(以 trace 信号为例):

  1. otelcol_exporter_sent_spansrate()otelcol_exporter_enqueue_failed_spans对比:如果入队失败持续增长而发送成功平稳,问题在队列容量或持久化存储(如磁盘满),而不是目标端;
  2. otelcol_exporter_queue_size / otelcol_exporter_queue_capacity逼近 1:队列接近打满,优先扩容queue_size或增加num_consumers,并检查block_on_overflow设置以避免静默丢弃;
  3. otelcol_exporter_in_flight_requests长期处于高位:目标端吞吐不足,重试退避中的请求也计入该值,需检查retry_on_failure的退避参数与目标端健康;
  4. otelcol_exporter_send_failed_spans增长:按error.permanent属性区分永久性失败与可重试失败,永久性失败(如数据格式错误)应在上游治理,可重试失败则可调整initial_interval/max_interval/max_elapsed_time
  5. 批次直方图形态异常otelcol_exporter_queue_batch_send_size若始终贴近min_sizeflush_timeout频繁触发,说明流量稀疏,可下调min_size以降低延迟。

上述全部指标的定义源文件为 documentation.md,指标元数据(含直方图 bucket 边界与稳定性声明)可在 metadata.yaml 中查阅,生成代码位于 internal/metadata/generated_telemetry.go。需要留意的是,各指标的 Stability 差异(Alpha / Development)意味着其 API 与语义在 Collector 演进中可能调整,升级版本时应回归核对告警规则。

【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询