# スパンの命名方法

Site [llms.txt](/ja/llms.txt)

---

優れた計装において最も基本的でありながら見落とされがちな側面の一つが命名です。
この記事は、OpenTelemetry における命名の技術と科学に特化したシリーズの第1回です。
分散トレースの構成要素であるスパンから始め、最も重要なポイントを冒頭でお伝えします。
それは、あなた固有のビジネスロジックを記述するスパンの命名方法です。

## ビジネススパンの命名 {#naming-your-business-spans}

OpenTelemetry の自動計装は標準的なオペレーション（受信 HTTP リクエストやデータベース呼び出しなど）をカバーする点で優れていますが、最も価値のあるインサイトは、あなた自身のビジネスロジックに追加するカスタムスパンから得られることが多いです。
これらは、あなたのアプリケーションのドメイン固有のオペレーションです。

こうしたカスタムスパンには、基本的な文法から借用したパターンを推奨します。
シンプルで明確な文は、主語 -> 動詞 -> 直接目的語という構造に従うことが多いです。
「主語」（作業を実行するサービス）はすでにトレースのコンテキストの一部です。
スパン名にはこの構造の残りの部分を使うことができます。

## {verb} {object} {#verb-object}

このパターンは説明的で理解しやすく、低[カーディナリティ](/docs/concepts/glossary/#cardinality)を維持するのに役立ちます。
カーディナリティは後ほど触れる重要な概念です。

- **{verb}**: 実行される作業を記述する動詞（例: process、send、calculate、render）。
- **{object}**: 作用の対象を記述する名詞（例: payment、invoice、shopping_cart、ad）。

いくつかの例を見てみましょう。

| 悪い名前                           | 良いスパン名        | より良い理由                                                                               |
| :--------------------------------- | :------------------ | :----------------------------------------------------------------------------------------- |
| process_payment_for_user_jane_doe  | process payment     | 動詞と目的語が明確です。ユーザー ID は属性に入れるべきです。                               |
| send*invoice*#98765                | send invoice        | 集約可能です。すべてのインボイス送信の P95 レイテンシーを簡単に確認できます。              |
| render_ad_for_campaign_summer_sale | render ad           | 特定のキャンペーンは詳細であり、コアオペレーションではありません。属性に入れましょう。     |
| calculate_shipping_for_zip_90210   | calculate shipping  | オペレーションが一貫しています。郵便番号はパラメーターであり、名前の一部ではありません。   |
| validation_failed                  | validate user_input | 結果ではなくオペレーションに焦点を当てましょう。結果はスパンのステータスに入れるべきです。 |

`{verb} {object}` 形式に従うことで、ビジネスオペレーションに対する明確で一貫した語彙を作成できます。
これにより、トレースは非常に強力なものになります。
プロダクトマネージャーが「決済処理にどのくらい時間がかかるか？」と質問したとき、エンジニアはすぐにそれらのスパンをフィルタリングして回答を得ることができます。

## このパターンが有効な理由 {#why-this-pattern-works}

では、なぜ `process payment` が良く、`process*invoice*#98765` が悪いのでしょうか。
その理由は**カーディナリティ**です。

カーディナリティとは、あるデータが取りうる一意の値の数を指します。
スパン名は**低カーディナリティ**であるべきです。
ユーザー ID やインボイス番号のような一意の識別子をスパン名に含めると、すべてのオペレーションに対して一意の名前が作成されます。
これはオブザーバビリティバックエンドを溢れさせ、類似のオペレーションをグループ化して分析することを不可能にし、コストを大幅に増加させる可能性があります。

`{verb} {object}` パターンは自然に低カーディナリティの名前を生成します。
一意で高カーディナリティの詳細（`invoice\_#98765, user_jane_doe`）は**スパン属性**に入れるべきであり、今後のブログ記事で取り上げる予定です。

## セマンティック規約から学ぶ {#learning-from-semantic-conventions}

この `{verb} {object}` アプローチは恣意的なものではありません。
これは、公式の **OpenTelemetry セマンティック規約（SemConv）** の背後にある原則を反映したベストプラクティスです。
SemConv は、一般的なオペレーションのための標準化された名前のセットを提供し、HTTP リクエストのスパンが言語やフレームワークに関係なく一貫して命名されることを保証します。

よく見ると、リソースに対するオペレーションを記述するこの同じパターンが規約全体に反映されていることがわかります。
カスタムスパンでこのパターンに従うことで、OpenTelemetry エコシステム全体の確立された哲学と一致することになります。

SemConv からいくつかの例を見てみましょう。

### HTTP スパン {#http-spans}

サーバーサイドの HTTP スパンの場合、規約は `{method} {route}` です。

- **例:** `GET /api/users/:ID`
- **分析:** これは動詞（`GET`）がオブジェクト（`/api/users/:id`）に作用しています。
  実際のパス（`/api/users/123`）ではなくルートテンプレートを使用していることが、低カーディナリティを維持する完璧な例です。

### データベーススパン {#database-spans}

データベーススパンは `{db.operation} {db.name}.{db.sql.table}` と命名されることが多いです。

- **例:** `INSERT my_database.users`
- **分析:** これは動詞（`INSERT`）がオブジェクト（`my_database`.users）に作用しています。
  挿入される具体的な値は高カーディナリティであり、名前から正しく除外されています。

### RPC スパン {#rpc-spans}

リモートプロシージャコールの場合、規約は `{rpc.service}/{rpc.method}` です。

- **例:** `com.example.UserService/GetUser`
- **分析:** 形式は異なりますが、原則は同じです。
  メソッド（`GetUser`）、すなわち動詞と、サービス（`com.example.UserService`）、すなわちオブジェクトまたはリソースを記述しています。

重要なポイントは、`{verb} {object}` を使用することで、残りの計装と同じ言語で話すことになるということです。

## 健全なシステムを育てる {#cultivating-a-healthy-system}

スパンの命名は些細な作業ではありません。
堅牢で効果的なオブザーバビリティ戦略を構築するための基盤となるプラクティスです。
ビジネス固有のスパンに `{verb} {object}` のような明確で一貫したパターンを採用することで、テレメトリーデータを絡まった混乱から手入れの行き届いた庭園へと変えることができます。

適切に命名されたスパンは、将来の自分自身とチームへの贈り物です。
ストレスの多い障害時に明確さを提供し、強力なパフォーマンス分析を可能にし、最終的にはより優れた、より信頼性の高いソフトウェアの構築に役立ちます。

このシリーズの次の記事では、次の詳細レイヤーである**スパン属性**を掘り下げます。
スパン名の集約可能性を損なうことなく、深いデバッグに必要なリッチで高カーディナリティのコンテキストをスパンに追加する方法を探ります。
