遥测模式
状态: 稳定
动机
遥测来源(如已仪器化的应用程序)和遥测的消费者(如可观察性后端)有时会对发出的遥测数据做出隐式假设。它们假设遥测数据将包含某些属性,或者具有特定的数据形状和组成(在本文档中,这被称为“遥测模式”)。
这使得在不破坏消费者的情况下更改发出遥测数据的组成变得困难或不可能。例如,更改仪器库创建的 span 的属性名称可能会破坏后端,如果后端期望通过名称查找该属性。
语义约定是此问题的重要组成部分。这些约定定义了 span 属性、指标名称和其他字段使用的名称和值。如果更改了语义约定,则需要相应地更改现有实现(遥测来源或消费者)。此外,为了使情况变得更糟,协同工作且依赖于已更改语义约定的遥测来源和遥测消费者的实现需要同时更改,否则这些实现将不再能正确协同工作。
本质上,存在三个参与者之间的耦合:1)OpenTelemetry 语义约定,2)遥测来源,3)遥测消费者。这种耦合阻碍了这三方独立演进。
我们认识到以下需求:
OpenTelemetry 语义约定需要随着时间的推移而演进。当最初定义约定后,可能会出现错误,并且我们可能希望随着时间的推移修复这些错误。我们还可能希望更改约定,以便随着对属性分类法的理解的提高,将属性重新分组到不同的命名空间中。
遥测来源可能希望随着时间的推移更改其发出的遥测数据的模式。这可能是因为,例如,语义约定发生了演变,我们希望我们的遥测数据与新引入的约定匹配。
在一个可观察性系统中,可能同时存在产生符合不同遥测模式数据的遥测来源,因为不同的来源以不同的速度演进,并且由不同的实体实现和控制。
遥测消费者需要了解特定遥测数据符合哪种模式。消费者还需要一种方法来解释使用不同遥测模式的遥测数据。
在 OTEP0152 中提出的并被接受的遥测模式解决了这些需求。
模式如何工作
我们相信,上述三个参与者能够随着时间的推移独立演进,同时持续保留正确协同工作的能力。
遥测模式是实现此目的的关键。以下是模式工作方式的摘要:
OpenTelemetry 定义了一个用于定义遥测模式的 文件格式。
遥测模式是版本化的。随着时间的推移,模式可能会演进,遥测来源可能会发出符合新版本模式的数据。
遥测模式明确定义了在可能的情况下,将遥测数据在不同模式版本之间进行转换所需的转换。当转换不可能时,这构成了版本之间的破坏性更改。
遥测模式由模式 URL 标识,每个模式版本都有唯一的 URL。
遥测来源(例如,仪器库)将在发出的遥测数据中包含模式 URL。
遥测消费者将关注接收到的遥测数据的模式。如果需要,遥测消费者可能会将遥测数据从接收到的模式版本转换为使用点(例如,仪表板可能会定义它期望的模式版本)所期望的目标模式版本。
OpenTelemetry 在规范中发布遥测模式。该模式包含语义约定经历的转换列表。该模式应可通过一个众所周知的 URL 进行访问、引用和下载:
/schemas/<version>(其中<version>匹配规范版本号)。OpenTelemetry 仪器库在所有发出的遥测数据中都包含 OpenTelemetry 模式 URL。这目前仍在进行中,这是 Go SDK 资源检测器中的一个示例。
OTLP 允许在发出的遥测数据中包含模式 URL。
建议第三方库、仪器或应用程序定义和发布自己的遥测模式(如果它与 OpenTelemetry 模式完全不同,或者使用 OpenTelemetry 模式),并在发出的遥测数据中包含模式 URL。
范围外的内容
模式的概念并不试图完全描述遥测数据的形状。例如,模式不定义属性的所有可能有效值或指标的预期数据类型等。这不是目标。我们的目标严格定义为仅解决以下问题:允许 OpenTelemetry 语义约定随时间演进。因此,本文档关注的是模式的*更改*,而不是模式的*完整状态*。尽管如此,我们并不排除这一点:模式文件格式是可扩展的,并且将来可能允许定义模式的完整状态。
我们故意将模式的转换类型限制在处理我们认为 OpenTelemetry 语义约定在不久的将来将需要的最常见更改所必需的最低限度。将来可能会提出更多类型的转换。此提案不试图支持一套全面的可能转换类型,以处理我们可以想象的所有可能的模式更改。那将过于复杂,而且极有可能多余。任何新的转换类型在有证据表明它们对 OpenTelemetry 的演进是必要时,都*必须*在将来提出并添加到模式文件格式中。
用例
本节展示了遥测模式的几个有趣的用例(其他用例也是可能的,这不是一个详尽的列表)。
完全感知模式
这是一个关于感知模式的可观察性系统的示例:

让我们仔细看看遥测数据发出、传输和存储时遥测来源和后端对之间的交互。

在此示例中,遥测来源生成符合 OpenTelemetry 模式 1.2.0 版本的 span,其中使用“deployment.environment”属性来记录 span 来自生产环境。
遥测消费者希望将遥测数据存储在 OpenTelemetry 模式 1.1.0 版本中。模式转换器比较接收到的 span 中的 schema_url 和所需的模式,发现需要版本转换。然后,它应用模式文件中描述的更改,将属性从“deployment.environment”重命名为“environment”,然后再存储 span。
这里例如是如何使用模式来查询已存储的数据的:

收集器辅助模式转换
这是一个稍微不同的用例,其中后端不感知模式,我们依赖 OpenTelemetry Collector 将遥测数据转换为后端期望接收的模式。“Schema Translate Processor”已配置,指定了目标 schema_url,并且所有通过 Collector 的遥测数据都将被转换为该目标模式。

模式 URL
模式 URL 是模式的标识符。URL 指定了一个可以通过 HTTP 或 HTTPS 协议检索的模式文件的位置(因此它是一个 URL 而不仅仅是一个 URI)。
获取指定的 URL 可能会返回 HTTP 重定向状态码。获取器*必须*遵循 HTTP 标准并遵守重定向响应,从重定向的 URL 获取文件。
URL 路径的最后一部分是模式的版本号。
http[s]://server[:port]/path/<version>
URL 中 <version> 前面的部分称为模式家族标识符。同一个模式家族中的所有模式都具有相同的模式家族标识符。
要创建模式的新版本,请复制该模式家族的最新版本的模式文件,然后添加新版本的定义。对应于新版本的模式文件*必须*可通过新 URL 进行检索。
重要提示:模式文件一旦发布,就不可变。检索到模式文件后,建议永久缓存它。模式文件也可以在构建时与可能需要该模式的软件一起打包(例如,最新的 OpenTelemetry 模式文件可以与 OpenTelemetry Collector 的模式转换处理器一起在构建时打包)。
模式版本号
版本号遵循 MAJOR.MINOR.PATCH 格式,类似于 semver 2.0。
版本号使用 semver 2.0 规范定义的排序规则。请参阅 排序转换中的排序规则。除了排序规则之外,模式版本号不携带任何其他语义含义。
OpenTelemetry 模式版本号与 OpenTelemetry 语义约定的版本号匹配,更多详细信息请参阅此处。
OTLP 支持
为了允许在发出的遥测数据中携带模式 URL,OTLP 在消息中包含了一个 schema_url 字段。
ResourceSpans、ResourceMetrics、ResourceLogs 消息中的 schema_url 字段适用于包含的 Resource、Span、SpanEvent、Metric、LogRecord 消息。
InstrumentationLibrarySpans 消息中的 schema_url 字段适用于包含的 Span 和 SpanEvent 消息。
InstrumentationLibraryMetrics 消息中的 schema_url 字段适用于包含的 Metric 消息。
InstrumentationLibraryLogs 消息中的 schema_url 字段适用于包含的 LogRecord 消息。
如果 Resource* 消息和包含的 InstrumentationLibrary* 消息中的 schema_url 字段都非空,则 InstrumentationLibrary* 消息中的值具有优先权。
API 支持
OpenTelemetry API 允许获取与模式 URL 相关联的Tracer/Meter。
OpenTelemetry 模式
OpenTelemetry 在 opentelemetry.io/schemas/<version> 发布自己的模式。模式的版本号与发布该模式的语义约定版本号相同。每次发布新的语义约定版本时,都*必须*同时发布相应的模式。如果语义约定版本发布没有引入任何更改,则模式文件中对应版本的“更改”部分将为空。