# 任意のデータをAnyValueへマッピングする

> Source: https://www.ymotongpoo.com/works/otel-specs-ja/spec/common/attribute-type-mapping/


**ステータス**: [Development](../../document-status/)

本文書は、任意のデータ（例えばメモリー上のオブジェクト）をOTLPの[AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/cc4ed55c082cb75e084d40b4ddf3805eda099f97/opentelemetry/proto/common/v1/common.proto#L27)へマッピング（変換）する方法を定義します。

このマッピングは、OpenTelemetryの外部で生成された値をOTLPエクスポーターでエクスポート可能な値に変換する必要がある場合や、その他OpenTelemetryの境界内で使用するために変換する必要がある場合に必要になります。用途の例を以下に示します。

- [Logging SDK](/works/otel-specs-ja/spec/logs/sdk/)において、ロギングライブラリから受け取った値をOpenTelemetryの表現に変換する場合。
- Collectorにおいて、様々なデータソースから受け取った値を[pdata](https://github.com/open-telemetry/opentelemetry-collector/blob/4998703dadd19fa91a88eabf7ccc68d728bee3fd/model/pdata/common.go#L84)の内部表現に変換する場合。

## Converting to AnyValue

[AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L27)は、特定の型のプリミティブなデータおよび構造化されたデータを表現できます。

いかなる形式であれソースデータを持つ実装、あるいはAnyValueへ変換する必要がある他の形式から得られたデータを持つ実装は、以下に説明する規則に従うべきです（SHOULD）。

### Primitive Values

#### Integer Values

64ビット符号付き数の範囲[-2^63..2^63-1]内にある整数値は、AnyValueの[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33)フィールドに変換すべきです（SHOULD）。

64ビット符号付き数の範囲外にある整数値は、10進表現を使ってAnyValueの[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31)フィールドに変換すべきです（SHOULD）。

#### Enumerations

限られた列挙集合に属する値（例えばJavaの[enum](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)）は、列挙のシンボル名を値とする文字列を使い、AnyValueの[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31)フィールドに変換すべきです（SHOULD）。

列挙のシンボル名を取得できない場合、実装は、そのような序数が自然に取得できるならば、列挙値を序数値に設定したAnyValueの[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33)フィールドにマッピングすべきです（SHOULD）。

序数値も取得できない場合、その列挙は実装が合理的とみなす任意の方法でAnyValueの[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37)フィールドに変換すべきです（SHOULD）。

#### Floating Point Values

IEEE 754の64ビット浮動小数点数の範囲と精度（IEEEの32ビット浮動小数点数を含む）に収まる浮動小数点数値は、AnyValueの[double_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L34)フィールドに変換すべきです（SHOULD）。

IEEE 754の64ビット浮動小数点数の範囲や精度に収まらない浮動小数点数値（例えばIEEEの128ビット浮動小数点値）は、10進浮動小数点表現を使ってAnyValueの[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31)フィールドに変換すべきです（SHOULD）。

#### String Values

有効なUTF-8シーケンスである文字列値は、AnyValueの[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31)フィールドに変換すべきです（SHOULD）。

有効なUnicodeシーケンスでない文字列値は、元の文字列の順序と形式を保ったバイト列を使い、AnyValueの[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37)に変換すべきです（SHOULD）。

#### Byte Sequences

バイト列（例えばGoの`[]byte`スライスやファイルの生バイト内容）は、AnyValueの[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37)フィールドに変換すべきです（SHOULD）。

### Composite Values

#### Array Values

他の値の順序付きシーケンスを表す値（[配列](https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html)、[ベクター](https://en.cppreference.com/w/cpp/container/vector.html)、順序付きの[リスト](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists)、[スライス](https://go.dev/ref/spec#Slice_types)など）は、AnyValueの[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35)フィールドに変換すべきです（SHOULD）。文字列値とバイト列はこの規則の例外です（前述のとおり）。

本文書で説明する規則は、配列の各要素に対して再帰的に適用してください。

#### Associative Arrays With Unique Keys

一意なキーを持つ連想配列（マップ、辞書、キーバリューストアとも呼ばれます）を表す値は、AnyValueの[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36)フィールドに変換すべきです（SHOULD）。

ソース配列のキーが文字列でない場合、利用可能な任意の手段（多くの場合、プログラミング言語で利用可能なtoString()やstringify関数）で文字列に変換されなければなりません（MUST）。変換関数は、変換先の配列における文字列キーが一意になることを保証する方法で選ばれなければなりません（MUST）。

ソース配列の各要素の値部分は、再帰的にAnyValueに変換すべきです（SHOULD）。

例えば、JSONオブジェクト`{"a": 123, "b": "def"}`は次のように変換すべきです（SHOULD）。

```
AnyValue{
    kvlist_value:KeyValueList{
        values:[
            KeyValue{key:"a",value:AnyValue{int_value:123}},
            KeyValue{key:"b",value:AnyValue{string_value:"def"}},
        ]
    }
}
```

本文書で説明する規則は、連想配列の各値に対して再帰的に適用してください。

#### Associative Arrays With Non-Unique Keys

同じキーに複数の値が関連付けられうる非一意なキーを持つ連想配列（マルチマップ、マルチディクトとも呼ばれます）を表す値は、AnyValueの[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36)フィールドに変換すべきです（SHOULD）。

変換結果の[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36)フィールドは各キーを一度だけ列挙しなければならず（MUST）、[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36)フィールドの各要素の値はAnyValueの[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35)フィールドを使って表現された配列でなければならず（MUST）、その[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35)の各要素は、そのキーに関連付けられたソース配列の1つの値を表します。

例えば、以下の表に示す連想配列は、

|キー|値|
|---|---|
|"abc"|123|
|"def"|"foo"|
|"def"|"bar"|

次のように変換すべきです（SHOULD）。

```
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"}
                ]}}
            },
        ]
    }
}
```

本文書で説明する規則は、連想配列の各値に対して再帰的に適用してください。

#### Sets

一意な値からなる順序を持たないコレクション（[Java Sets](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html)、[C++ sets](https://en.cppreference.com/w/cpp/container/set.html)、[Python Sets](https://docs.python.org/3/tutorial/datastructures.html#sets)など）は、集合の各要素が配列の要素になるようにして、AnyValueの[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35)フィールドに変換すべきです（SHOULD）。

本文書で説明する規則は、集合の各値に対して再帰的に適用してください。

### Other Values

上記に挙げられていないその他の値は、ソースデータをプログラミング言語で利用可能なtoString()やstringify関数を使って文字列に直列化できる（文字列化できる）場合、AnyValueの[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31)フィールドに変換すべきです（SHOULD）。

ソースデータを文字列に直列化できない場合、その値は利用可能な任意の手段でバイト列に直列化し、AnyValueの[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37)フィールドに変換すべきです（SHOULD）。

ソースデータを文字列にもバイト列にも直列化できない場合、その値は空のAnyValueに変換すべきです（SHOULD）。

### Empty Values

ソースデータに紐づく型がなく、空、null、nilである、あるいはその他の方法でデータの不在を示している場合、それはすべてのフィールドが未設定である[空](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L29)のAnyValueに変換すべきです（SHOULD）。

型が紐づいている空の値（例えば空の連想配列）は、上記の対応する型の規則を使って変換すべきです（SHOULD）。

