设计驱动的可观测性:通过 OpenTelemetry Weaver 实现一致性

为何一致性至关重要:语义约定

您是否经历过……

  • 因指标名称更改而导致现有警报或仪表板中断的部署?
  • 由于团队为同一事物使用不同的指标名称而编写过于复杂的查询?
  • 因缺少或不明确的检测而花费数小时调试生产问题?
  • 团队难以理解未记录或不一致的指标?

如果这些听起来很熟悉,您并不孤单。这些是将遥测视为事后考虑的症状,而不是软件设计中的一个有意识的部分。这就是语义约定的用武之地。

语义约定是遥测数据的规则和标准名称的集合。可以将它们视为指标、跟踪和日志的“语法”,以便每个人和每个事物(包括您的工具)都知道您对 http.request.methoddb.system.namehttp.client.request.duration 的意思。

OpenTelemetry 语义约定是一个庞大、开放的目录,包含 70 多个领域的 900 多个属性和信号,由 9 个特殊兴趣小组维护。这个开放目录确保了

  • 一致性:一个名称,到处一个含义。
  • 互操作性:工具、团队和供应商可以相互理解。
  • 自动化:机器可读的标准支持代码和文档生成、静态和实时合规性检查等。

但维护和演进跨团队和工具的这样一个注册表并不容易。这就是 OTel Weaver 的用武之地。

设计中的可观测性:一种现代工程方法

设计中的可观测性意味着在软件开发生命周期 (SDLC) 的早期就将可观测性集成进来。这通常被称为“可观测性左移”,因为它将可观测性问题移到开发时间表的更早(“左”)阶段——从部署后监控回到设计和开发阶段。

  1. 设定明确目标:预先定义可观测性目标。您需要哪些信号?
  2. 自动化:使用工具根据约定生成代码、文档、测试和模式。
  3. 验证:尽早发现可观测性问题,在 CI/CD 中,而不是在生产环境中。
  4. 迭代:根据实际反馈和不断变化的需求改进您的遥测。

换句话说,将遥测视为公共 API。如果您不想在发布之间破坏应用程序的 API,那么也不要破坏您的遥测。

OTel Weaver:赋能语义约定和设计中的可观测性

OTel Weaver 是开源的 CLI 和自动化平台,可帮助您管理、验证和演进语义约定和可观测性工作流。

Weaver 能为您做什么?

  • 定义和版本化您的语义约定:创建您自己的约定或在 OTel 的基础上构建。为您的团队或社区版本化和共享您的模式。
  • 基于策略的验证:强制执行最佳实践——命名、稳定性、不可变性等。检测破坏性更改并保持质量。您甚至可以定义自己的策略!
  • 实时检测检查:检查您的应用程序的遥测是否与定义的模式和最佳实践匹配。测量检测覆盖率,类似于代码覆盖率,以确保您的单元和集成测试实际运行了所有检测到的代码。再也不会在生产环境中遗漏关键信号。
  • 代码和文档生成:开箱即用地生成多种编程语言的 Markdown 文档和常量。我们还在努力提供更高级的解决方案,以自动生成类型安全的检测助手(Go、Rust 等),从而实现更轻松、更安全的集成。
  • 差异和演进:通过自动差异和升级/降级支持,安全地演进您的遥测模式。

定义:注册表是语义约定的集合,它们是描述指标、日志和跟踪等遥测数据应如何命名和结构的标准化定义。OpenTelemetry 维护官方的语义约定注册表,但团队、项目或供应商可以定义和发布自己的自定义注册表以满足特定需求。

Weaver 目前支持一种基本的**多注册表**形式,允许自定义注册表导入和覆盖另一个注册表(例如,扩展官方 OTel 语义约定)。目前,仅支持两个级别:您的自定义注册表和单个依赖项。这涵盖了许多常见情况,但我们知道还有更多的灵活性和协作潜力。

Weaver 实战:关键命令

开始使用 Weaver 非常简单:它可作为预编译的二进制 CLI(参见发布 页面)和 Docker 镜像提供,可直接集成到任何 CI/CD 管道或本地工作流中。

OTel 语义约定社区如何使用 Weaver

OTel 语义约定社区依赖 Weaver 作为构建、验证和演进官方注册表的主要工具。以下是社区使用的一些命令。

检查官方 OTel 注册表
Weaver 确保注册表的每一项更改都一致、经过验证并遵循核心策略。

weaver registry check -r registry-path

以下列表简要概述了为 OTel 注册表实现的策略。

属性规则命名与结构稳定与演进
注册表外无属性名称必须遵循格式规则禁止删除元素
属性无必需级别ID 必须匹配命名模式禁止降级稳定性
组内无重复属性属性必须完全限定禁止更改类型或单位
属性集必须是不可变的无命名空间冲突定义需要稳定性
稳定组中的实验性属性必须选择加入无常量名称冲突枚举值一旦定义不得更改

生成 Markdown 文档
Weaver 自动生成您在 opentelemetry.io 上看到的、人类可读的文档。

weaver registry update-markdown -r registry-path --target=markdown

为检测助手生成代码
所有支持的 OpenTelemetry SDK 都受益于其原生语言中的自动生成常量和代码,确保没有错别字或不一致。

例如,从 Weaver 为 Go 客户端 SDK 生成的代码可以在此 存储库中找到。使用的 Weaver 命令如下:

weaver registry generate -r registry-path -t templates-root-dir go

同样,为 OpenTelemetry Semantic Conventions for Java 库生成的代码在此 项目中可见。Weaver 提供了一个兼容 Jinja2 的嵌入式模板系统,并拥有大量自定义函数,可促进不同语言的代码生成。

