# 設定データモデル

> Source: https://www.ymotongpoo.com/works/otel-specs-ja/spec/configuration/data-model/


**ステータス**: [安定（Stable）](../../document-status/)（別途明記されている箇所を除く）

## 概要

OpenTelemetryの設定データモデルは、[宣言的設定インターフェース](../#宣言的設定)の一部です。

このデータモデルは、利用者がOpenTelemetry SDKコンポーネントと計装の意図した設定を指定できるようにするデータ構造を定義します。

このデータモデルは、[JSON Schema](https://json-schema.org/)を使って[opentelemetry-configuration](https://github.com/open-telemetry/opentelemetry-configuration)の中で定義されています。

データモデル自体は抽象であり、複数の組み込み表現を持ちます。

* [File-based configuration model](#file-based-configuration-model)
* [SDK in-memory configuration model](../sdk/#in-memory-configuration-model)

### バージョニング方針と安定性の保証

`opentelemetry-configuration`の[バージョニング方針](https://github.com/open-telemetry/opentelemetry-configuration/blob/main/VERSIONING.md)を参照してください。

### File-based configuration model

設定ファイルは、設定データモデルのシリアライズされたファイルベースの表現です。

設定ファイルは、以下のシリアライズ形式のいずれかをSHOULD使用するものとします。

* [YAML file format](#yaml-file-format)

#### YAML file format

[YAML](https://yaml.org/spec/1.2.2/)設定ファイルは、YAML仕様のリビジョン1.2以上にSHOULD従うものとします。

YAML設定ファイルは、[v1.2 YAML core schema](https://yaml.org/spec/1.2.2/#103-core-schema)を使って解析されるべきです（SHOULD）。

YAML設定ファイルは、拡張子`.yaml`または`.yml`をMUST使用するものとします。

#### Environment variable substitution

設定ファイルは、[Augmented Backus-Naur Form](https://datatracker.ietf.org/doc/html/rfc5234)を使って定義された参照のための環境変数置換をサポートします。

```abnf
SUBSTITUTION-REF = "${" [PREFIX ":"] GENERIC-SUBSTITUTION "}"; generic substitution reference

; when PREFIX is absent or "env", GENERIC-SUBSTITUTION MUST conform to ENV-SUBSTITUTION:
ENV-SUBSTITUTION = ENV-NAME [":-" DEFAULT-VALUE]; env var substitution

PREFIX = ALPHA *(ALPHA / DIGIT / "_"); substitution prefix, e.g. "env" (universal) or language-specific
GENERIC-SUBSTITUTION = 1*(VCHAR-WSP-NO-RBRACE); substitution content, interpretation depends on PREFIX
ENV-NAME = (ALPHA / "_") *(ALPHA / DIGIT / "_"); the name of the environment variable to be substituted
DEFAULT-VALUE = *(VCHAR-WSP-NO-RBRACE); any number of VCHAR-WSP-NO-RBRACE
VCHAR-WSP-NO-RBRACE = %x21-7C / "~" / WSP; printable chars and whitespace, except }

ALPHA = %x41-5A / %x61-7A; A-Z / a-z
DIGIT = %x30-39 ; 0-9
```

`SUBSTITUTION-REF`は有効な置換参照を定義します。

* `${`で始まらなければなりません
* 任意で`PREFIX:`が続きます。`PREFIX`は`env`（汎用）または言語固有の識別子です
* `GENERIC-SUBSTITUTION`（`}`を除く少なくとも1つの表示可能文字または空白）が続かなければなりません
* `}`が続かなければなりません

`PREFIX`が存在しない、または`env`である場合、`GENERIC-SUBSTITUTION`は`ENV-SUBSTITUTION`にMUST準拠するものとします。

* 置換対象の環境変数の名前である`ENV-NAME`で始まらなければなりません
  * アルファベットまたは`_`文字で始まらなければなりません
  * 任意の数の英数字または`_`文字が続かなければなりません
* 任意でデフォルト値が続きます
  * `:-`で始まらなければなりません
  * `}`と空白を除く任意の数の表示可能文字である`DEFAULT-VALUE`が続かなければなりません

言語の実装は、言語固有の設定ソースへアクセスするために、`env:`を超える追加のプレフィックスをサポートしてもかまいません（MAY）。`GENERIC-SUBSTITUTION`の内容は、`PREFIX`のスキームに従って解釈されます。例えばJavaの実装では、システムプロパティにアクセスするために`sys:`をサポートする場合があります（`${sys:otel.service.name}`）。言語の実装は、サポートする追加のプレフィックスをSHOULD文書化するものとします。

便宜上、`SUBSTITUTION-REF`と`ENV-SUBSTITUTION`は以下でPCRE2の正規表現として表現されています。これらの表現は非規範的であることに注意してください。

```regexp
// SUBSTITUTION-REF
\$\{(?:(?<PREFIX>[a-zA-Z][a-zA-Z0-9_]*):)?(?<GENERIC_SUBSTITUTION>[^}]+)\}

// ENV-SUBSTITUTION (applied to GENERIC_SUBSTITUTION when PREFIX is absent or "env")
(?<ENV_NAME>[a-zA-Z_][a-zA-Z0-9_]*)(:-(?<DEFAULT_VALUE>[^\n]*))?
```

例えば、`${API_KEY}`と`${env:API_KEY}`は有効な環境変数置換ですが、`${1API_KEY}`と`${API_$KEY}`は`ENV-SUBSTITUTION`に準拠しないため無効です。

環境変数置換は、スカラー値にのみMUST適用されるものとします。マッピングのキーは置換の対象外です。

`SUBSTITUTION-REF`の`DEFAULT-VALUE`の部分は、`ENV-NAME`がnull、空、または未定義の場合に置換される任意のフォールバック値です。参照された環境変数が定義されておらず、`DEFAULT-VALUE`も持たない場合、それは空の値へMUST置き換えられるものとします。

`$`文字はエスケープシーケンスであり、入力中の`$$`は出力中の単一の`$`へ変換されます。エスケープシーケンスから解決された`$`は、入力を環境変数置換の正規表現に対してマッチングする際にMUST NOT考慮されないものとします。例えば、`$${API_KEY}`は`${API_KEY}`に解決され、`API_KEY`環境変数の値は置換されません。より多くの例については下の表を参照してください。実際には、これはパーサーが入力を左から右に消費し、次のエスケープシーケンスを反復的に識別し、直前のエスケープシーケンス以降の内容を`SUBSTITUTION-REF`に対してマッチングすることを意味します。

例えば、`FOO=a, BAR=b, BAZ=c`のとき、入力`$${FOO} ${BAR} $${BAZ}`を処理する疑似コードは以下のようになります。

* インデックス0でエスケープシーケンス`$$`を識別します。`input.substring(0, 0)=""`に対して置換を実行すると`""`になり、これを出力に追加します。`$`を出力に追加します。現在の出力: `"$"`。
* インデックス15でエスケープシーケンス`$$`を識別します。`input.substring(0+2, 15)="{FOO} ${BAR} "`に対して置換を実行すると`"{FOO} b "`になり、これを出力に追加します。`$`を出力に追加します。現在の出力: `"${FOO} b $"`。
* エスケープシーケンスなしで入力の終端に達します。`input.substring(15+2, input.length)="{BAZ}"`に対して置換を実行すると`"{BAZ}"`になります。出力を返します: `"${FOO} b ${BAZ}"`。

`GENERIC-SUBSTITUTION`がそのスキームの検証規則に準拠しない`SUBSTITUTION-REF`を含む設定ファイル（例えば`PREFIX`が存在しないか`env`である場合に`ENV-SUBSTITUTION`に準拠しない場合）を解析する際、パーサーは空の結果を返さなければならず（部分的な結果は許容されません）、解析の失敗を説明するエラーを利用者に返さなければなりません（MUST）。

ノードの型は、環境変数置換が行われた後にMUST解釈されるものとします。これにより、ブーリアン、整数、浮動小数点数のプロパティの環境変数文字列表現が、期待される型へ適切に変換されることが保証されます。

環境変数によってYAML構造を注入することがMUST NOT可能であるものとします。例えば、以下の`INVALID_MAP_VALUE`環境変数への参照を参照してください。

環境変数によって環境変数を注入することがMUST NOT可能であるものとします。例えば、以下の`DO_NOT_REPLACE_ME`環境変数への参照を参照してください。

以下の表は、さまざまな入力に対する環境変数置換の振る舞いを示しています。これらの例は、環境変数が以下のように設定されていることを前提としています。

```shell
export STRING_VALUE="value"
export BOOL_VALUE="true"
export INT_VALUE="1"
export FLOAT_VALUE="1.1"
export HEX_VALUE="0xdeadbeef"                   # A valid integer value (i.e. 3735928559) written in hexadecimal
export INVALID_MAP_VALUE="value\nkey:value"     # An invalid attempt to inject a map key into the YAML
export DO_NOT_REPLACE_ME="Never use this value" # An unused environment variable
export REPLACE_ME='${DO_NOT_REPLACE_ME}'        # A valid replacement text, used verbatim, not replaced with "Never use this value"
export VALUE_WITH_ESCAPE='value$$'              # A valid variable substituted without escaping
```

| YAML - 入力                               | YAML - 置換後                  | 解決されたタグURI          | 注記                                                                                                                                             |
|--------------------------------------------|-------------------------------------------|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| `key: ${STRING_VALUE}`                     | `key: value`                              | `tag:yaml.org,2002:str`   | YAMLパーサーは文字列に解決します                                                                                                                    |
| `key: ${BOOL_VALUE}`                       | `key: true`                               | `tag:yaml.org,2002:bool`  | YAMLパーサーはtrueに解決します                                                                                                                     |
| `key: ${INT_VALUE}`                        | `key: 1`                                  | `tag:yaml.org,2002:int`   | YAMLパーサーはintに解決します                                                                                                                      |
| `key: ${FLOAT_VALUE}`                      | `key: 1.1`                                | `tag:yaml.org,2002:float` | YAMLパーサーはfloatに解決します                                                                                                                    |
| `key: ${HEX_VALUE}`                        | `key: 0xdeadbeef`                         | `tag:yaml.org,2002:int`   | YAMLパーサーはint `3735928559`に解決します                                                                                                         |
| `key: "${STRING_VALUE}"`                   | `key: "value"`                            | `tag:yaml.org,2002:str`   | 二重引用符で文字列`"value"`への強制変換を強制                                                                                                       |
| `key: "${BOOL_VALUE}"`                     | `key: "true"`                             | `tag:yaml.org,2002:str`   | 二重引用符で文字列`"true"`への強制変換を強制                                                                                                        |
| `key: "${INT_VALUE}"`                      | `key: "1"`                                | `tag:yaml.org,2002:str`   | 二重引用符で文字列`"1"`への強制変換を強制                                                                                                           |
| `key: "${FLOAT_VALUE}"`                    | `key: "1.1"`                              | `tag:yaml.org,2002:str`   | 二重引用符で文字列`"1.1"`への強制変換を強制                                                                                                         |
| `key: "${HEX_VALUE}"`                      | `key: "0xdeadbeef"`                       | `tag:yaml.org,2002:str`   | 二重引用符で文字列`"0xdeadbeef"`への強制変換を強制                                                                                                  |
| `key: ${env:STRING_VALUE}`                 | `key: value`                              | `tag:yaml.org,2002:str`   | 代替の`env:`構文                                                                                                                                   |
| `key: ${INVALID_MAP_VALUE}`                | `key: value\nkey:value`                   | `tag:yaml.org,2002:str`   | マップ構造は文字列に解決され、展開_されません_                                                                                                       |
| `key: foo ${STRING_VALUE} ${FLOAT_VALUE}`  | `key: foo value 1.1`                      | `tag:yaml.org,2002:str`   | 複数の参照が注入され、文字列に解決されます                                                                                                           |
| `key: ${UNDEFINED_KEY}`                    | `key:`                                    | `tag:yaml.org,2002:null`  | 未定義の環境変数は`""`に置き換えられ、nullに解決されます                                                                                              |
| `key: ${UNDEFINED_KEY:-fallback}`          | `key: fallback`                           | `tag:yaml.org,2002:str`   | 未定義の環境変数はデフォルト値`fallback`の置換をもたらします                                                                                          |
| `${STRING_VALUE}: value`                   | `key: ${STRING_VALUE}: value`             | `tag:yaml.org,2002:str`   | キーの中で置換構文を使うことは無視されます                                                                                                            |
| `key: ${REPLACE_ME}`                       | `key: ${DO_NOT_REPLACE_ME}`               | `tag:yaml.org,2002:str`   | 環境変数`REPLACE_ME`の値は`${DO_NOT_REPLACE_ME}`であり、再帰的には置換され_ません_                                                                    |
| `key: ${UNDEFINED_KEY:-${STRING_VALUE}}`   | `key: ${STRING_VALUE}`                    | `tag:yaml.org,2002:str`   | 未定義の環境変数はデフォルト値`${STRING_VALUE}`の置換をもたらし、再帰的には置換され_ません_                                                            |
| `key: ${STRING_VALUE:?error}`              | n/a                                       | n/a                       | 無効な置換参照は解析エラーを生じさせます                                                                                                              |
| `key: $${STRING_VALUE}`                    | `key: ${STRING_VALUE}`                    | `tag:yaml.org,2002:str`   | `$$`エスケープシーケンスは`$`に置き換えられ、`{STRING_VALUE}`は置換構文にマッチしません                                                                 |
| `key: $$${STRING_VALUE}`                   | `key: $value`                             | `tag:yaml.org,2002:str`   | `$$`エスケープシーケンスは`$`に置き換えられ、`${STRING_VALUE}`は`value`に置き換えられます                                                              |
| `key: $$$${STRING_VALUE}`                  | `key: $${STRING_VALUE}`                   | `tag:yaml.org,2002:str`   | `$$`エスケープシーケンスは`$`に置き換えられ、続く`$$`エスケープシーケンスも`$`に置き換えられ、`{STRING_VALUE}`は置換構文にマッチしません                  |
| `key: $${STRING_VALUE:-fallback}`          | `key: ${STRING_VALUE:-fallback}`          | `tag:yaml.org,2002:str`   | `$$`エスケープシーケンスは`$`に置き換えられ、`{STRING_VALUE:-fallback}`は置換構文にマッチしません                                                       |
| `key: $${STRING_VALUE:-${STRING_VALUE}}`   | `key: ${STRING_VALUE:-value}`             | `tag:yaml.org,2002:str`   | `$$`エスケープシーケンスは`$`に置き換えられ、`{STRING_VALUE:-${STRING_VALUE}}`が残り、`${STRING_VALUE}`は`value`に置き換えられます                     |
| `key: ${UNDEFINED_KEY:-$${UNDEFINED_KEY}}` | `key: ${UNDEFINED_KEY:-${UNDEFINED_KEY}}` | `tag:yaml.org,2002:str`   | `$$`エスケープシーケンスは`$`に置き換えられ、`${UNDEFINED_KEY:-`が前に、マッチしない`{UNDEFINED_KEY}}`が後に残ります                                    |
| `key: ${VALUE_WITH_ESCAPE}`                | `key: value$$`                            | `tag:yaml.org,2002:str`   | 環境変数`VALUE_WITH_ESCAPE`の値は`value$$`であり、エスケープなしで置換されます                                                                        |
| `key: a $$ b`                              | `key: a $ b`                              | `tag:yaml.org,2002:str`   | `$$`エスケープシーケンスは`$`に置き換えられます                                                                                                       |
| `key: a $ b`                               | `key: a $ b`                              | `tag:yaml.org,2002:str`   | エスケープシーケンスも置換参照もなく、値は変更されません                                                                                               |

