初探 OpenTelemetry

OpenTelemetry是一个规范和工具集合,用于生成、收集和导出遥测数据,包括Metrics、Traces和Logs,以提升软件性能分析。它是OpenTracing和OpenCensus的合并结果,提供与厂商无关的API和SDK,支持多种后端服务。OpenTelemetry旨在通过标准化解决数据不兼容问题,提高数据可移植性,并简化跨语言和平台的互操作性。
摘要由CSDN通过智能技术生成

什么是 OpenTelemetry

OpenTelemetry 由 OpenTracing 和 OpenCensus 项目合并而成,是一组规范、工具、API 和 SDK 的集合。使用它来检测、生成、收集和导出遥测数据(Metrics、Logs 和 Traces),以帮助运维开发人员分析软件的性能和行为。为众多开发人员带来 MetricsTracesLogs 的统一标准,三者都有相同的元数据结构,可以轻松实现互相关联。

OpenTelemetry 是一个CNCF 孵化项目。OpenTelemetry 与厂商、平台无关,不提供与可观测性相关的后端服务。可根据用户需求将可观测类数据导出到存储、查询、可视化等不同后端,如 Prometheus、Jaeger 、云厂商服务中。

OpenTelemetry 的诞生背景

为了使系统可观测,必须对其进行仪器化。也就是说,代码必须发出tracesmetricslogs。然后,检测的数据必须发送到 Observability 后端。那里有许多可观察性后端,从自托管开源工具(例如 JaegerZipkin)到商业 SaaS 产品。

在过去,检测代码的方式会有所不同,因为每个 Observability 后端都有自己的检测库和代理,用于向工具发送数据。

这意味着没有标准化的数据格式可以将数据发送到 Observability 后端。此外,如果一家公司选择切换 Observability 后端,这意味着他们将不得不重新编写代码并配置新的代理,以便能够将遥测数据发送到所选的新工具。

由于缺乏标准化,最终结果是缺乏数据可移植性,并且给用户带来了维护仪器库的负担。

意识到标准化的必要性,云社区走到了一起,两个开源项目诞生了:OpenTracing云原生计算基金会 (CNCF)项目)和 OpenCensusGoogle 开源社区项目)。

  • OpenTracing 提供了一个供应商中立 API,用于将遥测数据发送到 Observability 后端;然而,它依赖于开发人员实现他们自己的库来满足规范。

  • OpenCensus 提供了一组特定于语言的库,开发人员可以使用这些库来检测他们的代码,并将其发送到任何一个受支持的后端。

为了拥有一个单一的标准,OpenCensus 和 OpenTracing 于2019年5月合并成立了 OpenTelemetry(简称OTel)。作为一个 CNCF 孵化项目,OpenTelemetry 两全其美。

OTel 的目标是提供一套标准化的、与供应商无关的 SDK、API 和工具,用于接收、转换数据并将数据发送到Observability 后端(即开源或商业供应商)。

OpenTelemetry 的优势

  1. 打破各个厂商 Lock-On 隐患

    OpenTelemetry 旨在通过提供标准化 instrumentation 框架打破各个厂商不兼容的格局,作为一个可插拔的服务,可以轻松添加常见的技术协议与格式,让服务选择更自由。

  2. 规范的指定和协议的统一

    OpenTelemetry 采用基于标准的实现方法。对标准的关注对于 OpenTelemetry 来说尤其重要,因为需要追踪跨语言的互操作性。许多语言都带有类型定义,可以在实现中使用,例如用于创建可重用组件的接口。包括可观测客户端内部实现所需要的规范,以及可观测客户端与外部通信所需实现的协议规范。具体包括:

    • API:定义用于生成和关联 Metrics、Traces、Logs 数据的类型和操作
    • SDK:定义特定于语言的 API 实现的需求。这里还定义了配置、数据处理和导出概念。
    • Data:定义 OpenTelemetry 协议(OTLP)和供应商不可知的语义约定,遥测后端可以为其提供支持。虽然在 Opentelemetry中组件支持了 Zipkin v2 或 Jaeger Thrift 协议格式的实现,但都以第三方贡献库形式提供。只有 OTLP 是 Opentelemetry 官方原生支持的格式。

    在这里插入图片描述

  3. 多语言 SDK 的实现和集成

    OpenTelemetry 为每个常见语言都实现了对应 SDK,将导出器与 API 结合在一起。SDK 是具体的、可执行的 API 实现。包含 C++、.NET、Erlang/Elixir、Go、Java、JavaScript、PHP、Python、Ruby、Rust、Swift。

    OpenTelemetry SDK 通过使用 OpenTelemetry API 使用选择的语言生成可观测数据,并将该数据导出到后端。并允许为公共库或框架增强。用户可以使用 SDK 进行代码自动注入和手动埋点,同时对其他三方库(Log4j、LogBack 等)集成支持;这些包一般都是根据 opentelemetry-specification 里面的规范与定义,结合语言自身的特点去实现在客户端采集可观测数据的基本能力。如元数据在服务间、进程间的传递,Trace 添加监测与数据导出,Metrics 指标的创建、使用及数据导出等。

  4. 数据收集系统的实现

    在 Tracing 实践中有个基本原则,可观测数据收集过程需要与业务逻辑处理正交。尽量减少可观测客户端对原有业务逻辑的影响,Collector 是基于这个原则。OpenTelemetry 基于 OpenCensus Service 的收集系统,包括 Agent 和 Collector。Collector 涵盖采集(Collect)、转换(Transform)和导出(Export)可观测数据的功能,支持以多种格式(例如 OTLP、Jaeger、Prometheus 等)接收可观测数据,并将数据发送到一个或多个后端。它还支持在输出可观测数据之前,对其进行处理和过滤。Collector contrib 软件包支持更多数据格式和后端。

    从架构层面来说,Collector 有两种模式。一种是把 Collector 部署在应用相同的主机内(如Kubernetes 的 DaemonSet),或者部署在应用相同的 Pod 里面(如Kubernetes 中的 Sidecar),应用采集到的遥测数据,直接通过回环网络传递给 Collector。这种模式统称为 Agent 模式。另一种模式是把 Collector 当作一个独立的中间件,应用把采集到的遥测数据往这个中间件里面传递。这种模式称之为 Gateway 模式。两种模式既可以单独使用,也可以组合使用,只需要数据出口的数据协议格式跟数据入口的数据协议格式保持一致。

  5. 自动代码注入技术

    OpenTelemetry 也开始提供可以自动代码注入的实现,目前已经支持 Java 各类主流框架的自动注入。

  6. 云原生架构

    OpenTelemetry 设计之初就已经考虑了云原生的特性,并且还提供了 Kubernetes Operator 用于快速部署使用。

