Warning
OTEPs have been moved to the Specification repository. This repository has been preserved for reference purposes. Please otherwise refer to the Specification.
This document defines how to map (convert) arbitrary data (e.g. in-memory objects) to OTLP's AnyValue.
The mapping is necessary to correctly implement Logging Library SDKs such that the converted values are unambiguous and consistent across languages and implementations.
AnyValue is capable of representing primitive and structured data of certain types.
Implementations that have a source data in any form, such as in-memory objects or data coming from other formats that needs to be converted to AnyValue SHOULD follow the rules described below.
Integer values which are within the range of 64 bit signed numbers [-2^63..2^63-1] SHOULD be converted to AnyValue's int_value field.
Integer values which are outside the range of 64 bit signed numbers SHOULD be converted to AnyValue's string_value field using decimal representation.
Values, which belong to a limited enumerated set (e.g. a Java enum) SHOULD be converted to AnyValue's string_value field with the value of the string set to the symbolic name of the enumeration.
If the symbolic name of the enumeration is not possible to obtain the implementation SHOULD map enumeration's value to AnyValue's int_value field set equal to enum's ordinal number when such ordinal number is naturally obtainable.
If the ordinal value is also not possible to obtain the enumeration SHOULD be converted to AnyValue's bytes_value field in any manner that the implementation deems reasonable.
Floating point values which are within the range and precision of IEEE 754 64-bit floating point numbers (including IEEE 32-bit floating point values) SHOULD be converted to AnyValue's double_value field.
Floating point values which are outside the range or precision of IEEE 754 64-bit floating point numbers (e.g. IEEE 128-bit floating bit values) SHOULD be converted to AnyValue's string_value field using decimal floating point representation.
String values which are valid Unicode sequences SHOULD be converted to AnyValue's string_value field.
String values which are not valid Unicode sequences SHOULD be converted to AnyValue's bytes_value with the bytes representing the string in the original order and format of the source string.
Byte sequences (e.g. Go's []byte
slice or raw byte content of a file) SHOULD
be converted to AnyValue's
bytes_value
field.
Values that represent ordered sequences of other values (such as arrays, vectors, ordered lists, slices) SHOULD be converted to AnyValue's array_value field. String Values and Byte Sequences are an exception from this rule (see above).
Values that represent associative arrays with unique keys (also often known as maps, dictionaries or key-value stores) SHOULD be converted to AnyValue's kvlist_value field.
If the keys of the source array are not strings they MUST be converted to strings by any means available, often via a toString() or stringify functions available in programming languages. The conversion function MUST be chosen in a way that ensures that the resulting string keys are unique in the target array.
The value part of each element of the source array SHOULD be converted to AnyValue recursively.
For example a JSON object {"a": 123, "b": "def"}
SHOULD be converted to
AnyValue{
kvlist_value:KeyValueList{
values:[
KeyValue{key:"a",value:AnyValue{int_value:123}},
KeyValue{key:"b",value:AnyValue{string_value:"def"}},
]
}
}
Values that represent an associative arrays with non-unique keys where multiple values may be associated with the same key (also sometimes known as multimaps, multidicts) SHOULD be converted to AnyValue's kvlist_value field.
The resulting kvlist_value field MUST list each key only once and the value of each element of kvlist_value field MUST be an array represented using AnyValue's array_value field, each element of the array_value representing one value of source array associated with the given key.
For example an associative array shown in the following table:
Key | Value |
---|---|
"abc" | 123 |
"def" | "foo" |
"def" | "bar" |
SHOULD be converted to:
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"}
]}}
},
]
}
}
Unordered collections of non-duplicate values (such as Java Sets, C++ sets, Python Sets) SHOULD be converted to AnyValue's array_value field, where each element of the set becomes an element of the array.
Any other values not listed above SHOULD be converted to AnyValue's string_value field if the source data can be serialized to a string (can be stringified) using toString() or stringify functions available in programming languages.
If the source data cannot be serialized to a string then the value SHOULD be converted AnyValue's bytes_value field by serializing it into a byte sequence by any means available.
If the source data cannot be serialized neither to a string nor to a byte sequence then it SHOULD by converted to an empty AnyValue.
If the source data has no type associated with it and is empty, null, nil or otherwise indicates absence of data it SHOULD be converted to an empty AnyValue, where all the fields are unset.
Empty values which has a type associated with them (e.g. empty associative array) SHOULD be converted using the corresponding rules defined for the types above.
Some of the mappings listed in this document can be designed differently. For example multimaps may be represented as arrays of maps, instead of maps with array values. Such alternative representations were considered but were not found to be advantageous to the solutions chosen in this document.
If AnyValue is extended to support more data types some rules in this document may be revised in order to result in a more natural mapping. If this is done then backwards compatibility should be carefully considered to avoid breaking applications that rely on the existing mapping rules.