将任意数据映射到 OTLP AnyValue
状态: 开发中
本文档定义了如何将任意数据(例如内存中的对象)映射(转换)为 OTLP 的 AnyValue。
当 OpenTelemetry 需要将 OpenTelemetry 外部生成的值转换为可以使用 OTLP 导出器导出的值,或者在 OpenTelemetry 边界内部使用的值时,就需要进行这种映射。示例如下:
转换为 AnyValue
AnyValue 能够表示某些类型的原始数据和结构化数据。
具有任何形式的源数据(例如内存对象或需要转换为 AnyValue 的其他格式的数据)的实现,应遵循以下规则。
原始值
整数值
在 64 位有符号整数范围 [-2^63..2^63-1] 内的整数值应转换为 AnyValue 的 int_value 字段。
超出 64 位有符号整数范围的整数值应使用十进制表示法转换为 AnyValue 的 string_value 字段。
枚举
属于有限枚举集的值(例如 Java enum)应转换为 AnyValue 的 string_value 字段,并将字符串值设置为枚举的符号名称。
如果无法获取枚举的符号名称,则实现应在可以自然获取序数值时,将枚举值映射到 AnyValue 的 int_value 字段,设置为枚举的序数值。
如果也无法获取序数值,则枚举应转换为 AnyValue 的 bytes_value 字段,通过实现认为合理的方式进行转换。
浮点数值
在 IEEE 754 64 位浮点数范围和精度内的浮点值(包括 IEEE 32 位浮点值)应转换为 AnyValue 的 double_value 字段。
超出 IEEE 754 64 位浮点数范围或精度的浮点值(例如 IEEE 128 位浮点值)应使用十进制浮点表示法转换为 AnyValue 的 string_value 字段。
字符串值
有效的 UTF-8 序列的字符串值应转换为 AnyValue 的 string_value 字段。
非有效 Unicode 序列的字符串值应转换为 AnyValue 的 bytes_value 字段,其中字节按源字符串的原始顺序和格式表示。
字节序列
字节序列(例如 Go 的 []byte 切片或文件的原始字节内容)应转换为 AnyValue 的 bytes_value 字段。
复合值
数组值
表示其他值有序序列的值(如 数组、向量、有序 列表、切片)应转换为 AnyValue 的 array_value 字段。字符串值和字节序列是此规则的例外(请参阅上文)。
本文档中描述的规则应递归应用于数组的每个元素。
具有唯一键的关联数组
表示具有唯一键的关联数组(也常称为映射、字典或键值存储)的值应转换为 AnyValue 的 kvlist_value 字段。
如果源数组的键不是字符串,则必须通过任何可用手段将其转换为字符串,通常通过编程语言提供的 toString() 或 stringify 函数。转换函数必须选择一种方式,以确保生成的字符串键在目标数组中是唯一的。
源数组每个元素的值部分应递归转换为 AnyValue。
例如,JSON 对象 {"a": 123, "b": "def"} 应转换为
AnyValue{
kvlist_value:KeyValueList{
values:[
KeyValue{key:"a",value:AnyValue{int_value:123}},
KeyValue{key:"b",value:AnyValue{string_value:"def"}},
]
}
}
本文档中描述的规则应递归应用于关联数组的每个值。
具有非唯一键的关联数组
表示具有非唯一键的关联数组(也称为多重映射、多重字典)的值应转换为 AnyValue 的 kvlist_value 字段,其中多个值可能与同一个键相关联。
生成的 kvlist_value 字段必须只列出每个键一次,并且 kvlist_value 字段的每个元素的值必须是一个使用 AnyValue 的 array_value 字段表示的数组,数组的每个元素代表源数组中与给定键相关联的一个值。
例如,下表中显示的关联数组
| 键 | 值 |
|---|---|
| “abc” | 123 |
| “def” | “foo” |
| “def” | “bar” |
应转换为
AnyValue{
kvlist_value:KeyValueList{
values:[
KeyValue{
key:"abc",
value:AnyValue{array_value:ArrayValue{values[
AnyValue{int_value:123}
]}}
},
KeyValue{
key:"def",
value:AnyValue{array_value:ArrayValue{values[
AnyValue{string_value:"foo"},
AnyValue{string_value:"bar"}
]}}
},
]
}
}
本文档中描述的规则应递归应用于关联数组的每个值。
集合
无序的唯一值集合(如 Java Set、C++ set、Python Set)应转换为 AnyValue 的 array_value 字段,其中集合的每个元素成为数组的一个元素。
本文档中描述的规则应递归应用于集合的每个值。
其他值
上面未列出的任何其他值,如果源数据可以(使用编程语言中可用的 toString() 或 stringify 函数)序列化为字符串(可 stringify),则应转换为 AnyValue 的 string_value 字段。
如果源数据无法序列化为字符串,则应通过任何可用手段将其序列化为字节序列,然后转换为 AnyValue 的 bytes_value 字段。
如果源数据既不能序列化为字符串也不能序列化为字节序列,则应将其转换为空的 AnyValue。
空值
如果源数据没有关联的类型,并且为空、null、nil 或以其他方式指示数据缺失,则应将其转换为 空 的 AnyValue,其中所有字段均未设置。
具有关联类型的空值(例如,空关联数组)应使用上面为该类型定义的相应规则进行转换。