OpenTelemetry 支持的数据类型

Traces

Traces 指单个请求的追踪,请求可以由应用程序发起,也可以由用户发起。分布式 Traces 是跨网络,跨应用的追踪形式。每个工作单元在 Traces 中被称为 Span,一个 Trace 由一个树形的 Span 组成。Span 表示经过应用程序所设计的服务或组件所做工作的对象,Span 还提供了可用于调试可用性和性能问题的请求、错误和持续时间的 Metrics。Span 包含了一个 Span 上下文,它是一组全局唯一标识符,表示每个 Span 所属的唯一请求。通常我们称之为 TraceID。

Spans

一个 Span 表示一个工作单位或操作单位。Spans 是 Traces 的组成部分。在 OpenTelemetry 中,它们包括以下信息:

  • Name:Span 的名称
  • Parent span ID (empty for root spans):父级 Span
  • Start and End Timestamps:Span 开始和结束的时间戳
  • Span Context
  • Attributes
  • Span Events
  • Span Links
  • Span Status

Span Context

Span Context 是每个跨度上的一个不可变对象,包含以下内容:

  • Trace ID:表示 Span 所属的 Trace
  • Span ID:表示 Span 的 ID
  • Trace Flags:一种包含有关 Trace 信息的二进制编码
  • Trace State:键值对的列表,可以携带 vendor-specific trace 信息

Attributes

Attributes 是包含元数据的键值对,可以使用这些元数据对 Span 进行注释,以携带有关其正在跟踪的操作的信息。

例如,如果 Span tracks 在电子商务系统中将商品添加到用户购物车的操作,则可以捕获用户的ID、要添加到购物车的商品的ID和购物车ID。

属性具有以下每个语言 SDK 实现的规则:

  • 键必须是非空字符串值
  • 值必须是非空字符串、布尔值、浮点值、整数或这些值的数组

尽可能使用语义属性命名:语义属性

Span Event

Span Event 可以被认为是 Span 上的结构化日志消息(或注释),通常用于表示 Span 持续时间内有意义的单一时间点。

例如,考虑 Web 浏览器中的两种情况:

  1. 跟踪页面加载
  2. 表示页面何时变为交互式

Span 最适用于第一种情况,因为它是一个有开始和结束的操作。Span Event 最适合用于跟踪第二种情况,因为它代表一个有意义的、单一的时间点。

Span Links

Span Links 可以将一个 Span 与一个或多个 Span 相关联,从而暗示因果关系。例如,假设我们有一个分布式系统,其中一些操作由一个 trace 跟踪。

作为对其中一些操作的响应,额外的操作排队等待执行,但其执行是异步的。我们也可以通过 trace 来跟踪这一后续操作。

我们希望将后续操作的 trace 与第一个 trace 相关联,但无法预测后续操作何时开始。我们需要将这两个 traces 关联起来,所以我们将使用 Span Links。

可以将第一个 trace 的最后一个 trace link 到第二个 trace 的第一个 Span。现在,它们是因果关联的。

Span Status