跟踪更改和模式演进
Weaver 跟踪注册表版本之间的差异,以突出显示破坏性更改或改进。

weaver registry diff -r current-version-registry-path --baseline-registry previous-version-registry-path

实时检测检查和覆盖率
用户和维护者可以利用 Weaver 实时检查他们的应用程序是否正确发出符合官方语义约定或自定义注册表(见下文)的遥测。

weaver registry live-check --registry registry-path

此命令会生成一个关于您的应用程序针对注册表发出的信号的合规性报告。

Live-check Report

Weaver live-check 不仅有助于验证您的应用程序与语义约定的合规性,还可以直接在 CI/CD 工作流中应用于您链接到的所有库!除了基本的模式合规性,自定义 Rego 策略还支持特定于组织的**不变量**和**最佳实践**检查。每个属性和信号在接收时都会通过策略引擎。例如,您可以为指标值的范围定义一个策略,或者一个特定属性的字符串值匹配某个正则表达式。策略独立于语义约定注册表,因此您可以根据需要定义应用程序或库特定的检查。

使用 weaver emit 模拟遥测
代码检测和仪表板构建通常在不同时间进行,有时由不同的人完成。这会减慢您的可观测性工作:前端和 SRE 团队在应用程序在暂存或生产环境中发出真实数据之前,无法构建有用的仪表板或警报。Weaver 通过 emit 命令解决了这个先有鸡还是先有蛋的问题。

weaver registry emit --registry registry-path --endpoint https://:4317

此命令生成 OTLP 格式的示例遥测,您可以直接发送到您的收集器、后端或可视化工具。

自定义注册表:定义和检查自己的遥测模式

虽然 Weaver 为核心 OTel 注册表提供支持,但您也可以使用它来定义和管理自己应用程序的遥测模式。这意味着您可以重用和扩展官方约定,同时添加针对您域定制的自定义信号、属性和事件,并且您可以静态和实时地检查您应用程序的遥测是否是最新的和完整的。

注意:我们正在积极努力使自定义注册表更容易使用,提供更好的入门指南、更简单的配置以及更集成的代码生成和文档支持。我们正在寻找这方面的反馈和帮助。

为了帮助您入门,这里有一个使用“待办事项”应用程序的自定义注册表的快速示例。首先,创建一个 registry_manifest.yaml 文件来指定您的注册表。

name: todo_app
description: OTel signals for my native ToDo app
semconv_version: 0.1.0
dependencies:
  - name: otel
    registry_path: https://github.com/open-telemetry/semantic-conventions/archive/refs/tags/v1.34.0.zip[model]

导入并扩展现有约定,并定义您自己的信号和属性

imports: # import signals from the dependency registry, i.e. OTel semantic conventions
  metrics:
    - db.client.* # import all metrics with names starting with `db.client.`
  events:
    - app.*
    - exception # import the event named `exception`
  entities:
    - host
    - host.cpu

groups:
  - id: metric.todo.completion_time
    type: metric
    brief: Measures the time between the creation and completion of a ToDo item.
    metric_name: todo.completion_time
    instrument: histogram
    unit: s
    attributes:
      - id: todo.priority # define your own attribute
        type: string
        brief: The priority of the ToDo item.
      - id: todo.category
        type: string
        brief: The category of the ToDo item.
      - ref: user.id # reference an existing attribute from the imported registry
        requirement_level: required # refine the requirement level
    entity_associations:
      - os.name
      - os.version
  - id: event.todo.deleted
    type: event
    brief: Emitted whenever a ToDo item is deleted by the user.
    attributes:
      - id: delete.reason
        type: string
        brief: The reason for deletion.
      - id: todo.priority
        type: string
        brief: The priority of the deleted ToDo item.
      - ref: user.id
        requirement_level: required
    entity_associations:
      - os.name
      - os.version

Weaver 的未来展望?

我们正在努力使 Weaver 更加强大、灵活且易于采用。

  • 更好的文档和更轻松的入门:预计会有更多实际示例、分步指南,并更加注重易用性。我们还在为自定义注册表创建定制的模板和策略。
  • 多注册表支持:增强对组合、分层和管理多个语义约定注册表的支持,包括冲突解决。这将使库作者能够轻松发布和共享他们自己的注册表。
  • Schema v2:一套新命令,用于打包和发布已解析的、自包含的应用程序和库的遥测模式。这项标准化工作(遥测模式 v2)将使整个可观测性生态系统更容易在语义约定和 Weaver 的基础上进行构建。
  • 类型安全的语义约定 API 生成:自动生成强类型检测库,以减少错误并加速开发。一个 Go Prometheus 的类型安全客户端 API 示例已在 promconv 中进行。一个使用 Weaver 的更通用的 Go 类型安全客户端 API 也在 MrAlias/semconv-go 中开发。

敬请关注,下一代语义约定管理即将到来,Weaver 将为整个社区提供无缝体验。

参与进来!

Weaver 被设计成高度可扩展和可配置的。您可以使用 Weaver 内置的引擎创建自定义注册表、用 Rego 编写策略以及用 Jinja2 设计模板。如果您想开始或有疑问,请加入我们在 Slack 上的 #otel-weaver 频道。我们很乐意提供帮助,并始终对您的想法感兴趣!

可观测性不仅仅是一种工具,更是一种实践。通过 OpenTelemetry Weaver 驱动的清晰、一致且自动化的工作流,将其设计到您的系统中。

最后修改于 2025 年 7 月 2 日: [blog] OTEL Weaver (#7231) (881be590)