ネストされた JSON のクエリ
Telemetry は、ネストされた JSON オブジェクトをクエリ可能な点線フィールド パスに変換します。これにより、取り込み時に関連するコンテキストがまとめて保持され、同時に個々の値が SQL で利用可能になります。
このガイドでは、イベント コントラクトからフィルター、集計、スキーマ変更、トラブルシューティングまでの完全なパスを説明します。クエリをコピーする前にテーブル スキーマを検査してください。正確な識別子のスペルとタイプは、送信したイベントから取得されます。
安定したネストされたイベントを設計する
フィールドが 1 つの永続的な概念を形成する場合は、ネストされたオブジェクトを使用します。値を入力したままにし、機密性の高いペイロードを省略し、頻繁に変更される構造を配列に配置しないようにします。
{
"event_name": "tool_call_completed",
"event_id": "evt_7f31",
"account_id": "acct_8f31",
"release": "2026.07.3",
"workflow": {
"name": "answer_question",
"version": "v2"
},
"tool": {
"name": "inventory_lookup",
"outcome": "success",
"duration_ms": 184,
"usage": {
"input_units": 820,
"output_units": 244
}
}
}
行粒度は、1 つの完成したツール呼び出しです。 tool.duration_ms は常に数値であり、 tool.outcome 管理されたセットから取得され、識別子は仮名です。リクエスト引数、モデル プロンプト、生成されたコンテンツ、資格情報、生のエラー メッセージは意図的に省略されています。
SDK 経由でオブジェクトを送信します。
await telemetry.log("tool_call_completed", event);
ログ API は、クエリで使用される管理イベント時間を追加し、NULL 値、空のオブジェクト、および空の配列を再帰的に削除します。読む イベントのデータ型とnull許容性 ビジネス状態として空の値を使用する前に。
集計する前に検査する
境界のあるサンプルから始めます。テーブル スキーマに応じて、ネストされたパスは複合識別子として表示されるか、二重引用符で囲まれた 1 つのドット識別子を必要とする場合があります。
SELECT
timestamp_utc,
event_id,
workflow.name,
tool.name,
tool.outcome,
tool.duration_ms
FROM tool_call_completed
WHERE timestamp_utc >= now() - INTERVAL '1 hour'
ORDER BY timestamp_utc DESC
LIMIT 50;
スキーマがリテラルのドット付き列名を公開する場合は、完全なパスを引用符で囲みます。
SELECT
"workflow.name",
"tool.name",
"tool.duration_ms"
FROM tool_call_completed
LIMIT 50;
推測によって引用形式と引用形式を切り替えないでください。テーブル スキーマを確認し、小さなサンプルを実行し、保存されたフィールドと一致するフォームを使用します。
ネストされたフィールドのフィルターと集計
ネストされたフィールドは、フィルター、グループ、計算、および順序付けで機能します。このクエリは、ツールの量、失敗、および p95 の継続時間を完全な限定されたウィンドウにわたって比較します。
SELECT
tool.name AS tool_name,
COUNT(*) AS calls,
SUM(CASE WHEN tool.outcome = 'error' THEN 1 ELSE 0 END) AS errors,
100.0 * SUM(CASE WHEN tool.outcome = 'error' THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0) AS error_rate_pct,
approx_percentile_cont(tool.duration_ms, 0.95) AS p95_duration_ms
FROM tool_call_completed
WHERE timestamp_utc >= now() - INTERVAL '7 days'
AND workflow.name = 'answer_question'
GROUP BY tool.name
HAVING COUNT(*) >= 20
ORDER BY error_rate_pct DESC, calls DESC;
テーブルで引用符で囲まれたドット識別子が使用されている場合は、同じクエリ内の各完全パスを引用符で囲みます。
SELECT
"tool.name" AS tool_name,
approx_percentile_cont("tool.duration_ms", 0.95) AS p95_duration_ms
FROM tool_call_completed
WHERE "workflow.name" = 'answer_question'
GROUP BY "tool.name";
欠落しているパスを意図的に処理する
以前に作成された古い行 tool.usage.output_units 導入された場合にはそのフィールドはありません。 null、空のオブジェクト、または空の配列値を持つ新しいイベントも、正規化後にそのパスの値を格納しません。
使用する IS NULL 新しいフィールドに依存する前にカバレッジを測定するには:
SELECT
release,
COUNT(*) AS calls,
SUM(CASE WHEN tool.usage.output_units IS NULL THEN 1 ELSE 0 END)
AS missing_output_units,
100.0 * SUM(CASE WHEN tool.usage.output_units IS NULL THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0) AS missing_rate_pct
FROM tool_call_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY release
ORDER BY release;
ゼロがビジネス上の正しい意味である場合を除き、欠落している数値をゼロに置き換えないでください。 「報告されていない」、「該当なし」、および実際に測定されたゼロは異なる状態です。
ネストされたパスを安全に進化させる
各点線のパスをスキーマ コントラクトとして扱います。
| 変更 | 効果 | より安全な展開 |
|---|---|---|
追加 tool.usage.cache_hit |
既存の行には値がありません | 型付きフィールドを追加し、カバレッジを測定し、コンシューマーを更新します |
名前の変更 tool.name |
既存のクエリは引き続き古いパスを読み取ります | 移行中に古いパスと新しいパスを二重に書き込みます |
変更 tool.duration_ms 数値から文字列へ |
型の競合により取り込みが拒否される可能性がある | 新しい数値フィールドを追加して移行する |
移動 tool.outcome 別のオブジェクトに |
インプレイス移動ではなく、新しいパスを作成します | 契約をバージョンアップし、両方のパスを一時的にサポートします |
| 配列要素の形状を変更する | 不安定な分析契約を生成する | 永続的な結果ごとに 1 行を出力するか、固定の名前付きフィールドを使用します |
どの深さでも同じ意味とタイプを維持します。通常、オプションのネストされたフィールドの追加には互換性があります。パスのタイプを変更したり、新しい意味のために再利用したりすることはできません。
いつフラット化するかを決める
ネストされたオブジェクトは、次のような安定した名前空間に役立ちます。 tool, workflow、または billing。フラット フィールドは、ほぼすべてのクエリまたはダッシュボードで使用される場合に適しています。
次の場合には、フラットなフィールドまたは個別に放出されるフィールドを優先します。
- 値は行粒度または主要なイベントの結果を定義します。
- オペレーターはほぼすべての調査でそれをスキャンする必要があります。
- 複数のプロデューサーが 1 つの入れ子構造について合意することはできません。
- 配列は実際には複数の独立した結果を表します。
後でネストされたものからフラットなものに変更することは、スキーマの移行です。ペイロードの美しさではなく、質問と所有権の境界に基づいて選択してください。
ネストされたフィールド クエリのトラブルシューティング
クエリでネストされたパスが見つからない場合:
- 最近の生サンプルをクエリします。
LIMIT 50. - 正確なドット付きの名前とタイプについては、テーブル スキーマを調べてください。
- 別の SQL 方言から JSON 抽出構文を追加するのではなく、スキーマの引用符で囲まれた識別子の形式を試してください。
- プロデューサが実際に null や空ではない値を送信したことを確認します。
- 欠損値をグループ化する
releaseまたはプロデューサーバージョン。 - 古いプロデューサーと新しいプロデューサーの間で型の変更がないか確認します。
- 結合または集計を復元する前に、クエリを 1 つのフィールドと 1 つの最近の時間枠に減らします。
Telemetry は DataFusion SQL を使用するため、別のシステムからコピーされた PostgreSQL、BigQuery、Snowflake、または MySQL JSON 関数は適用されない可能性があります。で説明した構文を使用します。 DataFusion SQL リファレンス.
製作チェックリスト
- すべてのネストされたオブジェクトに 1 つの永続的な意味と所有者を与えます。
- すべてのパスのタイプ、単位、制御値を安定した状態に保ちます。
- シークレット、ユーザー コンテンツ、生のペイロード、および無制限のエラー テキストを除外します。
- 成功、失敗、欠落フィールド、および古いバージョンのフィクスチャをテストします。
- ダッシュボードやアラートをそれに依存させる前に、新しい分野の導入を測定します。
- 行粒度、保持の必要性、および移行計画を文書化します。
続けて イベントスキーマの設計, スキーマの進化、そして 必須フィールドのヌルレートレシピ.