Span Status 将附加到 Span。通常,当应用程序代码中存在已知错误(例如异常)时,将设置 Span Status。 Span Status 将标记为以下值之一:

  • Unset
  • Ok
  • Error

处理异常时,可以将 Span 状态设置为 Error。否则,Span 状态处于 Unset 状态。通过将 Span Status 设置为Unset,进程 Span 的后端现在可以分配最终状态。

Span Kind

创建 Span 时,它是Client, Server, Internal, Producer, 或 Consumer之一。这种 span 类型为跟踪后端提供了一个关于应该如何组装跟踪的提示。根据 OpenTelemetry 规范,服务器 Span 的父 Span 通常是远程客户端 Span,客户端 Span 的子 Span 通常是服务器 Span。类似地,消费者 Span 的父 Span 代始终是生产者,生产者 Span 的子代始终是消费者。如果未提供,则假定 Span Kind 为Internal

常见的 SpanKind

Metrics

Metric 是关于一个服务的度量,在运行时捕获。从逻辑上讲,捕获其中一个量度的时刻称为 Metric event,它不仅包含量度本身,还包括获取它的时间和相关元数据。应用和请求指标是可用性和性能的重要指标。自定义指标可以深入了解可用性如何影响用户体验和业务。自定义 Metrics 可以深入理解可用性 Metrics 是如何影响用户体验或业务的。

OpenTelemetry 目前定义了六种 Metrics 工具,它们可以通过 OpenTelemetry API 创建:

  • Counter:一个随着时间积累的值——你可以把它想象成汽车上的里程表;它只会上升。
  • **Asynchronous Counter **:与 Counter 相同,但每次导出都会收集一次。如果您无权访问连续增量,但只能访问聚合值,则可以使用。
  • UpDownCounter:一个随着时间的推移而累积的值,但也可能再次下降。例如,队列长度会随着队列中工作项的数量而增加和减少。
  • Asynchronous UpDownCounter :与UpDownCounter相同,但为每次导出收集一次。如果您无权访问连续更改,但只能访问聚合值(例如,当前队列大小),则可以使用。
  • (Asynchronous) Gauge:测量读取时的电流值。一个例子是车辆中的燃油表。Gauge 总是异步的。
  • HistogramHistogram 是客户端值的聚合,例如请求延迟。如果你有很多值,并且对每个单独的值都不感兴趣,而是对这些值的统计数据感兴趣(例如,有多少请求需要小于1?),那么直方图可能是一个不错的选择

Logs

日志是带有时间戳的文本记录,可以是带有元数据结构化的,也可以是非结构化的。虽然每个日志都是独立数据源,但可以附加到 Trace 的 Span 中。日常使用调用时,在进行节点分析时出伴随着也可看到日志。

在 OpenTelemetry 中,任何不属于分布式 Trace 或 Metrics 的数据都是日志。日志通常用于确定问题根因,通常包含有关谁更改了内容以及更改结果的信息。

Baggage

在 OpenTelemetry 中,Baggage 是 Span 之间传递的上下文信息。它是一个键值存储,与 Trace 中的 Span Context 一起驻留,使值可用于在该 Trace 中创建的任何 Span 。

例如,假设您想CustomerId在 Trace 中的每个 Span上都有一个属性,这涉及多个服务;但是,CustomerId仅在一项特定服务中可用。为实现您的目标,您可以使用 OpenTelemetry Baggage 在整个系统中传播此值。

在这里插入图片描述

OTel Baggage 为何存在?

Baggage 提供了一种统一的方式来存储和传播轨迹和其他信号中的信息。例如,你可能希望将应用程序中的信息附加到一个 Span,并在很久以后检索该信息,然后再将其用于另一个 Span。然而,opentelemetry 中的 Span 在创建后是不可变的,并且可以在你以后需要有关它们的信息之前导出。Baggage 允许你通过提供存储和检索信息的位置来解决这个问题。

OTel Baggage 应该用来做什么?

OTel Baggage 应用于你可以接受的数据,这些数据可能会暴露给任何检查你网络流量的人。这是因为它与当前上下文一起存储在 HTTP 头中。如果你的相关网络流量完全在你自己的网络内,则此警告可能不适用。

常见的用例包括只有在堆栈中才能访问的信息。例如,这可以包括帐户标识、用户标识、产品标识和原始IP。通过将它们向下传递到堆栈,可以将它们添加到下游服务中的 Span 中,从而在 Observability 后端搜索时更容易进行筛选。

没有内置的完整性检查来确保 Baggage 是你的,所以在取回时要小心。

在这里插入图片描述

Baggage 和 Span 属性不一样

关于 Baggage 需要注意的一件重要事情是它不是 Span Attributes的子集。当你添加一些东西作为 Baggage 时,它不会自动结束在子系统 Span 的属性上。你必须明确地从 Baggage 中取出一些东西并将其附加为属性。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值