OpenTelemetry: 经得起考验的工具

摘自:https://blog.newrelic.com/product-news/what-is-opentelemetry/

什么是 OpenTelemetry?

OpenTelemetry 合并了 OpenTracing 和 OpenCensus 项目,提供了一组 API 和库来标准化遥测数据的采集和传输。OpenTelemetry 提供了一个安全,厂商中立的工具,这样就可以按照需要将数据发往不同的后端。

OpenTelemetry 项目由如下组件构成:

  • 推动在所有项目中使用一致的规范
  • 基于规范的,包含接口和实现的 APIs
  • 不同语言的 SDK(APIs 的实现),如 Java, Python, Go, Erlang 等
  • Exporters:可以将数据发往一个选择的后端
  • Collectors:厂商中立的实现,用于处理和导出遥测数据

术语

如果刚接触 Opentelemetry,那么需要了解如下术语:

  • Traces:记录经过分布式系统的请求活动,一个 trace 是 spans 的有向无环图

  • Spans:一个 trace 中表示一个命名的,基于时间的操作。Spans 嵌套形成 trace 树。每个 trace 包含一个根 span,描述了端到端的延迟,其子操作也可能拥有一个或多个子 spans。

  • Metrics:在运行时捕获的关于服务的原始度量数据。Opentelemetry 定义的 metric instruments(指标工具) 如下。Observer 支持通过异步 API 来采集数据,每个采集间隔采集一个数据。 | ame | Synchronous | Adding | Monotonic | | —- | —- | —- | —- | | Counter | Yes | Yes | Yes | | UpDownCounter | Yes | Yes | No | | ValueRecorder | Yes | No | No | | SumObserver | No | Yes | Yes | | UpDownSumObserver | No | Yes | No | | ValueObserver | No | No | No |

  • Context:一个 span 包含一个span context,它是一个全局唯一的标识,表示每个 span 所属的唯一的请求,以及跨服务边界转移 trace 信息所需的数据。OpenTelemetry 也支持correlation context,它可以包含用户定义的属性。correlation context不是必要的,组件可以选择不携带和存储该信息。

  • Context propagation:表示在不同的服务之间传递上下文信息,通常通过 HTTP 首部。 Context propagation 是 Opentelemetry 系统的关键功能之一。除了 tracing 之外,还有一些有趣的用法,如,执行 A/B 测试。OpenTelemetry 支持通过多个协议的 Context propagation 来避免可能发生的问题,但需要注意的是,在自己的应用中最好使用单一的方法。

OpenTelemetry 的好处

通过将 OpenTracing 和 OpenCensus 合并为一个开放的标准,OpenTelemetry 提供了如下便利:

  • 选择简单:不必在两个标准之间进行选择,OpenTelemetry 可以同时兼容 OpenTracing 和 OpenCensus。
  • 跨平台:OpenTelemetry 支持各种语言和后端。它代表了一种厂商中立的方式,可以在不改变现有工具的情况下捕获并将遥测数据传输到后端。
  • 简化可观测性:正如 OpenTelemetry 所说的 “高质量的观测下要求高质量的遥测”。希望看到更多的厂商转向 OpenTelemetry,因为它更方便,且仅需测试单一标准。

如何使用 OpenTelemetry

OpenTelemetry APIs 和 SDKs 有很多快速使用指南和文档帮助快速入门,如Java 快速指南展示了如何获取跟踪程序、创建 spans、添加属性,以及跨不同 spans 传递 context。

将 OpenTelemetry trace APIs 插装到应用程序后,就可以使用预先编译好的OpenTelemetry 库中的 exporters 将 trace 数据发送到观测平台,如 New Relic 或其他后端。

metrics 和 logs 的规范仍在开发阶段,但一旦完成,它们将在实现 OpenTelemetry 的主要目标中发挥重要作用:确保库和框架包含所有内置的遥测数据类型,使开发人员无需进行检测即可提取遥测数据。

OpenTelemetry 架构组件

由于 OpenTelemetry 旨在成为一个为厂商和可观察性后端提供的跨语言框架,因此它非常灵活且可扩展,但同时也很复杂。OpenTelemetry 的默认实现中,其架构可以分为如下三部分:

  1. OpenTelemetry API
  2. OpenTelemetry SDK,包括

    • Tracer pipeline
    • Meter pipeline
    • shared Context layer
  3. Collector

OpenTelemetry架构介绍 - charlieroro - 博客园 - 图1

OpenTelemetry API

应用开发者会使用 Open Telemetry API 对其代码进行插桩,库作者会用它 (在库中) 直接编写桩功能。API 不处理操作问题,也不关心如何将数据发送到厂商后端。

API 分为四个部分:

  1. A Tracer API
  2. A Metrics API
  3. A Context API
  4. 语义规范

OpenTelemetry架构介绍 - charlieroro - 博客园 - 图2

Tracer API

Tracer API 支持生成 spans,可以给 span 分配一个traceId,也可以选择性地加上时间戳。一个 Tracer 会给 spans 打上名称和版本。当查看数据时,名称和版本会与一个 Tracer 关联,通过这种方式可以追踪生成 sapan 的插装库。

Metric API

