# リソースのデータモデル

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


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

リソースは、テレメトリーが生成される対象の観測対象エンティティを表します。リソースは、テレメトリーの発生源を識別する属性の集合によって定義され、それを技術的に生成しているコンポーネント（自動計装エージェントなど）を識別するものではありません。例えば、Kubernetes上のコンテナで実行されているプロセスは、ノード（VM）上で動作するPodに関連付けられ、そのノードは名前空間に属し、Deploymentの一部である場合もあります。リソースには、コンテナ、Pod、ノード、VM、Deploymentに関する情報を示す属性を持たせられます。これらはいずれも観測対象エンティティの識別に役立ちます。一部の属性には、規定された意味があることに注意してください。

リソースは、0個以上の[`Entity`](/works/otel-specs-ja/spec/entities/)と、いずれのエンティティにも関連付けられていない0個以上の属性から構成されます。

以下のデータモデルは、リソースの物理的なフォーマットやエンコーディングとは無関係に、リソースの論理モデルを定義します。

| フィールド | 型 | 説明 |
| ----- | ---- | ----------- |
| Entities | set\<Entity\> | このリソースに関連付けられたEntityの集合を定義します。<p>[Entityの定義はこちら](/works/otel-specs-ja/spec/entities/data-model/) |
| Attributes | map\<string, attribute value\> | リソースを識別する追加の属性です。<p>リソースの生存期間中に変化してはいけません（MUST）。<p>OpenTelemetryの[属性の定義](../../common/#attribute)に従います。 |

## アイデンティティ

ほとんどのリソースは、[`Entity`](/works/otel-specs-ja/spec/entities/data-model/)の合成です。Entityは、それ自体のアイデンティティの概念を含みます。リソースのアイデンティティは、そのリソースに含まれるエンティティの集合です。2つのリソースは、一方に他方には存在しないエンティティが含まれている場合、異なるものとみなされます。

一部のリソースには、Entityに加えて生の属性が含まれます。生の属性は、リソース上で識別的なものとみなされます。つまり、生の属性のキーと値の組が異なる場合、リソースは異なるものと仮定できます。

## リソースのマージ

注: 現在のSDK仕様では、[マージアルゴリズム](../sdk/#merge)が規定されています。本仕様は、このアルゴリズムをEntityに準拠する形に更新します。この節は、Entityが安定版になった時点で、その節を置き換えます。SDKは、Entity SDKが完全にサポートされるまで、マージアルゴリズムを更新すべきではありません（SHOULD NOT）。

リソースのマージとは、観測のコンテキストを結合する行為です。つまり、あるシグナルに対するリソースコンテキストを見て、そのコンテキストを*拡張*してより詳細な情報を含めることができます（[アイデンティティのテレスコーピング](../#テレスコーピング)を参照）。したがって、マージは、新しい識別情報や説明的な属性を追加する際に、リソース上に既に存在していたアイデンティティを保持すべきです（SHOULD）。

### リソースへのエンティティのマージ

既存のリソースにEntityをマージするための、次のアルゴリズムを定義します。

- リソース上の既存のエンティティの集合`E`を構築します。
  - 優先順位順（最も高いものから順に）で、各エンティティ`new_entity`について、次のいずれかを行います。
    - `new_entity`と同じエンティティ種別を持つエンティティ`e`が`E`に存在する場合：
      - `e`と`new_entity`に対して[Entity DataModelのマージ](/works/otel-specs-ja/spec/entities/data-model/#entityの統合)を実行します
      - 注: `e`と`new_entity`をマージできない場合、変更は行われません。
    - そうでない場合、エンティティ`new_entity`を集合`E`に追加します
- Eのエンティティ集合を使うようにリソースを更新します。
  - `E`内のすべてのエンティティが同じ`schema_url`を持つ場合、リソースの`schema_url`をそれに一致させます。
  - そうでない場合、リソースの`schema_url`を空にします。
  - `E`内のエンティティの説明またはアイデンティティに存在する属性を、`Attributes`から削除します。
- リソースのフラット化に関する問題を解決します（[属性参照モデル](/works/otel-specs-ja/spec/entities/data-model/#属性参照モデル)を参照）。
  - すべてのエンティティについて、属性キーの重複がなくなった場合、対応は不要です。
  - 2つのエンティティが同じ属性キーを使う競合がある場合、優先度の低いエンティティをリソースから削除します。

**注**: エンティティのマージにおける優先順位は、一般にユーザーの設定によって暗黙的に選択されます。例えば、SDKに設定されたリソース検出器の順序が、エンティティをマージする際の優先順位を暗黙的に決定します。

#### 例

*これらの例は、マージ中に競合がどのように解決されるかを示しています。*

##### 例1: エンティティによる非関連属性の置き換え

エンティティに属さない属性と、エンティティに属する属性の間の競合です。ここでは、エンティティが追加されると、以前の属性が削除されます。

**Initial Resource:**

- Entities: *None*
- Attributes:
  - `host.name`: `"old-name"`
  - `env`: `"prod"`

**Entities to Merge (by priority):**

1. `host`
   - type: `"host"`
   - identity:
     - `host.id`: `"H1"`
   - description:
     - `host.name`: `"new-name"`
2. `service`
   - type: `"service"`
   - identity:
     - `service.name`: `"my-svc"`

**Resulting Resource:**

- Entities:
  - `host`
    - type: `"host"`
    - identity:
      - `host.id`: `"H1"`
    - description:
      - `host.name`: `"new-name"`
  - `service`
    - type: `"service"`
    - identity:
      - `service.name`: `"my-svc"`
- Attributes:
  - `env`: `"prod"`

##### 例2: 非関連属性によるエンティティ属性の置き換え

エンティティに属さない属性と、エンティティに属する属性の間の競合です。ここでは、エンティティに属さない属性が追加されると、競合のためエンティティを削除しなければなりません。

**Initial Resource:**

- Entities:
  - `host`
    - type: `"host"`
    - identity:
      - `host.id`: `"H1"`
    - description:
      - `host.name`: `"detected-name"`
  - `process`
    - type: `"process"`
    - identity:
      - `process.pid`: `12345`
- Attributes: *None*

**Resource to Merge:**

- Entities: *None*
- Attributes:
  - `host.id`: `"h2"`
  - `env`: `"prod"`

**Resulting Resource:**

- Entities:
  - `process`
    - type: `"process"`
    - identity:
      - `process.pid`: `12345`
- Attributes:
  - `host.id`: `"h2"`
  - `env`: `"prod"`

##### 例3: アイデンティティと属性の競合

同じ種別で異なるアイデンティティを持つエンティティを拒否し、属性キーの競合のために優先度の低いエンティティを削除する例です。

**Initial Resource:**

- Entities:
  - `host`
    - type: `"host"`
    - identity:
      - `host.id`: `"H1"`
    - description:
      - `env`: `"prod"`
- Attributes: *None*

**Entities to Merge (by priority):**

1. `host`
   - type: `"host"`
   - identity:
     - `host.id`: `"H2"`
2. `service`
   - type: `"service"`
   - identity:
     - `service.name`: `"S1"`
   - description:
     - `env`: `"dev"`

**Resulting Resource:**

- Entities:
  - `host`
    - type: `"host"`
    - identity:
      - `host.id`: `"H1"`
    - description:
      - `env`: `"prod"`
- Attributes: *None*

