相関 ID
分散システムで 1 つのリクエストに紐づく全ログを追跡するための一意な識別子
相関 ID とは
相関 ID (Correlation ID) は、分散システムにおいて 1 つのユーザーリクエストが複数のサービスを横断する際に、全サービスのログを紐づけるための一意な識別子である。UUID v4 が一般的に使われる。
マイクロサービスアーキテクチャでは、1 つの HTTP リクエストが API Gateway → 認証サービス → 注文サービス → 決済サービス → 通知サービスのように 5〜10 のサービスを経由することがある。相関 ID がなければ、障害発生時に「どのリクエストが」「どのサービスで」「なぜ失敗したか」を突き止めるのに、各サービスのログをタイムスタンプだけで照合する羽目になる。本番環境で秒間数百リクエストが流れている状況では、事実上不可能だ。
伝播の仕組み
相関 ID の基本的な流れは 3 ステップで構成される。
- エントリーポイント (API Gateway やロードバランサー) でリクエストごとに一意な ID を生成する
- 下流サービスへのリクエストヘッダー (
X-Correlation-IDやX-Request-ID) に ID を付与して伝播する - 各サービスは受け取った ID を全ログ出力に含める
// 1. エントリーポイントで生成 or 受け取り
const correlationId = event.headers['x-correlation-id'] || crypto.randomUUID();
// 2. 全ログに自動付与 (Lambda Powertools の例)
const logger = new Logger({ persistentLogAttributes: { correlationId } });
logger.info('注文処理を開始', { orderId: '123' });
// 出力: {"correlationId":"a1b2c3...","message":"注文処理を開始","orderId":"123"}
// 3. 下流サービスへ伝播
await sqs.sendMessage({
MessageBody: JSON.stringify({ ...payload, correlationId }),
QueueUrl: QUEUE_URL,
MessageAttributes: {
'X-Correlation-ID': { DataType: 'String', StringValue: correlationId },
},
});
ポイントは、HTTP ヘッダーだけでなく SQS メッセージ属性や EventBridge のイベントペイロードにも相関 ID を含めることだ。非同期処理の境界で ID が途切れると、追跡が不可能になる。
相関 ID とトレース ID の違い
混同されやすいが、相関 ID と分散トレーシングのトレース ID は役割が異なる。
| 観点 | 相関 ID | トレース ID (X-Ray 等) |
|---|---|---|
| 生成元 | アプリケーションコード | トレーシング SDK が自動生成 |
| 伝播方法 | 明示的にヘッダーやペイロードに含める | SDK が自動的に伝播 |
| 用途 | ログの横断検索 | レイテンシ分析、サービスマップ |
| 永続性 | ログに残り続ける | トレースの保持期間に依存 |
実務では両方を併用する。X-Ray のトレース ID でレイテンシのボトルネックを特定し、相関 ID で該当リクエストの詳細ログを CloudWatch Logs Insights で掘り下げる、という使い分けだ。
AWS サービスでの実装パターン
API Gateway
$context.requestId を相関 ID として使用できる。アクセスログのフォーマットに含めておけば、API Gateway のログと Lambda のログを紐づけられる。ただし、クライアントが独自の相関 ID を送ってくる場合は、クライアントの ID を優先し、API Gateway の requestId はサブ ID として扱う設計が柔軟だ。
X-Ray
X-Ray のトレース ID (1-xxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx) は自動的にサービス間を伝播する。Lambda で X-Ray を有効にするだけで、API Gateway → Lambda → DynamoDB の呼び出しチェーンが可視化される。ただし X-Ray はサンプリングされるため、全リクエストを追跡するには相関 ID によるログベースの追跡が必要だ。
CloudWatch Logs Insights
相関 ID を構造化ログに含めておけば、1 つのリクエストに関する全ログを横断検索できる。
fields @timestamp, @log, @message
| filter correlationId = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
| sort @timestamp asc
複数のロググループ (API 用、注文処理用、決済用) を同時に検索できるため、サービスをまたいだリクエストの流れが時系列で把握できる。
よくある失敗パターン
非同期境界での途切れ
SQS や EventBridge を挟む非同期処理で相関 ID の伝播を忘れるケースが多い。同期的な HTTP 呼び出しでは意識しやすいが、メッセージキューを介すると「別のリクエスト」として扱ってしまいがちだ。メッセージ属性やイベントペイロードに必ず含める設計を最初から組み込む。
ログライブラリの設定漏れ
相関 ID を生成しても、一部のログ出力で含め忘れるケースがある。Lambda Powertools の Logger のように、一度設定すれば全ログに自動付与される仕組みを使うのが確実だ。console.log を直接使うと漏れる。
ID の衝突
UUID v4 の衝突確率は天文学的に低い (2^122 通り) が、タイムスタンプベースの短い ID を使うと衝突のリスクがある。本番環境では必ず UUID v4 か ULID を使う。
マイクロサービスやオブザーバビリティの技術書で、相関 ID を含む分散システムの可観測性設計が体系的に解説されている。
実践的な知識は関連書籍でも得られる。