セマンティック規約リファレンス - 実装で使う主要属性一覧
セマンティック規約を理解したら、次は実装の段階で「どの属性を使うのか」を判断する必要があります。この記事では、実装時に参照できるドメイン別の詳細属性リファレンスと、実装パターンを解説します。
HTTP通信の属性(http.namespace)
WebアプリケーションやREST API、マイクロサービス間通信で最も使われるドメインです。
HTTPリクエスト関連の属性
| 属性名 | 型 | 説明 | 例 | 記録タイミング |
|---|---|---|---|---|
http.request.method | string | HTTPメソッド | GET, POST, PUT, DELETE | リクエスト開始時 |
url.full | string | リクエストの完全URL | https://api.example.com/users/123?page=1 | リクエスト開始時 |
url.path | string | URLのパス部分 | /users/123 | リクエスト開始時 |
url.query | string | クエリ文字列 | page=1&limit=10 | リクエスト開始時 |
server.address | string | リクエスト先サーバーのホスト名またはIP | api.example.com、192.0.2.1 | リクエスト開始時 |
server.port | int | リクエスト先サーバーのポート番号 | 443、8080 | リクエスト開始時 |
http.request.body.size | int | リクエストボディのサイズ(バイト) | 1024 | リクエスト完了時 |
HTTPレスポンス関連の属性
| 属性名 | 型 | 説明 | 例 | 記録タイミング |
|---|---|---|---|---|
http.response.status_code | int | HTTPステータスコード | 200, 404, 500 | レスポンス受信時 |
http.response.body.size | int | レスポンスボディのサイズ(バイト) | 2048 | レスポンス完了時 |
http.response.header.<header_name> | string[] | 特定のレスポンスヘッダー値 | application/json | レスポンス受信時 |
実装パターン
HTTP クライアント呼び出しの実装例
# Python で HTTP リクエストをトレースする際の属性設定例
span.set_attributes({
"http.request.method": "GET",
"url.full": "https://api.example.com/users/123",
"server.address": "api.example.com",
"server.port": 443,
})
# レスポンス受信後
span.set_attributes({
"http.response.status_code": 200,
"http.response.body.size": 1024,
})
# エラー時
if status_code >= 400:
span.set_status(StatusCode.ERROR)属性選択のガイドライン
HTTPの属性では、以下の優先順で属性を記録します:
必須レベル(常に記録):
http.request.methodhttp.response.status_code
推奨レベル(ほとんどの場合記録):
url.fullまたはurl.path+server.address
オプショナルレベル(必要に応じて記録):
http.request.body.size、http.response.body.size- パフォーマンス監視が重要な場合に追加
データベース操作の属性(db. namespace)
SQL、NoSQL、キャッシュストアなど、あらゆるデータベースアクセスに関する属性です。
基本属性
| 属性名 | 型 | 説明 | 例 | 記録タイミング |
|---|---|---|---|---|
db.system | string | データベース管理システムの種別 | postgresql, mysql, mongodb, dynamodb, redis | 操作開始時 |
db.connection.string | string | データベース接続文字列(セキュリティを考慮) | host=localhost;port=5432(ログイン情報は含めない) | 操作開始時 |
db.user | string | データベースユーザー名(セキュリティを考慮) | app_user | 操作開始時 |
server.address | string | データベースサーバーのホスト名またはIP | localhost, db.example.com | 操作開始時 |
server.port | int | データベースサーバーのポート番号 | 5432 (PostgreSQL), 3306 (MySQL) | 操作開始時 |
操作関連属性
| 属性名 | 型 | 説明 | 例 | 記録タイミング |
|---|---|---|---|---|
db.collection.name | string | テーブル名またはコレクション名 | users, orders | 操作開始時 |
db.operation.name | string | 実行された操作の種別 | SELECT, INSERT, UPDATE, DELETE | 操作開始時 |
db.statement | string | 実行されたSQL文(簡潔に、機密情報は除外) | SELECT * FROM users WHERE id = ? | 操作開始時 |
db.response.row_count | int | クエリが返した行数 | 42 | 操作完了時 |
実装パターン
SQL データベース操作のトレース例
# Python で PostgreSQL クエリをトレースする場合
span.set_attributes({
"db.system": "postgresql",
"server.address": "db.example.com",
"server.port": 5432,
"db.collection.name": "users",
"db.operation.name": "SELECT",
"db.statement": "SELECT * FROM users WHERE status = ?",
})
# クエリ実行後
cursor.execute(query)
span.set_attribute("db.response.row_count", cursor.rowcount)NoSQL データベース操作のトレース例
# MongoDB での操作例
span.set_attributes({
"db.system": "mongodb",
"server.address": "mongodb.example.com",
"server.port": 27017,
"db.collection.name": "orders",
"db.operation.name": "find",
"db.statement": "db.orders.find({status: 'pending'})",
})セキュリティに関する注意点
db.statementにはパラメータ値(特にユーザーID、メールアドレス等)を含めないdb.connection.stringにはパスワードを含めない- ログイン情報が必要な場合は、
db.userのみを記録し、パスワードは絶対に含めない
RPC呼び出しの属性(rpc. namespace)
gRPC、JSON-RPC等の高性能なリモートプロシージャコール通信に関する属性です。
基本属性
| 属性名 | 型 | 説明 | 例 | 記録タイミング |
|---|---|---|---|---|
rpc.system | string | RPC通信システムの種別 | grpc, json_rpc | 呼び出し開始時 |
rpc.service | string | RPC サービスの名前 | helloworld.Greeter, myservice.PaymentService | 呼び出し開始時 |
rpc.method | string | RPC メソッドの名前 | SayHello, ProcessPayment | 呼び出し開始時 |
gRPC固有属性
| 属性名 | 型 | 説明 | 例 | 記録タイミング |
|---|---|---|---|---|
rpc.grpc.status_code | int | gRPC ステータスコード | 0 (OK), 3 (INVALID_ARGUMENT), 14 (UNAVAILABLE) | 呼び出し完了時 |
server.address | string | RPC サーバーのホスト名またはIP | rpc-service.example.com | 呼び出し開始時 |
server.port | int | RPC サーバーのポート番号 | 50051 | 呼び出し開始時 |
実装パターン
# gRPC クライアント呼び出しのトレース例
span.set_attributes({
"rpc.system": "grpc",
"rpc.service": "helloworld.Greeter",
"rpc.method": "SayHello",
"server.address": "greeter-service.default.svc.cluster.local",
"server.port": 50051,
})
# 呼び出し完了時
try:
response = stub.SayHello(request)
span.set_attribute("rpc.grpc.status_code", 0) # OK
except grpc.RpcError as e:
span.set_attribute("rpc.grpc.status_code", e.code().value[0])
span.set_status(StatusCode.ERROR)メッセージング関連の属性(messaging. namespace)
Kafka、RabbitMQ、AWS SQSなどのメッセージキューやイベントストリームに関する属性です。
基本属性
| 属性名 | 型 | 説明 | 例 | 記録タイミング |
|---|---|---|---|---|
messaging.system | string | メッセージング システムの種別 | kafka, rabbitmq, aws_sqs, azure_service_bus | 操作開始時 |
messaging.destination.name | string | トピック名、キュー名、エクスチェンジ名 | payment-events, user-queue | 操作開始時 |
messaging.operation | string | メッセージング操作の種別 | publish, receive, process | 操作開始時 |
messaging.message.id | string | メッセージの一意識別子 | msg-12345 | 操作開始時 |
messaging.batch.message_count | int | バッチで処理されたメッセージ数 | 10 | 操作完了時 |
Publish操作と Consumer操作
メッセージングでは、送信側(Publish)と受信側(Consumer)で異なるSpanが生成されます。これらは Trace Context を通じてリンクされます。
パブリッシュ側の属性
span.set_attributes({
"messaging.system": "kafka",
"messaging.destination.name": "order-events",
"messaging.operation": "publish",
"messaging.message.id": "msg-12345",
})コンシューマー側の属性
span.set_attributes({
"messaging.system": "kafka",
"messaging.destination.name": "order-events",
"messaging.operation": "receive",
"messaging.message.id": "msg-12345",
})リソース属性 - サービス識別情報
全てのテレメトリデータは、どのサービス・インスタンスから発生したのかを示すリソース属性が必須です。これはSpanの属性ではなく、テレメトリデータ全体に付加される特別な情報です。
最重要属性
| 属性名 | 型 | 説明 | 例 | 設定箇所 |
|---|---|---|---|---|
service.name | string | サービスの論理名(必須) | payment-service, user-api, order-processor | SDK初期化時 |
service.version | string | サービスのバージョン | 1.2.3, 2025-11-15 | SDK初期化時 |
deployment.environment | string | デプロイ環境 | production, staging, development | SDK初期化時 |
インスタンス識別関連属性
| 属性名 | 型 | 説明 | 例 | 設定箇所 |
|---|---|---|---|---|
service.instance.id | string | インスタンスの一意識別子 | server-01, pod-abc123 | SDK初期化時 |
host.name | string | ホスト名 | app-server-01.example.com | SDK初期化時 |
host.id | string | ホストのID(VM IDやコンテナIDなど) | i-0123456789abcdef0 | SDK初期化時 |
リソース属性設定の実装パターン
Python での設定例
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
resource = Resource.create({
"service.name": "payment-service",
"service.version": "1.2.3",
"deployment.environment": "production",
"service.instance.id": "server-01",
})
tracer_provider = TracerProvider(resource=resource)Java での設定例
Resource resource = Resource.builder()
.put("service.name", "payment-service")
.put("service.version", "1.2.3")
.put("deployment.environment", "production")
.put("service.instance.id", "server-01")
.build();
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setResource(resource)
.build();重要:service.nameを指定しない場合
service.name を指定しないと、トレーシングシステムは "unknown_service" という値を使用します。その結果:
- どのサービスから来たデータなのか識別不可能
- 複数サービスの監視が不可能
- アラート設定が機能しない
必ず明示的に設定してください。
属性選択の判断フロー
実装時に「どの属性を記録するべきか」判断するためのフロー図です。
カスタム属性の扱い
セマンティック規約に定義されていない、ビジネス固有の情報を記録したい場合があります。その際の実装パターンです。
カスタム属性の命名規則
セマンティック規約に従わないビジネス固有の属性を追加する場合は、以下の命名規則に従います:
app.<domain>.<attribute>例:
app.order.total_amount:注文の合計額app.user.customer_tier:顧客レベル(Gold、Silver等)app.transaction.correlation_id:トランザクション相関ID
実装例
# ビジネス固有の属性を追加する場合
span.set_attributes({
# セマンティック規約の属性
"http.request.method": "POST",
"http.response.status_code": 200,
# カスタム属性(app. prefix)
"app.order.total_amount": 15000,
"app.order.item_count": 3,
"app.user.customer_tier": "Gold",
})カスタム属性のガイドライン
- 過度に詳細な属性は避ける → ストレージコストが増加し、分析が複雑に
- セキュリティに配慮 → PII(個人識別情報)、パスワード、クレジットカード情報等は含めない
- ビジネス上の意味がある情報に限定 → デバッグ情報や一時的な中間値は含めない
- 属性数の目安 → 1つのSpanに対して 10~15個程度が適切
複数言語での属性設定の一貫性
Python、Java、Node.js等の異なる言語でマイクロサービスを実装する場合、セマンティック規約に従うことで自動的に一貫性が保証されます。
言語別の属性設定パターン比較
Python(OpenTelemetry SDK)
span.set_attributes({
"http.request.method": "GET",
"http.response.status_code": 200,
})Java(OpenTelemetry SDK)
span.setAttributes(Attributes.builder()
.put("http.request.method", "GET")
.put("http.response.status_code", 200)
.build());Node.js(OpenTelemetry SDK)
span.setAttributes({
"http.request.method": "GET",
"http.response.status_code": 200,
});どの言語を使用しても、属性の名前と値は全く同じです。これが「セマンティック規約」の力です。言語の違いを越えて、統一された形式でデータが整理されるため、運用チーム側の負担が大幅に軽減されます。
属性記録時のベストプラクティス
1. 属性の記録タイミング
属性によって最適な記録タイミングが異なります:
- 操作開始時に記録 → HTTPメソッド、DBシステム等、操作の種別を識別する情報
- 操作完了時に記録 → HTTPステータスコード、レスポンスサイズ等、結果の情報
- エラー発生時に記録 → エラーメッセージ、リトライ情報等
2. NULL値の扱い
属性値が不明な場合、NULLや空文字列を記録するのは避けます。記録しないか、デフォルト値を使用するほうが、分析側の処理が簡潔になります。
3. 高カーディナリティ属性への注意
ユーザーIDやセッションID等、取り得る値が非常に多い属性(高カーディナリティ属性)は、ストレージと分析パフォーマンスに大きな影響を与えます。本当に必要な場合のみに限定してください。
4. 定期的な見直し
実装後、実際に収集されたトレースデータを分析し、「本当に必要な属性か」を定期的に見直すことをお勧めします。不要な属性を削減することで、コスト削減と分析性能向上が実現できます。
まとめ
セマンティック規約に従った属性選択と記録は、OpenTelemetryの実装品質を大きく左右します。
重要なポイント:
- ドメイン別に定義された標準属性を優先して使用する
- セキュリティに配慮し、PII(個人識別情報)は含めない
- ビジネス固有の属性が必要な場合は、
app.プレフィックスで命名する service.nameは必須項目で、必ず設定する- 複数言語でも統一された属性名を使用することで、システム全体の可視性が向上する
実装の段階では、このリファレンスを参照しながら、各操作に適切な属性を選定してください。