Metric API提供了多种类型的 Metric instruments(桩功能),如CountersObservers。Counters 允许对度量进行计算,Observers 允许获取离散时间点上的测量值。例如,可以使用 Observers 观察不在 Span 上下文中出现的数值,如当前 CPU 负载或磁盘上空闲的字节数。

Context API

Context API 会在使用相同 “context” 的 spans 和 traces 中添加上下文信息,如W3C Trace Context, Zipkin B3 首部, 或 New Relic distributed tracing 首部。此外该 API 允许跟踪 spans 是如何在一个系统中传递的。当一个 trace 从一个处理传递到下一个处理时会更新上下文信息。Metric instruments 可以访问当前上下文。

语义规范

OpenTelemetry API 包含一组语义规范,该规范包含了命名 spans,属性以及与 spans 相关的错误。通过将该规范编码到 API 接口规范中,OpenTelemetry 项目保证所有的 instrumentation(不论任何语言) 都包含相同的语义信息。对于希望为所有用户提供一致的 APM 体验的厂商来说,该功能非常有价值。

OpenTelemetry SDK

OpenTelemetry SDK 是 OpenTelemetry API 的实现。该 SDK 包含三个部分,与上面的 API 类似:Tracer, 一个 Meter, 和一个 shared Context layer

OpenTelemetry架构介绍 - charlieroro - 博客园 - 图3

理想情况下,SDK 应该满足 99% 的标准使用场景,但如果有必要,可以自定义 SDK。例如,可以在 Tracer pipeline 实现中自定义除核心实现 (如何与共享上下文层交互) 外的其他任何内容,如 Tracer pipeline 使用的采样算法。

Tracer pipeline

OpenTelemetry架构介绍 - charlieroro - 博客园 - 图4

当配置SDK时,需要将一个或多个SpanProcessors与 Tracer pipeline 的实现进行关联。SpanProcessors会查看 spans 的生命周期,然后在合适的时机将 spans 传送到一个SpanExporter。SDK 中内置了一个简单的 SpanProcessor,可以将完成的 spans 直接转发给 exporter 。

SDK 还包含一个批处理实现,按照可配置的间隔分批次转发已完成的 spans。但由于SpanProcessor的实现可以接受插件,因此可以在完成自己的实现后赋予其自定义的行为。例如,如果遥测后端支持观测 “正在进行的”spans,那么可以创建一个 SpanProcessor 实现,将所有 span 状态变更涉及的 spans 转发出去。

Tracer pipeline 的最后是SpanExporter。一个 exporter 的工作很简单:将 OpenTelemetry 的 spans 转换为遥测后端要求的表达格式,然后转发给该后端即可。提供定制化的 SpanExporter 是遥测厂商参与 OpenTelemetry 生态系统的最简单方式。

Meter pipeline

OpenTelemetry架构介绍 - charlieroro - 博客园 - 图5

Meter pipeline

Meter pipeline 要远比 Tracer pipeline 负载,而 metrics 也远比 span 复杂。下面的描述基于 java SDK 实现,可能跨语言会有所不同。

Meter pipeline 会创建和维护多种类型的 metric 工具,包括 Counters 和 Observers。每个工具的实例都需要以某种方式聚合。默认情况下,Counters 通过累加数值进行聚合,而 Observers 通过采集记录到的最后一个数值进行聚合。所有的工具默认都有一个聚合。

(在本文编写之际,metric 工具的自定义聚合配置仍然在起草阶段)。

不同语言的 Meter pipeline 的实现会有所不同,但所有场景下,metric 的聚合结果都会被传递到MetricExporter。与 spans 类似,供应商可以提供自己的 exporter,将由 metric aggregators 生成的聚合数据转换为遥测后端所需的类型。

OpenTelemetry 支持两种类型的 exporter:基于 exporters 的 “push”,即 exporter 按照时间间隔将数据发送到后端;基于 exporters 的 “pull”,即后端按照需要请求数据。New Relic 是一个基于 push 的后端,而 Prometheus 是一个基于 push 的后端。

shared Context layer

shared Context layer 位于 Tracer 和 Meter pipeline 之间,允许在一个执行的 span 的上下文中记录所有非 observer 的 metric。可以使用propagators自定义 Context,在系统内外传递 span 上下文。OpenTelemetry SDK 提供了一个基于 W3C Trace Context 规范的实现,但也可以根据需要来包含 Zipkin B3 propagation 等。

Collector

OpenTelemetry架构介绍 - charlieroro - 博客园 - 图6

下面对 collector 的描述来自官方文档

OpenTelemetry Collector 提供了一种厂商中立的实现,无缝地接收,处理和导出遥测数据。此外,它移除了为支持发送到多个开源或商业后端而使用的开源可观察性数据格式 (如 Jaeger,Prometheus 等) 的运行,操作和维护。

OpenTelemetry collector 可以扩展或嵌入其他应用中。下面应用扩展了 collector:

如果要创建自己的 collector 发行版,可以参见这篇 blog: Building your own OpenTelemetry Collector distribution

如果要构建自己的发行版,可以使用OpenTelemetry Collector Builder
https://www.cnblogs.com/charlieroro/p/13862471.html