你拥有 IP,你想要主机名:为 OpenTelemetry 构建一个查找处理器
作者来自 Elastic Vihas Makwana在 OpenTelemetry Collector 中从 YAML、CSV 或 DNS 查找任意值或者通过 Elastic 构建并提交到 Collector Contrib 的 processor 接入你自己的数据源。丰富化是那些听起来很简单的任务之一直到你尝试在遥测管道中实现它。你在日志记录中有一个 user.id并且想要获取 user.name。你有一个 client.ip并且想要获取其背后的主机名。直到现在OpenTelemetry Collector 还没有一种通用方式来执行这种类型的查找。目前最接近的选择是在 transform processor 中手动编写映射# otel.yml processors: transform: log_statements: - context: log statements: - set(attributes[user.name], Alice) where attributes[user.id] user001 - set(attributes[user.name], Bob) where attributes[user.id] user002 - set(attributes[user.name], Carol) where attributes[user.id] user003 # ...and one more line for every user这对于少量条目有效但无法扩展到超过 10 到 20 个条目的情况。每一个新的映射都意味着增加另一条语句查找数据和你的管道配置位于同一个文件中并且无法指向已经存在的参考数据。它证明了这种需求是真实存在的但它只能覆盖最简单、最小规模的场景。如果你运行 Collector并且一直在使用 transform processor、sidecar 脚本或下游 ingest pipeline 只是为了添加参考数据那么这个组件就是为你准备的。为什么 OpenTelemetry Collector 需要 lookup processorCollector 已经能够很好地处理几种丰富化模式。transform processor 会根据记录中已有的数据重新组织和派生数据。k8sattributes 和 resourcedetection processors 会附加系统和环境元数据例如 Kubernetes pod 详细信息或云主机信息。但它无法根据你已经拥有的键来查找相关数据。尤其是以下三种模式没有对应的解决方案从 JSON、YAML 或 CSV 中的静态参考数据进行基于文件的查找从外部服务进行基于 HTTP 和 API 的丰富化DNS 查找例如将 IP 解析为主机名这些是在其他数据采集器和转换工具中的日常任务。将内部服务 ID 映射到易读名称根据客户 ID 附加业务元数据或者解析 IP都属于这一类任务。如果没有原生组件团队只能构建脆弱的变通方案或者将工作推送到下游而在那里更难复用。这个差距正是新的lookup processor所解决的问题。Elastic 的 Data Processing 团队提出了它社区接受了它并且它是在 Grafana 的合作下构建完成的感谢 Sam DeHaanGH: dehaansa。lookup processor 从你的遥测数据中获取一个值使用 OTTL 构建查找键查询 YAML 文件或 DNS 等数据源并将结果作为新的属性写回。OpenTelemetry lookup processor 的设计方式该设计源于社区对更丰富丰富化能力的反复需求。促成它的一些示例包括根据 YAML 或 CSV 定义通过键匹配丰富属性#40526使用来自清单数据源的资源元数据丰富遥测数据#40936通用资源检测器#29627Alert Manager receiver 和 exporter#18526gRPC processor / connector#20888与其为每个请求构建一个一次性组件目标是创建一个足够灵活的单一 processor 来覆盖这些场景。以下四个理念塑造了它支持每个 processor 进行多次查找因此一个实例可以在单次处理中丰富多个属性。支持缓存因此 DNS 等外部数据源不会针对同一个键被反复查询。使用 OTTL 进行键提取因此你可以获得完整的表达式语言用于从记录中提取查找键包括转换器。支持可扩展的数据源因此你不会受限于内置的数据源集合。你可以为自己的数据注册自定义数据源。可扩展的数据源对于该 processor 的长期价值最为重要。数据源是一个小型、定义清晰的接口因此该 processor 是一个丰富化基础而不是一个固定的功能列表。YAML 和 CSV 目前覆盖静态参考数据DNS 覆盖动态解析而相同的接口为 HTTP API、键值存储或任何特定于你环境的数据源留下了扩展空间。Lookup processor 如何使用 OTTL 评估键无论你配置哪种数据源该 processor 都会针对每条记录执行相同的三个步骤。首先它会评估一个 OTTL 表达式以从记录中生成一个查找键。其次它会将该键传递给配置的数据源并获取返回值。第三它会将该值写入你指定的属性中写入记录本身或其父资源中。当某个键没有匹配项时该 processor 会写入一个可配置的默认值以确保下游查询保持可预测。接下来的两个部分将介绍当前可用的两个数据源。在 OpenTelemetry Collector 中使用 YAML 进行基于文件的查找最常见的场景是静态参考数据。你将一个映射文件保存在 Collector 旁边并根据它丰富记录。这里processor 会读取一个 YAML 文件并根据 user.id 为每条日志添加 user.name。# otel.yml processors: lookup: source: type: yaml path: /etc/otel/mappings.yaml lookups: - key: log.attributes[user.id] attributes: - destination: user.name default: Unknown User映射文件是一组简单的键值对# /etc/otel/mappings.yaml user001: Alice user002: Bobkey 字段是一个 OTTL 值表达式因此 log.attributes[user.id] 会从日志记录中读取 user.id 属性。destination 是查找到的值写入的位置而 default 是当键在文件中不存在时写入的内容。给定以下传入的日志记录{ body: User logged in, attributes: { user.id: user001, http.method: POST } }该 processor 查找 user001找到 Alice并生成{ body: User logged in, attributes: { user.id: user001, user.name: Alice, http.method: POST } }原始属性保持不变丰富化后的值会添加在它们旁边。对于将参考数据保存在电子表格或导出文件中而不是 YAML 中的团队CSV 数据源的工作方式相同。在 OpenTelemetry Collector 中进行 DNS 查找丰富化静态文件是一回事但有些丰富化需要实时变化的数据。将 IP 地址解析为主机名是典型示例也是该 processor 支持的第一个动态数据源。你不需要使用文件而是将它指向一个 DNS 服务器。# otel.yml processors: lookup: source: type: dns lookups: - key: log.attributes[client.ip] attributes: - destination: client.hostname default: Not found配置的结构与 YAML 示例完全相同。只有数据源发生了变化。该 processor 从记录中提取 client.ip向 DNS 解析器请求反向解析并将主机名写回。给定以下传入记录{ body: User logged in, attributes: { client.ip: 8.8.8.8, http.method: POST } }DNS 数据源解析 8.8.8.8并生成{ body: User logged in, attributes: { client.ip: 8.8.8.8, client.hostname: dns.google, http.method: POST } }因为 DNS 查询会访问外部系统所以缓存的作用就体现出来了。该 processor 会将结果保存在内存缓存中因此共享相同 IP 的一系列记录不会变成一系列相同的 DNS 查询。这样可以降低延迟并避免对解析器造成过大压力。编写自定义 lookup source内置数据源覆盖了常见场景但真正的设计目标是可扩展性。数据源是一个小型契约你实现一个查找函数该函数接收字符串键并返回一个值。processor 负责 OTTL 键评估、缓存、默认值以及属性写入因此自定义数据源只需要回答“这个键对应什么值”这个问题。这意味着如果你已经运行一个内部元数据 API、Redis 缓存或自定义数据库你可以将其接入为一个数据源并复用 processor 提供的其他所有功能。基于 HTTP 的数据源和键值存储都是自然匹配的选择它们也正位于路线图中因为该接口使它们很容易添加。Elastic 如何计划使用这个 lookup processorElastic 基于 OpenTelemetry Collector Contrib 构建其 Collector 发行版。计划包含 lookup processor使团队今天通过脆弱变通方案完成的丰富化工作可以在管道内部运行而不是在下游执行。有两种模式尤为突出。第一种是参考数据丰富化将内部服务 ID 转换为易读名称或者根据 ID 附加团队或客户等元数据使遥测数据到达时已经带有用于搜索和关联的标签。第二种是 DNS 解析在数据落地之前将 client.ip 转换为主机名这对于网络和安全遥测非常重要因为你通常需要名称而不是原始地址。在 Collector 中执行这些操作可以让参考数据更接近遥测处理的位置并避免在单独的 ingest 步骤中重复实现逻辑。随着数据源接口扩展以支持 HTTP API 和键值存储同一个 processor 可以支持更丰富的丰富化而无需改变管道配置方式。Lookup processor 路线图以及如何贡献Lookup processor 的主要实现已经合并到 OpenTelemetry Collector Contrib 上游。核心 processor 和 YAML 数据源首先完成合并随后 DNS 数据源作为第一个动态查找功能加入。未来还有大量工作需要完成欢迎贡献用于从外部 API 进行丰富化的 HTTP lookup source。更多 DNS 能力包括 A 和 AAAA 查询以及支持多个 DNS 服务器。组件遥测以便你可以观察缓存命中率和未命中率、查找延迟以及错误率。随着真实使用场景增加而进行的性能优化。如果你想尝试它可以将 processor 添加到包含 Contrib 的 Collector 构建中将 YAML 数据源指向一个映射文件并丰富一条真实记录。然后在 OpenTelemetry Collector Contrib 仓库中提交 issue 或 pull request。该组件由社区共同维护获得的数据源和反馈越多它就会变得越有用。想进一步了解可以阅读 lookup processor README 和丰富化跟踪 issue。要了解更多 Elastic 如何基于 OpenTelemetry 构建功能请浏览 Elastic Observability Labs 中的 OpenTelemetry 文章。原文OpenTelemetry lookup processor: File and DNS enrichment — Elastic Observability Labs