OpenTelemetry Python入门指南

2025年3月3日 | 阅读7分钟

引言

云原生应用程序已成为许多复杂应用程序的常态,要保持从应用程序到其所依赖系统的可见性,需要持续监控。随着系统的增长及其在层级结构中规模的不断扩大,诸如日志记录和一些基础指标之类的简单直接的方法似乎变得不足甚至不够,无法满足在识别问题、改进性能或保证可靠性方面至关重要的分析任务。可观测性正是我们所处的领域,而可用于实现可观测性的最大资产之一是 OpenTelemetry

OpenTelemetry (OTel) 是一个开源的、以供应商为中心的可观测性框架,旨在收集和转发分布式系统中的跟踪、指标或日志数据。该概念为开发人员提供了一种标准的从各种服务编译和导出数据的方法,使他们能够更好地理解自己的应用程序。OpenTelemetry 为任何架构 - 从单个单体应用程序到分布式微服务系统 - 提供了跟踪请求、分析系统性能和识别问题的工具。

OpenTelemetry 的关键概念

因此,在探索 OpenTelemetry 在 Python 上下文中的具体细节之前,有必要简要了解一下 OpenTelemetry 的定义性概念。它们提供了用于遥测数据收集、处理和导出机制的组件,以帮助开发人员分析他们的应用程序。

跟踪和跨度

跟踪: 跟踪代表请求、事务或任何其他用户活动的整个路径或生命周期,因为它涵盖了多个服务或系统。事实上,跟踪或多或少是一组操作或事件,它们描绘了过程的高级视图。例如,当用户想要向 Web 服务发出请求时,该请求将需要跨越不同的微服务或数据库中的多个操作。此过程中的每个步骤或操作都是跟踪的一部分。

跨度: 跨度用于表示在跟踪中发生的任何一个单独的操作。跨度包含重要方面,例如操作名称,通常伴随着开始时间、停止时间以及与特定操作相关的任何元数据或属性。跨度是跟踪的原子部分,可以是数据库查询请求或完成用户请求等。跨度是分层的,一个跨度可以包含另一个跨度,这使得它们具有父/子关系。

指标

KPI 是系统性能的评估,与其它形式的系统测量相比,它们可以被视为更定量的。它们提供了对系统行为和健康的通用增值理解,因为它们会随着时间收集数据。指标的例子包括

  • 延迟:请求完成所需的时间。
  • 请求速率:不言而喻:它保存了系统每秒需要处理的请求数。
  • 错误率:失败的请求数量,或者软件未能完成预期操作的次数。
  • CPU 或内存使用情况:系统资源被消耗在哪里、多少以及由谁消耗。

日志

日志是系统中发生的事件的时间戳叙述性记录。它们提供特定时间段的完全详细但有上下文的信息,对于调试和熟悉系统非常有价值。与大多数其他日志框架一样,每个日志条目都包含一个时间戳和一个消息,并且可能包含诸如严重性级别(例如,DEBUG、INFO、WARNING 和 ERROR)之类的可选参数。

上下文传播

上下文传播是 OpenTelemetry 将跟踪、指标和日志跨服务连接的方式。每当一个请求或事务从一个服务传递到另一个服务时(例如,从 Web 服务器到数据库),上下文也会随之传递,以便 OpenTelemetry 能够捕获分布式基础设施中该请求的所有方面。上下文还包括标识信息,例如跟踪 ID 和跨度 ID,它们在任何给定时间都与每个请求或操作一起传递。这有助于确保所有跨度都与正确的跟踪相关联,尤其是在后者可能已在不同的服务或系统中开发的情况下。

OpenTelemetry 原则

以下是 OpenTelemetry 在设计和使用中采用的一些原则,以确保它能在不同的平台、语言和服务上和谐工作。现在,让我们看看构成 OpenTelemetry 作为可靠的可观测性解决方案基础的主要原则。

  1. 供应商中立性
    OpenTelemetry 的本质是允许用户不依赖于特定可观测性工具供应商,因为它不受特定供应商的限制。因此,如果您的目标是将遥测数据转发到 Prometheus、Jaeger、Datadog、New Relic 或任何其他服务,OpenTelemetry 供应商都提供多种导出器解决方案。这些选择使 OpenTelemetry 具有面向未来性,用户可以在不更改代码库的情况下切换后端。
  2. 标准化
    作为主要目标之一,OpenTelemetry 旨在标准化获取遥测信息的过程。通过这种方式,OpenTelemetry 提供的 API、SDK 和数据格式在各种编程语言中是一致的,这使得从不同的服务和平台收集数据并进行聚合和分析成为可能。通过这种方式,W3C Trace Context 等标准,它管理跟踪和跨度的传播,保证了跨服务和库的跨度和跟踪的互操作性。
  3. 统一数据收集
    OpenTelemetry 的关键卖点是它能够收集三种形式的可观测性数据,即跟踪、指标和日志。OpenTelemetry 将跟踪、日志记录和指标这三个不同类别合并为一个。这种统一使得分布式系统的监控更加容易,并减少了管理每个遥测代理的需求。
  4. 自动插桩
    可以区分 OpenTelemetry 概念的最后一个原则是自动生成插桩库和框架。这意味着开发人员可以开启跟踪、指标和日志记录器,而无需在实现阶段在代码中实现它们。OpenTelemetry 为许多框架(如 Flask 和 Django)、HTTP 客户端(如 requests)以及数据库客户端等提供开箱即用的插桩。

在 Python 中设置 OpenTelemetry

步骤 1:安装必需的包

您需要使用 pip 安装 OpenTelemetry 包。根据您的可观测性目标,以下是常用的入门包:

其他可选包包括插桩库、指标以及特定的导出器,如 Jaeger 或 Zipkin,具体取决于您想要使用的后端。

步骤 2:初始化追踪器和导出器

要捕获跟踪数据并将其通过另一个后端发送,您需要创建一个追踪器和一个导出器。

这是一个使用 OTLP(OpenTelemetry Protocol)作为导出器的基本示例。

在此示例中,OtlpSpanExporter 将跟踪数据发送到运行在 localhost:4317 上的端点。您可以根据您的设置配置端点。

步骤 3:启动跟踪

之后,您可以继续捕获跨度,为此,请创建追踪器和导出器。跨度是一个逻辑工作单元,它可以表示跟踪中的请求/响应周期。以下代码演示了如何创建和结束一个跨度:

输出

 
Hello from OpenTelemetry!   

步骤 4:插桩库

要自动跟踪第三方库,如 Flask、Django 或 HTTP 客户端,您可以使用 OpenTelemetry 的插桩库:

然后,在您的代码中插桩该库:

输出

 
Status Code: 200   

例如,这允许 OpenTelemetry 捕获和跟踪使用 requests 库发出的出站 HTTP 请求

步骤 5:查看遥测数据

要可视化您的跟踪数据,您需要设置一个后端,如 Jaeger 或 Zipkin。对于 Jaeger,您可以使用 Docker 来启动一个本地 Jaeger 实例:

然后,在 Python 中配置 Jaeger 导出器:

并按如下方式修改您的代码:

一切设置完成后,您的跟踪数据将在 Jaeger UI 中可见,地址为 https://:16686。