OpenTelemetry 简称为 OTel, 是一个供应商中立的开源遥测框架, 用于检测、生成、收集和导出遥测数据, 例如跟踪、度量、日志, 以帮助分析软件的性能和行为。旨在提供可观测性领域的标准化方案, 解决观测数据的数据模型、采集、处理、导出等的标准化问题。
OpenTelemetry 是一组 API、SDK、工具和集成, 旨在创建和管理遥测数据, 例如 Trace、Metrics 和 Logs。该项目提供了一个与供应商无关的实现, 可以将其配置为将遥测数据发送到您选择的后端。它支持各种流行的开源项目, 包括 Jaeger 和 Prometheus。 主要解决的问题是观测性领域模型的统一, 观测性数据收集的统一, 观测性数据输出的统一。这些统一性主要体现在 API 规范, SDK 实现规范, 接口规范等。OpenTelemetry 不会负责观测数据的存储, 需要存储这些观测数据的 backend。OpenTelemetry 定义数据输出的规范, 由各大厂商自行完成数据的持久化。
OpenTelemetry 是一个 CNCF 孵化项目, 由 OpenTracing 和 OpenCensus 项目合并而成。
以 Dapper 的定义作为基准, 一个标准的分布式 Trace 示例如下图所示。一个 Trace 是由 Span 构成的有向无环图 (DAG), Span 是一个最小粒度的调用, 既可以指代一个程序块执行, 也可以指代一次 HTTP 等应用协议的远程调用。
在云原生技术堆栈中, 分布式和多语言架构是常态。分布式架构引入了各种运营挑战, 包括如何快速解决可用性和性能问题。这些挑战导致了可观察性的兴起。这就需要遥测数据来支持可观测性产品。传统上, 遥测数据由开源项目或商业供应商提供, 但是由于缺乏标准化, 最终结果是缺乏数据可移植性, 增加用户维护仪表的负担。OpenTelemetry 项目通过提供与供应商无关的单一解决方案来解决这些问题。该项目得到了云提供商、供应商和最终用户的广泛行业支持和采用。它提供以下能力:
Opentelemetry 采集的信息包括可观测的三支柱 Tracing、Metrics、Logging, 其次还包括 Baggage。Baggage 类似与 OpenTrace 中 Baggage, Opentelemetry 将它从 trace 中独立了出来。目前状态: Traces 和 Baggage 已进入稳定状态, Metrics 也大部分完成, 而下一将在 Logs 上逐步发力。值得一提的是 Metrics 中的 Exemplars 的情况, 目前在 Java SDK 中已经实现, 而在 Go SDK 中还未支持。
Tracing
OpenTelemetry 追踪系统是基于 OpenTracing 和 OpenCensus。这两个系统, 以及流行的 Zipkin 和 Jaeger 项目, 都是基于谷歌开发的 Dapper 追踪系统。OpenTelemetry 可以将这些项目兼容到一个系统中。
Metrics
度量指标 (metric) 是一个很大的话题, 包含各种各样的方法和实现。OpenTelemetry 度量信号可以与 Prometheus 和 StatsD 完全兼容。
Logging
OpenTelemetry 结合了高度结构化的日志 API 和高速日志处理系统。现有的日志 API 可以连接到 OpenTelemetry, 避免了对应用程序的重新测量。 目前这部分尚发展阶段
Baggage
OpenTelemetry Baggage 是一个简单但通用的键值系统。一旦数据被添加为 Baggage, 它就可以被所有下游服务访问。这允许有用的信息, 如账户和项目 ID, 在事务的后期变得可用, 而不需要从数据库中重新获取它们。例如, 一个使用项目 ID 作为索引的前端服务可以将其作为 Baggage 添加, 允许后端服务也通过项目 ID 对其跨度和指标进行索引。这信息添加到了 http header 中, 进行上下文传递, 因此每增加一个项目都必须被编码为一个头, 每增加一个项目都会增加事务中每一个后续网络请求的大小, 因此不建议在将大量的非重要的信息添加到 Baggage 中。
Specification: 是定义了 API/SDK 及数据模型, 所有包含第三方实现的都需要遵循 spec 定义的规范。
Semantic Conventions: OpenTelemetry 项目保证所有的 instrumentation(不论任何语言)都包含相同的语义信息
Resource: resource 附加于某个 process 产生的所有 trace 的键值对, 在初始化阶段指定并传递到 collector 中
Baggage: 为添加在 metrics、log、traces 中的注解信息, 键值对需要唯一, 无法更改
Propagators: 传播器, 比如在多进程的调用中, 开启传播器用于跨服务传播 spanContext。
Attributes: 其实就是 tag, 可以给 span 添加 metadata 数据, SetAttributes 属性可以多次添加, 不存在就添加, 存在就覆盖
Events: 类似于日志, 比如在 trace 中嵌入请求体跟响应体。
Collector: 它负责遥测数据源的接收、处理和导出三部分, 提供了与供应商无关的实现。
Data sources: OpenTelemetry 提供的数据源, 目前包含:
属性: 从数据的角度看属性是一个键值对, 本质上属性描述了空间信息, 方便从空间上做数据关联。OTel 定义了很多通用的属性, 如果定义不明确或数据不一致时, 是没法自动关联分析的。下面是 Otel 定义的 K8S 的 Pod 属性:
这部分更多的是协议层的内容, 不涉及具体实现, 定义跨语言的规范, 保证了数据格式的统一、接口的统一、配置、数据处理和导出的统一。该部分主要包括以下部分:
OpenTelemetry Collector 提供了一个与供应商无关的实现, 用于接收、处理和导出遥测数据。它消除了运行、操作和维护多个代理/收集器的需要。这与改进的可扩展性一起工作, 并支持将开源可观察性数据格式(例如 Jaeger、Prometheus、Fluent Bit 等)发送到一个或多个开源或商业后端。Collector 的能力有赖于各个厂商的贡献: 实现各厂商系统的数据采集和数据导入。它有两种部署方式:
其框架如下图所示:
收集器可以被配置为从各种来源接收各种格式的遥测数据。目前, 收集器支持超过四十种不同类型的接收器! 一旦接收到, 所有这些数据都会被转换为 OTLP。OpenTelemetry 同时支持基于推和拉的接收器。
一旦接收器将遥测数据转换为 OTLP, 就会有各种处理器可用。处理器可以被配置为执行各种任务。
一旦遥测数据被处理, 它可以被输出到各种后端。在未来, 我们希望越来越多的后端能够原生支持 OTLP。同时, OTLP 可以被转换为目前流行的系统所支持的许多格式。请查看 OpenTelemetry 供应商页面, 找到目前支持 OpenTelemetry 的商业供应商列表。
这里于 Opentelemetry 的官方文档略有不同, 其将其分为自动化仪表和 SDK, 这里为更好的总结将其归为客户端这一类别中, 这一部分是 Opentelemetry 在各种语言中的客户端的具体实现, 实现各种数据的采集。客户端架构如下图所示
OpenTelemetry 客户端由 4 种类型的包组成: API 包、SDK 包、语义约定包和插件包。API 和 SDK 被分成多个包, 根据信号类型分为: api-trace、api-metric、sdk-trace、sdk-metric。在自己的程序引入 OpenTelemetry 检测的库、框架和应用程序仅依赖于 API 包。这些第三方库的开发人员将调用 API 以生成遥测数据。使用通过 OpenTelemetry API 检测的第三方库的应用程序控制是否安装 SDK 并生成遥测数据, 未安装 SDK 时, API 调用应该是空实现的, 这会产生最小的开销。为了生成遥测数据, 应用程序必须依赖 OpenTelemetry SDK。应用程序还必须配置导出器和其他插件, 以便可以正确生成遥测数据并将其交付给他们选择的分析工具。如何启用和配置插件的详细信息是特定于语言的。
OpenTelemetry 支持大量 san’fan 组件, 这些组件可以从流行的库和支持语言的框架中生成相关的遥测数据。例如, HTTP, gRPC 的监测数据。使用自动检测可能因语言而异, 一些语言需要引入 SDK, 添加特定框架的 contrib 实现库, 而类似 Python、Ruby 和 NodeJS 解释性语言可以直接引入外部模块进行检测。