プロンプトとスコープ
面接官は次のように質問する場合があります。「トレース相関をサポートする OpenTelemetry ログパイプラインを設計してください。データモデル、バックプレッシャー、テナント分離、リカバリについて説明してください。」
ここでの評価ポイントは、アプリケーションイベントをガバナンスの効いたテレメトリに変換できるかどうかです。OpenTelemetry Logs Data Model は、Timestamp、TraceId、SpanId、SeverityNumber、Body、Resource、Attributes を明確に分離しています。OTLP により、ログはエージェント、Collector、バックエンドをホップバイホップで移動できます。課題は単に Kafka のラインを1本引くことではなく、セマンティクス、キャパシティ、セキュリティ境界を適切に保護することです。
面接官が評価している点
- Resource、Attributes、Body、Trace Context の責務を分離できているか。
- アプリケーション、エージェント、Collector、キュー、バックエンドにまたがる信頼性の高いパスを設計できるか。
- バースト時のバックプレッシャー、バッチ処理、リトライ、優先度に基づくドロップ、ディスクバッファリングを適切に処理できるか。
- テナント間のデータ漏洩を防ぎ、シークレットや個人データをマスキング(墨消し)できるか。
- 重複、順序保証、サンプリング、および TraceId が存在しない場合のクエリ体験を説明できるか。
明確化のための質問
- ソースは SDK、既存のログファイル、コンテナの stdout、あるいはそれらの混在ですか?
- テナント数、スループット、保持期間、クエリレイテンシの目標値はどれくらいですか?
- アプリケーションは一貫して TraceId を注入しますか?また、存在しない場合に相関キーを使用することは許可されますか?
- どのフィールドに個人データ、シークレット、またはビジネス上の機密情報が含まれ、マスキングはどこで実行する必要がありますか?
- バックエンド障害時、どのレベルのログをドロップ可能ですか?また、復旧後にどれくらいの再生(リプレイ)が必要ですか?
30秒の回答例
次のように回答できます:
アプリケーションやファイルレシーバーからローカル Collector、次にキュー、そしてバックエンドへと至る階層化されたパスを採用します。各レコードは時刻、重大度、Body、Resource、Attributes を保持し、コンテキストが存在する場合は TraceId と SpanId を含めます。Collector はバッチ処理、レート制限、マスキング、ルーティングを行い、キューとディスクバッファがバックエンドのジッターを吸収します。テナント識別情報は信頼できる Resource 属性および認可インデックスに含めます。負荷急増時は、まず debug をドロップまたはサンプリングし、その後リトライ、重複、リカバリ時の読み出しを管理します。
ステップバイステップの思考プロセス
1つのレコード契約を定義する
非構造化テキスト行のみを契約としないでください。論理レコードは次のようになります:
{
"timestamp": "2026-08-01T10:00:00Z",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"spanId": "00f067aa0ba902b7",
"severityNumber": 17,
"severityText": "ERROR",
"body": {"message": "payment declined", "code": "CARD_DECLINED"},
"resource": {"service.name": "checkout", "tenant.id": "t-7"},
"attributes": {"region": "us-east-1"}
}Resource は発行元のエンティティを表し、Attributes はイベントの発生状況を表し、Body は構造化されたコンテンツを保持します。重大度の比較には SeverityNumber を使用し、表示用として元の SeverityText を保持します。
収集とトランスポートの設計
SDK またはファイルレシーバーがレコードを OTLP に変換します。ノードエージェントはバッチ処理を行い、初期の制限を適用します。Collector はパース、Resource データのエンリッチメント、マスキング、ルーティング、エクスポートを実行します。OTLP は中間 Collector をサポートしているため、長いパスでは明示的なタイムアウト、認証、圧縮が必要です。キューは必須ではありませんが、バックエンドのスループットが不安定な場合に、永続的なバッファリングとテナントごとのクォータ境界を提供できます。
バックプレッシャーとデータ分類の処理
テナントごとおよびサービスごとに、レート、バッチ、メモリ、ディスクの制限を設定します。バックエンドが遅延した場合は、エラー、監査、セキュリティイベントを保持しつつ、優先度の低いエクスポートを一時停止し、debug をサンプリングまたはドロップします。リトライストームを防ぐため、リトライには指数バックオフと最大保持時間が必要です。再生のために失敗したバッチ範囲を記録し、重複を減らすために冪等性またはバックエンドでの重複排除を使用します。
セキュリティ保護、分離、クエリの相関付け
シークレット、トークン、個人データは、エッジまたは Collector の早い段階で除去します。テナント識別情報は信頼できる Resource ソースから注入し、クライアントによる勝手な上書きは受け入れません。インデックスはテナントと時間でパーティショニングし、オプションで TraceId と SpanId の相関インデックスを付与します。TraceId のないログも、サービス、時間、リクエスト識別子によってクエリ可能な状態を維持します。それらしい TraceId を捏造してはなりません。
模範解答
設計をレコード契約、収集、バッファリング、処理、クエリの各レイヤーに分割します。レコードは時間、重大度、Body、Resource、Attributes に関して OpenTelemetry Logs Data Model に準拠し、アプリケーションにコンテキストがある場合は TraceId と SpanId を付加します。SDK または filelog レシーバーがノード Collector に送信し、Collector はバッチ処理、マスキング、テナントクォータの適用を行い、OTLP 経由でルーティングします。必要に応じてテナントごとの永続キューを使用します。バックエンドのジッターはメモリおよびディスクバッファによって吸収され、バジェットを超過した場合はドロップ率と最古レコードの経過時間を測定しながら、debug、info、error、audit の順にドロップします。クエリインデックスはテナントおよび時間で分離され、TraceId 相関によりコンテキストを捏造することなく調査を加速します。リカバリにはバッチ範囲、バックオフ、冪等な重複排除を使用し、監査ログおよびセキュリティログには個別の保持ポリシーとアクセス制御ポリシーを適用します。
よくある落とし穴
- すべてのフィールドを Body に格納し、Resource、Attributes、Trace Context のセマンティクスを失ってしまう。
- エージェント、Collector、キュー、ディスクバッファを挟まず、アプリケーションからバックエンドへの直接の線だけを描いてしまう。
- バックエンド障害時にメモリが枯渇して障害が連鎖するまで、無制限にリトライを繰り返す。
- クライアントがテナント属性を直接送信することを許可し、テナント横断的なインデックスを汚染してしまう。
- コンテキストを欠くログに対してランダムなトレース ID を生成し、調査を誤った方向に導いてしまう。
- 優先度ドロップ、マスキング、重複、リカバリのメトリクスに触れずにスループットだけを議論する。
フォローアップの質問と回答例
1. TraceId が存在しない場合はどうしますか?
元のログを保持し、コンテキストが存在しないものとしてマークします。相関付けには、検証可能なサービス名、時刻、リクエスト識別子を使用します。TraceId は、アプリケーションまたは信頼できるプロキシから提供された場合にのみ設定し、決して捏造してはなりません。
2. シークレットの漏洩をどのように防ぎますか?
SDK、エージェント、または Collector の早い段階でフィールドルールとパターンマスキングを適用し、明確なシークレットフォーマットを拒否した上で、テナントレベルのバックエンドアクセス制御を強制します。サンプリングされた生のログを保持する場合は、より厳格な分離と監査が必要です。
3. ログのドロップが許容されるのはどのような場合ですか?
まずビジネス上の分類を定義します。セキュリティ、監査、重大なエラーは通常保持されますが、debug やカーディナリティの高い診断フィールドはサンプリング可能です。容量圧迫の原因を説明可能にしアラートを上げられるよう、ドロップごとに理由、テナント、時間範囲、件数を記録します。