多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

深入解析 Tempo 内置的 OTel Collector Filter Processor:内部遥测指标、defaultErrorModeIgnore 特性开关与 OTTL 过滤配置实战

深入解析 Tempo 内置的 OTel Collector Filter Processor:内部遥测指标、defaultErrorModeIgnore 特性开关与 OTTL 过滤配置实战 深入解析 Tempo 内置的 OTel Collector Filter Processor内部遥测指标、defaultErrorModeIgnore 特性开关与 OTTL 过滤配置实战【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempoFilter Processor 是 OpenTelemetry Collector 生态中负责按条件丢弃遥测数据的核心处理器允许基于 OTTLOpenTelemetry Transformation Language条件丢弃 spans、span events、metrics、datapoints、logs 与 profiles。本文以 Grafana Tempo 仓库内置的filterprocessor组件vendor 目录及其自动生成的遥测文档documentation.md为骨架结合 README.md、config.go、telemetry.go 等源码以及 Tempo 中真实使用该处理器的 forwarder.go系统讲解其埋点指标、特性开关feature gate、错误模式、基础/高级两种配置风格、上下文推断context inference与迁移注意事项帮助你读懂遥测文档中的每一个字段并能在 Tempo 的分布式追踪转发链路中正确配置与运维过滤器。一、Filter Processor 是什么组件定位与能力边界Filter Processor 允许在 Collector 内部丢弃 spans、span events、metrics、datapoints 与 logs。它利用 OTTL 语言构造条件来决定何时丢弃遥测数据只要任意一条条件命中对应的遥测就会被丢弃同一列表内的条件之间是 OR 关系。从 metadata.yaml 可以看到组件元信息type: filterclass: processor稳定性traces、metrics、logs 为 alphaprofiles 为 development分发范围core、contrib、k8s 三种官方发行版均包含告警项Orphaned Telemetry孤儿遥测、Other代码维护者TylerHelmuth、evan-bradley、edmocosta、bogdandrutuTempo 仓库将其作为 vendored 依赖内置并在 modules/distributor/forwarder/forwarder.go 中直接 importfilterprocessor用于在把 trace 转发到外部 OTLP gRPC 后端之前按 span 条件做过滤这是理解该组件在 Tempo 中价值的最佳入口详见第六节。二、内部遥测指标documentation.md 的四个计数器documentation.md是 mdatagen 自动生成的组件遥测说明它声明了 Filter Processor 对外暴露的4 个内部指标全部是被丢弃数量类计数器。下表逐一说明指标名含义UnitMetric TypeValue TypeMonotonicStabilityotelcol_processor_filter_datapoints.filtered被 Filter Processor 丢弃的 metric data point 数量1SumInttrueDevelopmentotelcol_processor_filter_logs.filtered被 Filter Processor 丢弃的 log 数量1SumInttrueDevelopmentotelcol_processor_filter_profiles.filtered被 Filter Processor 丢弃的 profile 数量1SumInttrueDevelopmentotelcol_processor_filter_spans.filtered被 Filter Processor 丢弃的 span 数量1SumInttrueDevelopment这些指标的含义可以归纳为三个共同特征均为单调递增的 Int Summonotonic: true表示计数器只增不减反映的是累计丢弃量适合通过rate()、increase()等函数观察丢弃速率Unit 均为1表示纯计数无时间、字节等量纲Stability 均为 development指标本身仍处于开发阶段字段或语义可能在未来版本调整。2.1 指标在源码中如何生成documentation.md中的表格与 metadata.yaml 中的telemetry.metrics声明一一对应description、unit、sum.monotonic、stability 完全一致再由 mdatagen 据此生成internal/metadata包与计数器对象。运行时埋点逻辑在 telemetry.gonewFilterTelemetry根据 pipeline 的信号类型metrics/logs/traces/profiles选择对应的计数器例如 traces 信号绑定ProcessorFilterSpansFilteredtelemetry.go#L37计数器附带filter属性标签attribute.NewSet(attribute.String(metadata.Type.String(), set.ID.String()))即指标会带上处理器的类型名与实例 ID方便在多处理器实例场景下按名称区分record(ctx, dropped)方法统一执行counter.Add记录本次被丢弃的数量。因此这四个指标在 Prometheus 等监控体系中的使用方式可以概括为# 观测 span 丢弃速率 sum by (filter) (rate(otelcol_processor_filter_spans.filtered[5m]))由于指标带filter标签还可以按不同 filter 实例分别告警例如当某个 filter 的丢弃速率异常飙升时触发告警这通常是配置条件过宽、误伤合法数据的信号。三、Feature Gateprocessor.filter.defaultErrorModeIgnoredocumentation.md声明了组件唯一的特性开关Feature GateStageDescriptionFrom VersionTo VersionReferenceprocessor.filter.defaultErrorModeIgnorebeta将 filter processor 的默认 error_mode 从 propagate 改为 ignorev0.150.0N/Aupstream issue #472323.1 它到底改变了什么error_mode决定处理器在评估 OTTL 条件出错时如何反应。该开关把默认值从propagate把错误向上游传递导致整个 payload 被丢弃改为ignore记录错误日志但保留数据、继续评估下一条条件。在 config.go 的注释中同样写明feature gate 启用默认时默认值是ignore禁用时默认值是propagate。为何推荐ignore因为过滤器本意是选择性丢弃如果因条件求值出错反而把整个批次数据丢掉属于放大故障。ignore模式把错误限制在日志层面既保证可观测性又保证正常数据不被误伤。3.2 如何恢复旧默认值如果需要恢复 v0.150.0 之前的propagate默认行为在启动 Collector 时显式禁用该 gate 即可./otelcol --config config.yaml --feature-gates-processor.filter.defaultErrorModeIgnore--feature-gates参数中带-前缀表示禁用不带前缀表示启用。由于该 gate 处于 beta 阶段且默认启用绝大多数用户无需任何操作即可获得ignore的默认行为只有依赖出错即丢弃整个 payload的严格语义时才需要显式禁用。四、error_mode 详解与优先级配置层面error_mode是一个可选的顶层字段也可在高级配置中按条件组覆盖。三种模式的语义对照如下error_mode行为适用场景ignore忽略条件返回的错误、记录日志继续评估下一条条件推荐生产环境默认选择兼顾可见性与数据完整性silent忽略错误且不记录日志继续评估下一条条件数据量极大、错误日志噪音高只关心过滤结果propagate把错误沿 pipeline 向上返回导致整个 payload 被丢弃严格要求宁可整体丢弃也不放过可疑数据的场景三个模式在 Tempo 的转发器实现中也有体现forwarder.go 创建 filter processor 时显式设置fpCfg.ErrorMode ottl.IgnoreError即 Tempo 的 trace 转发链路默认采用ignore语义——即便过滤条件出错也不会影响原始 trace 的继续转发。五、配置实战基础风格、高级风格与上下文推断Filter Processor 的核心配置按信号拆分为trace_conditions、metric_conditions、log_conditions、profile_conditions四个列表每个列表可以容纳 OTTL 条件字符串基础风格或带上下文/错误模式的对象高级风格。5.1 每种信号可用的 OTTL 上下文信号可用上下文trace_conditionsresource、scope、span、spaneventmetric_conditionsresource、scope、metric、datapointlog_conditionsresource、scope、logprofile_conditionsresource、scope、profile上下文按层级从高到低求值Logsresource→scope→logMetricsresource→scope→metric→datapointTracesresource→scope→span→spanevent层级求值的关键行为若较高层级的遥测命中条件被丢弃较低层级的条件就不再检查。例如一个 span 被丢弃后针对该 span 的 spanevent 条件不会执行反之若某 span 的全部 span event 都被丢弃span 本身会原样保留若某 metric 的全部 datapoint 都被丢弃该 metric 也会被一并丢弃。5.2 基础配置Basic Config基础风格把 OTTL 条件写成扁平字符串列表条件之间 OR 连接是最简单的用法processors: filter: error_mode: propagate trace_conditions: - span.attributes[container.name] app_container_1 - resource.attributes[host.name] localhost - span.name app_3 metric_conditions: - metric.name my.metric and resource.attributes[my_label] abc123 - metric.type METRIC_DATA_TYPE_HISTOGRAM - resource.attributes[service.name] my_service_name log_conditions: - IsMatch(log.body, .*password.*) - log.severity_number SEVERITY_NUMBER_WARN profile_conditions: - profile.duration_unix_nano 3000要点条件内支持and、or与括号()组合OTTL 函数如IsMatch、枚举如METRIC_DATA_TYPE_HISTOGRAM、SEVERITY_NUMBER_WARN可直接使用引号内的字符串按字面值比较。5.3 高级配置Advanced Config当需要为某组条件显式指定上下文、或覆盖顶层error_mode时使用对象形式processors: filter: error_mode: propagate trace_conditions: - conditions: - resource.attributes[host.name] localhost - error_mode: ignore conditions: - span.attributes[container.name] container_1 - span.name app_3 - conditions: - spanevent.attributes[grpc] true - IsMatch(spanevent.name, .*grpc.*) metric_conditions: - conditions: - metric.name my.metric and resource.attributes[my_label] abc123 - metric.type METRIC_DATA_TYPE_HISTOGRAM - conditions: - metric.type METRIC_DATA_TYPE_SUMMARY log_conditions: - conditions: - IsMatch(log.body, .*password.*) - log.severity_number SEVERITY_NUMBER_WARN对象字段说明context指定该组条件的 OTTL 上下文取值必须落在上表允许范围内。大多数情况下不要手动设置让处理器自动推断即可见 5.4error_mode覆盖顶层 error_mode仅对该组条件生效取值ignore/silent/propagateconditionsOTTL 条件字符串列表任意一条命中即丢弃。在 config.go 的Unmarshal实现中可以看到基础风格字符串数组会被自动改造成单组、无 context的conditions对象再走统一的解析路径两种风格不能在同一个*_conditions列表中混用否则返回configuring multiple configuration styles is not supported错误。5.4 上下文推断Context Inference由于 OTTL Path 都以上下文名作为前缀如span.、spanevent.、resource.处理器可以自动推断每条条件所属的上下文并按层级顺序分组执行。例如trace_conditions: - scope.name my.scope # 推断为 scope 上下文 - span.name app_3 # 推断为 span 上下文 - spanevent.name grpc.timeout # 推断为 spanevent 上下文 - resource.attributes[host.name] localhost # 推断为 resource 上下文执行顺序为 resource → scope → span → spanevent。当一条条件里混用多个上下文 Path 时取较低上下文求值例如trace_conditions: - resource.attributes[host.name] localhost or spanevent.name grpc.timeout该条件等价于对每个 span event检查其父 span 的 resource 属性host.name是否为localhost或该 span event 名称是否为grpc.timeout任一为真即丢弃该 span event。推断失败的情形当 Path、函数或枚举的组合在不同上下文间不兼容时配置会校验失败。例如IsRootSpan() or spanevent.name bar——IsRootSpan()只在 span 上下文可用而spanevent.前缀要求按 span event 上下文求值二者冲突。解决办法是拆分为两条高级配置trace_conditions: - context: span conditions: - IsRootSpan() - conditions: - spanevent.name barIsRootSpan()没有 Path 前缀无法推断上下文必须显式context: span。上述规则在 config.go 的validateInferredContextConfig中会在启动前完成校验错误配置会在启动阶段即被拒绝。5.5 高频实战示例以下示例均来自组件官方文档可直接套用按资源属性丢弃例如按 k8s Pod 名过滤processors: filter: error_mode: ignore trace_conditions: - resource.attributes[k8s.pod.name] my-pod-name丢弃类型无效的指标processors: filter: error_mode: ignore metric_conditions: - metric.type METRIC_DATA_TYPE_NONE按指标名与具体值组合丢弃processors: filter: error_mode: ignore metric_conditions: - metric.name k8s.pod.phase and datapoint.value_int 4丢弃非 HTTP span通过属性是否为 nil 判断processors: filter: error_mode: ignore trace_conditions: - span.attributes[http.request.method] nil丢弃 HTTP spanprocessors: filter: error_mode: ignore trace_conditions: - span.attributes[http.request.method] ! nil丢弃持续时间不足 1 秒且非错误状态的 spanprocessors: filter: error_mode: ignore trace_conditions: - (span.end_time - span.start_time) Duration(1s) and span.status.code ! STATUS_CODE_ERROR5.6 处理器专属 OTTL 函数除全部 OTTL Converter 函数外Filter Processor 还自带两个仅用于 metrics 的 datapoint 级函数HasAttrKeyOnDatapoint(key)当 metric 上任意一个 datapoint的属性表包含给定 key 时返回true必须在metrics.metric上下文使用。示例HasAttrKeyOnDatapoint(http.method)HasAttrOnDatapoint(key, value)当 metric 上任意一个 datapoint 的属性表同时命中 key 与 value 时返回truekey/value 均为字符串若 datapoint 上对应属性值不是字符串则与比较。示例HasAttrOnDatapoint(http.method, GET)。这两个函数用于根据 datapoint 级属性决定是否丢弃整个 metric的场景例如丢弃包含bad.metric属性键的指标filter/keep_good_metrics: error_mode: ignore metrics: metric: - HasAttrKeyOnDatapoint(bad.metric)六、Tempo 中的真实集成distributor 转发链路过滤Tempo 仓库在 modules/distributor/forwarder/forwarder.go 中把 filterprocessor 直接用于 trace 转发前的预处理。核心逻辑如下创建转发器时若配置中带有 span 或 span event 过滤条件len(cfg.Filter.Traces.SpanConditions) 0 || len(cfg.Filter.Traces.SpanEventConditions) 0forwarder.go#L70则包装出一个FilterForwarderNewFilterForwarder通过filterprocessor.NewFactory()创建官方 factory并显式配置fpCfg.ErrorMode ottl.IgnoreError与fpCfg.Traces filterprocessor.TraceFilters{SpanConditions, SpanEventConditions}forwarder.go#L95-L100ForwardTraces先深拷贝ptrace.Traces再交给 filter processor 消费避免修改原始 traceforwarder.go#L118-L129过滤后的数据经由 adapter 交给真正的 OTLP gRPC 后端转发。由此可以推断Tempo 允许运维人员通过 distributor 的 forwarder 配置为 trace 转发定义 span 级过滤规则配合error_mode: ignore即使过滤条件异常也不会中断转发链路。这与本文前面关于error_mode的语义完全一致是理解文档中的配置概念如何落到真实项目代码的最佳实例。七、旧配置迁移与排查7.1 Legacy 配置迁移旧的按上下文分段的写法traces.resource、metrics.datapoint、logs.log_record等已废弃需迁移到统一的*_conditions格式。迁移映射如下废弃配置迁移目标traces.resourcetrace_conditionsresource.前缀traces.spantrace_conditionsspan.前缀traces.spaneventtrace_conditionsspanevent.前缀metrics.resourcemetric_conditionsresource.前缀metrics.metricmetric_conditionsmetric.前缀metrics.datapointmetric_conditionsdatapoint.前缀logs.resourcelog_conditionsresource.前缀logs.log_recordlog_conditionslog.前缀profiles.resourceprofile_conditionsresource.前缀profiles.profileprofile_conditionsprofile.前缀需要特别注意的是新老两套写法不能同时使用Validate会对trace_conditions/traces.*、metric_conditions/metrics.*等组合返回明确的互斥错误见 config.go#L492-L511有助于在启动期尽早发现配置冲突。7.2 OTTL 调试技巧OTTL 提供精确的求值日志。将 collector 日志级别设为debug后每次条件求值都会打印类似如下的诊断信息包含condition、match结果与完整的 TransformContextservice: telemetry: logs: level: debug输出示例2024-05-29T16:47:04.362-0600 debug ottlv0.101.0/parser.go:338 condition evaluation result {kind: processor, name: filter, pipeline: logs, condition: body \test\, match: true, TransformContext: {resource: {...}, scope: {...}, log_record: {body: test, ...}, cache: {}}}该日志能直观展示 OTTL 眼中的底层数据形态属性、body、severity 等是定位条件为什么不生效的首选手段。注意此特性非常冗长生产环境建议仅在排障时临时开启。7.3 使用警告务必先理解数据形态再配置过滤条件越宽泛误丢正确数据的风险越高。建议使用尽可能具体的条件并在上线前充分测试孤儿遥测Orphaned Telemetry丢弃 span 可能导致其子 span 成为孤儿若日志引用了被丢弃的 span日志也可能失去关联上下文。在 Tempo 这类以 trace 关联为核心的系统中过滤 span 前需评估对完整链路可观测性的影响。八、小结围绕documentation.md这份 mdatagen 自动生成的遥测文档我们完整拆解了 Filter Processor 的可观测性契约4 个.filtered单调计数器与唯一特性开关processor.filter.defaultErrorModeIgnorebeta、默认启用、将默认 error_mode 从 propagate 改为 ignore。在此基础上结合 README.md 与源码掌握了error_mode三态语义、按信号划分的上下文层级求值规则、基础/高级两种配置风格、上下文自动推断机制、两个专属 OTTL 函数、Legacy 迁移映射与 debug 调试方法并透过 forwarder.go 看到 Tempo 如何在分布式转发链路中落地这套过滤能力。实际使用时建议保持默认的ignore错误模式用*_conditions新格式书写尽量具体的条件配合otelcol_processor_filter_*_filtered指标的速率与filter标签做丢弃量监控即可安全地利用 Filter Processor 实现低误伤、可观测、可回滚的遥测裁剪。【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表