アプリケーション Telemetry: 実践ガイド
アプリケーション テレメトリは、誰に対して何が起こったか、どれくらいの時間がかかったのか、結果が役に立ったかどうかについて、ソフトウェアが生成する構造化された証拠です。優れたテレメトリにより、製品、エンジニアリング、サポート、運用は、境界のないテキストから現実を再構築するのではなく、同じイベント契約からの質問に答えることができます。
このガイドでは、適切なシグナルを選択し、安全な結果イベントを設計し、配信し、SQL で検証し、ダッシュボードとアラートに変換する方法を示します。
有用なアプリケーション イベントは、出力境界からストレージおよび SQL 分析まで構造化されたままになります。
アプリケーション テレメトリにはどのようなものが含まれますか
ログ、メトリクス、トレース、構造化イベントは重なり合っていますが、それぞれに有用な重心があります。
| 信号 | 得意分野 | 典型的な質問 |
|---|---|---|
| 構造化されたイベント | 永続的なビジネスまたはアプリケーションの成果 | サインアップ後にアクティブ化に失敗したアカウントはどれですか? |
| ログ | 詳細な診断記録 | このプロセスでは、1 つの失敗に関して何が報告されましたか? |
| メトリック | 安価な総計の傾向 | リクエスト量やCPUが変化しているのでしょうか? |
| トレース | 分散作業による因果関係 | このリクエストが遅くなったのはどのスパンですか? |
1 つの信号を他の信号と強制的に置き換えないでください。端末 api_request_completed イベントには、エラー率ダッシュボードに必要なルート、アカウント、ステータス、期間、リリースを保持できます。トレースにより、どの依存関係がその期間を消費したかを説明できます。診断ログには、レビューされた技術メッセージを保存できます。インフラストラクチャ メトリックは、サービスがリソースに制約されているかどうかを示すことができます。
これらの信号間の共有識別子は、多くの場合、完全なペイロードを複製するよりも価値があります。
決断から始める
インストルメンテーションは質問とアクションから始める必要があります。
- 質問: リリース後に最も多くのアカウントで失敗する API ルートはどれですか?
- 決定: ロールバックするか、機能を無効にするか、依存関係を調査します。
- イベント:
api_request_completed. - Grain: 完了したリクエストが 1 つあります。
- ディメンション: ルート テンプレート、メソッド、ステータス コード、エラー カテゴリ、リリース。
- 測定値: ミリ秒単位の遅延。
- 安全な相関: リクエストとアカウントの識別子。
フィールドが既知のフィルター、グループ、計算、結合、調査、またはポリシーで使用されない場合は、フィールドを省略します。 「後で役立つかもしれない」という考えは、有用な答えを保証することなく、コスト、プライバシーのリスク、不安定なスキーマを生み出します。
1 つのイベント契約を設計する
端末リクエスト イベントは次のようになります。
{
"event_id": "evt_api_01",
"request_id": "req_2f71",
"account_id": "acct_8f31",
"route": "/v1/query/:id",
"method": "POST",
"status_code": 200,
"latency_ms": 184,
"error_type": null,
"release": "2026.07.3"
}
契約書には次のように記載する必要があります。
| プロパティ | 定義 |
|---|---|
| イベント名 | 安定した過去形の結果: api_request_completed |
| 穀物 | まさに 1 行が表すもの |
| 放出境界 | 最終的な結果が得られるまでのアプリケーションの状態変化 |
| オーナー | プロデューサーを担当するチームまたはサービス |
| 必須フィールド | 受け入れられたすべての行が持つ必要がある値 |
| 管理値 | 許可されるステータス、カテゴリ、メソッド、またはバージョン |
| 単位 | _ms, _bytes, _usd、または別の明示的な接尾辞 |
| プライバシークラス | 機密性が低い、匿名である、またはレビューが必要である |
| 保持の必要性 | 意思決定にデータが必要な期間 |
次のようなルート テンプレートを使用します。 /v1/query/:id、あらゆる識別子を新しい次元に変える生の URL ではありません。境界のあるものを使用する error_typeスタックトレースではありません。数値測定値は数値のままにし、安定した識別子は文字列型にします。
結果の境界で放出する
結果がわかっている場合にのみ結果を記録します。 HTTP リクエストの場合、通常は最終ステータスと期間が利用可能になった後です。
import telemetry from "telemetry-sh";
telemetry.init("YOUR_API_KEY");
async function recordRequest(context, response, startedAtMs) {
await telemetry.log("api_request_completed", {
event_id: crypto.randomUUID(),
request_id: context.requestId,
account_id: context.accountId,
route: context.routeTemplate,
method: context.method,
status_code: response.status,
latency_ms: Date.now() - startedAtMs,
error_type: response.error
? classifyRequestError(response.error)
: null,
release: process.env.APP_RELEASE ?? "unknown"
});
}
Telemetry は正規化中に null 値を削除するため、成功した行には何も格納されません。 error_type。クエリレイヤーが提供するのは、 timestamp_utc;その名前を持つクライアント提供のフィールドは削除されます。を参照してください。 ログ API 正確に受け入れられる形状と正規化ルールについて。
テレメトリ配信の失敗によって、完了したビジネス成果が重複した支払い、電子メール、ジョブ、またはリクエストに変更されないようにしてください。ワークフローのリスクに応じて、バッファリング、再試行、サンプリング、ドロップのいずれを行うかを決定します。同じものを再利用する event_id 同じ論理イベントの配信を再試行する場合.
相関のための識別子の選択
調査対象のエンティティに一致する識別子を使用します。
event_id1 つのテレメトリ イベントの重複を排除します。request_id1 つの申請に対して申請証拠をリンクします。job_idライフサイクル イベントと再試行を接続します。account_id顧客への影響を測定する。user_id承認された場合、アクターレベルの製品分析をサポートします。trace_id分散トレースへのリンク。
識別子は仮名のままにしてください。電子メール アドレス、アクセス トークン、セッション Cookie、プロンプト、ドキュメント、または完全な URL は便利な識別子ではありません。これは機密性の高いペイロード データです。
カーディナリティとペイロード サイズを制御する
カーディナリティは、フィールドが生成する個別の値の数です。カーディナリティの高い ID は調査や結合には便利ですが、デフォルトのダッシュボード グループには適していません。境界のないテキストが安全な分析次元となることはほとんどありません。
使用:
route: "/v1/query/:id"代わりに/v1/query/9be1...;error_type: "upstream_timeout"例外メッセージの代わりに。- アドホック表示ラベルの代わりに承認されたプロバイダー モデル識別子。
release: "2026.07.3"完全な展開マニフェストの代わりに。
境界付きフィールドでグループ化します。限定された調査結果でのみ識別子を選択します。取り込み後に考えられるすべての機密値を編集しようとするのではなく、リクエストおよびレスポンスの本文を省略します。
型と意味を安定させる
イベントの柔軟性は、混合タイプを送信する理由にはなりません。 latency_ms を交互に使用してはなりません 184, "184 ms"、そして "slow". account_id あるサービスのユーザーと別のサービスの組織を参照してはなりません。
通常、追加のオプション フィールドは最も安全な進化です。名前の変更、単位の変更、タイプの変更、または新しい行粒度には、移行または新しいイベント バージョンが必要です。フォローしてください スキーマ進化ガイド ダッシュボードやアラートを変更する前に、リリースごとに現場での採用状況を測定します。
ネストされたオブジェクトは便利な名前空間を作成できますが、すべての点線のパスは依然として契約です。参照 ネストされた JSON のクエリ.
イベント時間と取り込み時間を分離する
ビジネスまたはアプリケーションの結果がいつ発生したかを定義します。モバイル クライアント、キュー、オフライン エージェント、および再試行バッファの遅延により、その時点よりも遅れて配信される可能性があります。
サーバー生成のオンライン イベントの場合、Telemetry が管理します timestamp_utc 多くの場合、これは正しい運用クエリ時間です。ワークフローにソース イベント時間が必要な場合は、タイムゾーンで修飾された別の名前のタイムスタンプを送信し、遅延がレポートに与える影響を文書化します。現在のバケットの一部と過去のバケット全体を比較しないでください。
の タイムスタンプガイドの操作 UTC、Windows、および遅延到着データをカバーします。
最初の有用な質問をクエリする
境界のあるサンプルから始めます。
SELECT
timestamp_utc,
route,
status_code,
latency_ms,
release
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '1 hour'
ORDER BY timestamp_utc DESC
LIMIT 100;
次に、ボリューム、エラー率、影響を受けるアカウント、テール レイテンシーを計算します。
SELECT
route,
COUNT(*) AS requests,
SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors,
COUNT(DISTINCT CASE
WHEN status_code >= 500 THEN account_id
END) AS affected_accounts,
100.0 * SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0) AS error_rate_pct,
approx_percentile_cont(latency_ms, 0.95) AS p95_latency_ms
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY route
HAVING COUNT(*) >= 20
ORDER BY affected_accounts DESC, error_rate_pct DESC;
最小ボリューム ルールにより、単一の静かな障害が自動的にビジーな回帰よりも上位にランクされることがなくなります。重要な少量ワークフローには、一般的なリーダーボードではなく、独自のアラートが必要な場合があります。
すぐに意思決定ができるダッシュボードを構築する
アプリケーション信頼性ダッシュボードでは、読者が検出から範囲と証拠に移行できるようにする必要があります。
- リクエストまたはワークフローのボリューム。
- 完全な時間バケットにわたる成功率またはエラー率。
- p50 および p95 の潜伏期間。
- 影響を受けるアカウント。
- ルート、エラー カテゴリ、リリースごとの内訳。
- 調査のためのリクエスト ID を含む制限付きテーブル。
単位、時間範囲、分母、最小ボリューム、データの鮮度、およびイベント コントラクトに注釈を付けます。重要な SQL の横に合成結果または既知のフィクスチャを保存して、レビュー担当者がクエリが何を返すことを意図しているかを判断できるようにします。
を使用します。 API 信頼性ダッシュボードの例 そして API レイテンシ レシピ 完全な出発点として。
所有者が応答できる場合にのみアラートを送信する
アラート定義には、クエリ、正確な分母、完全な時間枠、しきい値またはベースライン、最小ボリューム、所有チーム、ランブック、最初の診断の内訳、および欠落データの動作が必要です。
例: p95 レイテンシが 3 つの完全なバケットのルート目標を超え、少なくとも 100 のリクエストが観察された場合、API 所有者に通知します。応答は、リリース、エラー カテゴリ、影響を受けるアカウント数を比較することから始まります。
テレメトリ パイプライン自体を監視します。フラット ゼロは、静かなアプリケーション、壊れたプロデューサ、配信の失敗、またはクエリ エラーを意味する可能性があります。の テレメトリ配信イベントのスキーマ そして 取り込み鮮度のレシピ 欠けている証拠を可視化します。
プライバシーとセキュリティを保護する
判断に必要な最低限の証拠を集めます。リリース前:
- すべての識別子と自由記述フィールドを分類します。
- シークレット、資格情報、Cookie、リクエスト本文、プロンプト、生成されたコンテンツを削除します。
- 仮名の内部 ID を使用します。
- アクターまたはリソースの識別子を公開する調査ビューを制限します。
- 文書化された運用ニーズまたは製品ニーズに基づいて保持期間を設定します。
- 成功したリクエストだけでなく、編集ブランチと失敗ブランチをテストします。
- データの管轄権と使用に関する削除とアクセスの要件を確認します。
読む 機密データの秘匿化 そして セキュリティの概要 ペイロードを拡張する前に。
パス全体を検証する
プロデューサー単体テストは必要ですが、十分ではありません。検証:
- 成功、失敗、タイムアウト、再試行、および重複ブランチ。
- フィールド名、タイプ、単位、および制御される値。
- API の受け入れとエラー処理。
- 宛先テーブル内の最近の生の行。
- 既知のフィクスチャに対する合計 SQL。
- ダッシュボードの時間枠と分母。
- アラートのしきい値、所有者、および欠落データの動作。
- 以前のプロデューサー バージョンのロールバック パス。
導入後のリリースごとにフィールド カバレッジとイベントのボリュームを追跡します。 ソースにコードパスが存在しても、本番環境で完全なイベントが送信されている証拠にはなりません.
成果を失わずにコストを管理
大々的に展開する前にボリュームを見積もる:
events per day
= requests per day
× events per request
× retained sample fraction
中間状態が使用されない場合は、複数の冗長な進行状況イベントよりも 1 つの最終結果イベントを優先します。成功した診断を大量にサンプリングするには、レートに必要な分母を保存した後でのみ行ってください。ポリシーで許可されている場合は失敗やまれに重大な結果を保持しますが、機密データを削除する代わりにサンプリングを使用しないでください。
文書化された所有者がいる最長の比較または調査期間に保持期間を合わせます。誰もクエリしないフィールドやイベントは、永続的なコストになる前に計画から削除する必要があります。
アプリケーション テレメトリ ロールアウト チェックリスト
- 質問、決定事項、所有者、および期待される応答を書きます。
- 1 つの行の粒度と正確な結果の境界を定義します。
- 必須フィールド、制御値、単位、および安全な識別子を選択します。
- プライバシー、濃度、保持、ボリュームを分類します。
- 代表的な成功、失敗、再試行、複製、ロールバックのフィクスチャを追加します。
- ビジネス運用セマンティクスを変更することなく、機器を配信します。
- 受け入れられた行と必須フィールドの範囲をリリースごとに確認します。
- 既知の結果に対して SQL をテストします。
- ダッシュボードの定義、鮮度、分母を公開します。
- 所有者と応答が明らかな場合にのみアラートを追加します。
- テレメトリ パイプライン自体を監視します。
- 最初の保持期間の後にフィールドを確認し、未使用のデータを削除します。
続けて イベントスキーマの設計, 構造化されたロギング、 イベントスキーマカタログ、そして エンドツーエンドの SaaS 可観測性デモ.