通用规范概念

Status: Stable, 除非另有说明

AnyValue

AnyValue

  • 一种原始类型:字符串、布尔值、双精度浮点数(IEEE 754-1985)或有符号 64 位整数,
  • 原始类型值的同构数组。同构数组**不得**包含不同类型的值。
  • 状态开发中 - 字节数组。
  • 状态开发中 - AnyValue 的数组,
  • 状态开发中 - map<string, AnyValue>
  • 状态开发中 - 如果语言支持,则为空值(例如,JavaScript/TypeScript 中的 nullundefined,Python 中的 None,Go/Ruby 中的 nil,Erlang 不支持等)

允许数组和映射值的任意深度嵌套(基本上允许表示等同于 JSON 对象)。

API **应**以一种向用户传达使用数组和映射值可能比原始值带来更高性能开销的方式进行文档记录。

对于不原生支持某些值类型的协议,相应的值**应**表示为 JSON 编码的字符串。例如,表达式 int64(100) 将编码为 100float64(1.5) 将编码为 1.5,任何类型的空数组将编码为 []

表示空值、零数值、空字符串或空数组的 AnyValues 被认为是有效的,并且**必须**存储并传递给处理器/导出器。

虽然 null 是有效的属性值,但其在同构数组中的使用**通常应**避免,除非语言限制使其不可能。但是,如果无法确保不接受 null 值(例如,在没有适当编译时类型检查的语言中),数组中的 null 值**必须**按原样保留(即,以 null 的形式传递给处理器/导出器)。如果导出器不支持导出 null 值,它们**可以**用 0、false 或空字符串替换这些值。这对于表示为两个数组的映射/字典结构是必需的,其中索引保持同步(例如,两个属性 header_keysheader_values,都包含一个字符串数组来表示映射 header_keys[i] -> header_values[i])。

map<string, AnyValue>

状态: 开发中

map<string, AnyValue> 是一个字符串键到 AnyValue 值的映射。映射中的键是唯一的(不允许重复键)。

键的区分大小写**必须**保留。大小写不同的键被视为不同的键。

映射的表示取决于语言。

实现**必须**默认强制导出的映射只包含唯一键。唯一性的强制执行可以通过多种方式进行,这最适合特定实现的限制(例如,通过删除重复项)。

实现**可以**提供一个选项来允许导出具有重复键的映射(例如,为了获得更好的性能)。如果提供了此类选项,**必须**注明许多接收方处理具有重复键的映射是不可预测的,用户有责任确保键不重复。

当映射包含相同的键值对时,它们是相等的,与这些元素出现的顺序无关(无序集合相等)。

属性

Attribute 是一个键值对,它**必须**具有以下属性

  • 属性键**必须**是一个非 null 且非空字符串。
    • 键的区分大小写得到保留。大小写不同的键被视为不同的键。
  • 属性值**必须**是 AnyValue 中定义的类型之一。

当键和值相等时,属性相等。

有关命名准则,请参阅 属性命名

有关要求级别准则,请参阅 要求级别

请参阅 本文档,了解如何将 OpenTelemetry 外部获取的值映射到 OpenTelemetry 属性值。

属性集合

资源仪器范围指标点跨度、跨度 事件、跨度 链接日志记录 包含属性的集合。

属性集合是 OpenTelemetry 数据模型中使用的顶级键值对集合。请注意,它们与 map<string, AnyValue> 不同,后者是一种 AnyValue 类型,用于表示嵌套数据结构,例如属性值和 日志记录正文

实现**必须**默认强制导出的属性集合只包含唯一键。唯一性的强制执行可以通过多种方式进行,这最适合特定实现的限制(例如,通过删除重复项)。

通常,使用 OpenTelemetry SDK 生成的遥测数据通过 API 设置属性键值对,该 API 接受单个键值对或键值对的集合。设置具有与现有属性相同键的属性**应**覆盖现有属性的值。例如,请参阅跨度的 SetAttribute API。

SetAttribute API 的典型实现将通过覆盖所有待导出的现有属性值来强制执行唯一性,以便在最终导出跨度时,导出器仅看到唯一的属性。特别是 OTLP 格式要求导出的资源、跨度、指标数据点和日志记录仅包含唯一的属性。

其他一些实现可能使用流式方法,其中每次调用 SetAttribute API 都会立即使用流式线路协议导出该单个属性值。在这种情况下,唯一性的强制执行很可能是此数据接收者的责任。

实现**可以**提供一个选项来允许导出具有重复键的属性集合(例如,为了获得更好的性能)。如果提供了此类选项,**必须**注明许多接收方处理具有重复键的映射是不可预测的,用户有责任确保键不重复。

属性集合当它们包含相同的属性时相等,与这些元素出现的顺序无关(无序集合相等)。

属性限制

执行错误代码可能导致意外的属性。如果不对属性集合设置限制,它们可能会很快耗尽可用内存,从而导致难以安全恢复的崩溃。

默认情况下,SDK **应**按照下面的 可配置参数 列表应用截断。

如果 SDK 提供了一种方法来

  • 设置属性值长度限制,使得对于每个属性值
    • 如果是字符串,如果它超过该限制(将任何字符计为 1),SDK **必须**截断该值,使其长度最多等于限制,
    • 状态开发中 - 如果是字节数组,如果其长度超过该限制(将每个字节计为 1),SDK **必须**截断该值,使其长度最多等于限制,
    • 如果是字符串数组,则分别将限制应用于数组中的每个值,
    • 状态开发中 - 如果是 AnyValue 数组,则分别(并递归地)将限制应用于数组中的每个元素,
    • 状态开发中 - 如果是 map,则分别(并递归地)将限制应用于映射中的每个值,
    • 否则,**不得**截断值;
  • 设置属性计数限制,使得
    • 如果将属性添加到属性集合会导致超过限制(将集合中的每个属性计为 1),SDK **必须**丢弃该属性,使得属性集合中的总属性数最多等于限制;
    • 状态开发中 - 计数限制仅适用于顶级属性,而不适用于 map 中的嵌套键值对;
    • 否则,**不得**丢弃属性。

可能会记录一条日志,告知用户属性已被截断或丢弃。为防止日志过多,**不得**对属性设置的每条记录发出超过一次日志。

如果 SDK 实现上述限制,则**必须**提供一种以编程方式更改这些限制的方法。配置选项的名称**应**与下面的列表相同。

SDK **可以**实现特定于模型的限制,例如 SpanAttributeCountLimitLogRecordAttributeCountLimit。如果同时实现了通用限制和特定于模型的限制,则 SDK **必须**首先尝试使用特定于模型的限制,如果未设置,则 SDK **必须**尝试使用通用限制。如果两者都未定义,则 SDK **必须**尝试使用特定于模型的默认值,然后是全局限制的默认值。

请注意,限制仅适用于属性集合。因此,它们不适用于其他数据结构中的值,例如 LogRecord.Body

可配置参数

  • AttributeCountLimit(默认值=128)- 每个记录允许的最大属性数;
  • AttributeValueLengthLimit(默认值=Infinity)- 允许的最大属性值长度(适用于字符串值和字节数组);

豁免实体

资源属性**应**豁免上述限制,因为资源不易受到导致过多属性计数或大小的场景(自动仪器)的影响。资源每个批次只发送一次,而不是每个跨度发送一次,因此拥有更多/更大的属性相对便宜。资源在设计上也是不可变的,并且它们通常与限制一起向下传递给 TracerProvider。这使得为资源实现属性限制变得麻烦。

目前,属于指标的属性已豁免上述限制,如 指标属性限制 中所述。