アプリのアナリティクスイベントスキーマとクエリー
プレビュー
この機能は プライベート プレビュー段階です。試用については、Databricksの担当者にお問い合わせください。
このリファレンスを使用して、イベントプロデューサーを実装するか、Appアナリティクスイベントに対してクエリーを記述します。スキーマバージョン1、そのOpenTelemetry Protocol(OTLP)エンコーディング、および集計前に必要な処理ステップを定義します。
最初のイベントの例については、App アナリティクスを起動するを参照してください。ダッシュボードと追加のアプリ アクセス データについては、App Analytics とは何ですか?を参照してください。
イベントスキーマ
各イベントは、Unity Catalog 内のアプリの otel_logs テーブルに格納される OpenTelemetry ログレコードです。プレフィックスを含め、設定されたテーブル名を使用します。テーブルには他のLogsレコードも含まれているため、スキーマバージョンとイベントタイプでアナリティクス イベントを選択してください。
ペイロードの例
イベントタイプを選択すると、そのペイロードが表示されます。各例は、エクスポート時にresourceLogs[].scopeLogs[].logRecords[]に配置される1件のOTLPログレコードです。クイックスタートでは、そのリクエストラッパーについて説明しています。
以下の ID と Timestamp は例示です。新しいイベントごとに一意の ID を生成し、実際の発生時刻を使用します。例ではオプションのsession_idを省略しています。
- Action
- Page view
- Web Vital
完了したレポートのエクスポートを記録します。オプションのformatプロパティは、イベント名を変えずにエクスポートを記述します。
{
"timeUnixNano": "1790164800000000000",
"eventName": "report_exported",
"attributes": [
{ "key": "databricks.app.analytics.schema.version", "value": { "intValue": "1" } },
{ "key": "databricks.app.analytics.event.id", "value": { "stringValue": "d6c34165-7f4a-467c-b671-50ae495bcb14" } },
{ "key": "databricks.app.analytics.event.type", "value": { "stringValue": "action" } },
{ "key": "databricks.app.analytics.event.name", "value": { "stringValue": "report_exported" } },
{ "key": "databricks.app.analytics.properties.format", "value": { "stringValue": "csv" } }
]
}
/reports へのアクセスを記録します。イベントタイプとイベント名はどちらも page_view です。
{
"timeUnixNano": "1790164800000000000",
"eventName": "page_view",
"attributes": [
{ "key": "databricks.app.analytics.schema.version", "value": { "intValue": "1" } },
{ "key": "databricks.app.analytics.event.id", "value": { "stringValue": "caafc8e3-5f19-4f22-934b-09d1f8bf8e63" } },
{ "key": "databricks.app.analytics.event.type", "value": { "stringValue": "page_view" } },
{ "key": "databricks.app.analytics.event.name", "value": { "stringValue": "page_view" } },
{ "key": "databricks.app.analytics.page.path", "value": { "stringValue": "/reports" } }
]
}
1,800ミリ秒のLargest Contentful Paint(LCP)測定値を記録します。この値の評価はgoodです。
{
"timeUnixNano": "1790164800000000000",
"eventName": "lcp",
"attributes": [
{ "key": "databricks.app.analytics.schema.version", "value": { "intValue": "1" } },
{ "key": "databricks.app.analytics.event.id", "value": { "stringValue": "a23eecb7-b6c1-47c8-92ab-e2856f6ac804" } },
{ "key": "databricks.app.analytics.event.type", "value": { "stringValue": "web_vital" } },
{ "key": "databricks.app.analytics.event.name", "value": { "stringValue": "lcp" } },
{ "key": "databricks.app.analytics.page.path", "value": { "stringValue": "/reports" } },
{ "key": "databricks.app.analytics.web_vital.value", "value": { "doubleValue": 1800 } },
{ "key": "databricks.app.analytics.web_vital.unit", "value": { "stringValue": "ms" } },
{ "key": "databricks.app.analytics.web_vital.delta", "value": { "doubleValue": 1800 } },
{
"key": "databricks.app.analytics.web_vital.sample_id",
"value": { "stringValue": "30990ea0-3ec1-4a93-98b9-7c9abfe0e2d8" }
},
{ "key": "databricks.app.analytics.web_vital.rating", "value": { "stringValue": "good" } }
]
}
同じ測定のレポートで web_vital.sample_id が共有されます。新しいレポートにはそれぞれ event.id があります。See Web Vital rules.
共通フィールド
以下の論理フィールドは、すべてのイベントタイプに適用されます。それらの OTLP 属性名が上記の例に示されています。
フィールド | Type | 要件 | 説明 |
|---|---|---|---|
|
| 必須 | メジャー コントラクト バージョン。 |
|
| 必須 | グローバルに一意な不透明識別子。イベントを再試行する際に保持します。 |
|
| 必須 |
|
|
| 必須 | イベントタイプ内の低カーディナリティの名前。 |
|
| 必須 | イベントが発生した時であり、取り込まれた時ではありません。 |
|
| オプション | アナリティクスのアクティビティウィンドウの不透明な識別子。個人を特定しません。 |
|
| オプション |
|
| オブジェクト | オプション | アプリケーション定義のスカラープロパティ。 |
session_id はイベントスキーマではオプションです。セッションベースのメトリクスでは、それを提供するレコードが使用されます。存在しないセッションを表すために、IDを自作したり空の文字列を使用したりしないでください。
必須の文字列は空であってはならず、空白、資格情報、または個人データを含めてはなりません。オプショナルフィールドが存在する場合、そのフィールドルールに準拠する必要があります。存在しないオプショナル属性は、論理スキーマではnullとして読み込まれます。
イベントタイプ
イベントタイプ | イベント名 | 追加のフィールド |
|---|---|---|
|
| オプショナルプロパティでアクションの説明を行います。 |
|
| オプションの |
|
| Webバイタルルールで定義されているWebバイタルフィールド。 |
キャプチャされたアクションは、プロデューサーが記録した内容を説明します。たとえば、クリックによって、操作が成功したことを証明しなくても、意図を記録できる場合があります。
OTLPエンコーディングとテーブルフィールド
Analytics 属性は databricks.app.analytics. 名前空間を使用します。次の表は、論理フィールドを OTLP およびテレメトリテーブルにマッピングするものです。
論理フィールド | OTLPソース |
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
次の OTLP JSON エンコーディングを使用します。
- タイムスタンプ:
timeUnixNanoにおける Unix ナノ秒の10進文字列。 - 整数:
{ "intValue": "1" }などの十進文字列intValue。 - 倍精度浮動小数点数(Double):
{ "doubleValue": 1.25 }などの数値doubleValue。 - 文字列:
stringValue。 - Boolean:
boolValue。
ログレコードの eventName をアナリティクスの event_name 属性と同じ値に設定します。インストルメンテーション scope.name はプロデューサーを特定しますが、アナリティクス レコードのセレクターではありません。
テレメトリテーブルでは、ゼロを含む数値に対して、単一フィールドのdoubleValueラッパーを保持できます。数値フィールドを検証する前に、そのラッパーをデコードします。数値のように見える文字列を数値として受け入れるのではなく、キャストする前に元の値の型を検証します。
物理的な date 列は、パーティションプルーニングに使用できます。それは論理的なイベントスキーマの一部ではありません。
フィールドの制約
エクスポートする前にフィールドをサニタイズします。クエリーでのバリデーションとプロジェクションは、テレメトリテーブルにすでに格納されている生データを削除しません。
アクション名とプロパティ
アクション名には1~128文字を使用します。小文字で始まり、小文字、数字、ドット、アンダースコアを使用します。英数字のセグメントはドットとアンダースコアで区切られます。文法は^[a-z][a-z0-9]*([._][a-z0-9]+)*$です。
ID、Eメールアドレス、またはユーザーが入力したテキストを埋め込むのではなく、安定した名前を使用します。プロパティに変動する詳細を指定します。たとえば、すべての形式に対して異なるアクション名を使用するのではなく、format プロパティとともに report_exported を使用します。
プロパティキーも同じ文法に従います。analytics、identity、session、telemetry、url、user、users、email、password、passwd、secret、token、authorization、cookie、username、ip、credential、api_key、private_key、html、dom、selector、selectors、stack、stacktrace、text、input、referrer を含め、予約済みの名前空間や機密性の高いセグメントを使用しないでください。これらの制限はアクション名にも適用されます。
プロパティには、スカラー文字列、有限数、ブール値を含めることができます。配列、ネストされたオブジェクト、空値、資格情報、個人データは許可されません。
上限 | Value |
|---|---|
イベントあたりのプロパティ | 50 |
プロパティキーの長さ | 128文字 |
文字列値の長さ | 1,024文字 |
クエリーのプロジェクションでは、これらの制約を満たさないプロパティが除外されます。プロデューサーは、送信する値の意味に対して引き続き責任を負います。構文チェックだけでは、値が非個人データであることを確立できません。
ページのパス
page_pathは/で始まり、具体的なアプリケーションパスを含みます。クエリー文字列とフラグメントを削除し、機密性の高いパスセグメントをサニタイズします。パスに資格情報、個人データ、またはユーザーが入力したテキストを送信しないでください。
無効なパスは、クエリープロジェクションから除外されます。パスのないページビューは有効なままですが、ルートレベルの集約には寄与しません。
セッション
アナリティクスセッションは、最上位のブラウザーコンテキストに属します。プロデューサーがセッションIDを提供する場合、クライアント側のナビゲーションや再読み込みの間もそれを維持し、記録されたアナリティクスイベントなしで30分経過した後に更新します。
セッション ID は難読化されている必要があり、ユーザー ID、Eメールアドレス、IP アドレス、リクエスト ID、ジョブ ID、アクセストークンから派生したものであってはなりません。利用可能な場合、バックエンドイベントは発生元のセッションを保持します。リプレイされたイベントは、元のセッションとイベント時刻を保持します。
セッションは、一意のユーザーではなく、アクティビティウィンドウを測定します。製品内の閲覧者メトリクスでは、個別のアプリアクセスデータを使用できます。
Web Vital ルール
Web Vital イベントには次のフィールドが追加されます。値とデルタを OTLP doubleValue 属性としてエンコードし、残りのフィールドを stringValue 属性としてエンコードします。Web Vital 固有のフィールドは、アクションおよびページビューに含めない必要があります。
フィールド | 要件 | 説明 |
|---|---|---|
| 必須 | サンプルの有限かつ非負の累積値。 |
| 必須 |
|
| 必須 | 前回のレポート以降の、有限の非負の変化。 |
| 必須 | 1つのサンプルのレポートによって共有される、グローバルに一意な識別子。 |
| 必須 |
|
| オプション |
|
次の表では、単位と threshold について定義しています。
メトリクス | 名前 | 単位 | 良い | 低 |
|---|---|---|---|---|
| Largest Contentful Paint (LCP) |
| ≤ 2,500 | > 4,000 |
| Interaction to Next Paint(INP) |
| ≤ 200 | > 500 |
| Cumulative Layout Shift(CLS) |
| ≤ 0.1 | > 0.25 |
| First Contentful Paint(FCP) |
| ≤ 1,800 | > 3,000 |
| Time to First Byte(TTFB) |
| ≤ 800 | > 1,800 |
LCP、INP、CLSはCore Web Vitalsです。FCPおよびTTFBは、追加のパフォーマンス測定値を提供します。値は、Goodのthreshold以下ではgood、Poorのthresholdより上ではpoor、その間ではneeds_improvementになります。単位や評価が一致しない場合、レコードは無効になります。
1つのサンプルから複数のレポートを生成できます。Web Vitals はドキュメントのナビゲーションを表します。クライアント側のルート変更により、新しい Web Vital サンプルを生成することなく、ページビューを生成できます。サーバーはブラウザの測定値を転送できますが、サーバーのタイミングはその測定値の代わりにはなりません。
検証順序
次の順序でレコードを処理します。
- サポートされているスキーマバージョンとイベントタイプを選択します。このスキーマについては、バージョン
1とaction、page_view、またはweb_vitalを選択してください。 - 入力された属性をデコードし、有効な
event_id、event_name、occurred_atの値を要求します。 - イベントタイプのフィールド、名前、単位、評価、フィールドの制約を検証します。必須フィールドが無効なレコードを除外して、許可されたオプションデータのみを射影します。
- 競合するイベントIDを検出し、同一のデリバリーの重複を排除します。
- 分析の間隔、およびパスやイベントのフィルターを選択します。
- Webバイタルでは、重複するレポートをサンプルごとに1つに減らしてください。
- 結果として得られるイベントまたはサンプルを集計します。
検証を、取り込み診断から分離した状態に維持します。otel_logs 内の行の検索では、それがイベントスキーマに準拠していることは確立されません。
重複排除とサンプルの削減
イベントの同一の配信は、1つのイベントとしてカウントされます。異なる論理イベントコンテンツに対してevent_idが再利用される場合は、その競合セット内のすべてのレコードを除外し、データ品質の問題として競合を報告します。セットから任意の配信を選択しないでください。
任意フィールドやプロパティを含む、正規化された論理コンテンツを比較します。プロパティの確定的表現を使用して、キーの順序付けが誤った競合を引き起こさないようにします。トランスポート メタデータは、論理イベント コンテンツの一部ではありません。再試行でも元のイベント Timestamp が保持されます。
分析時間範囲を適用する前に、候補となる各イベントIDの保持された配信全体で整合性を確認してください。生の配信を最初にフィルタリングすると、その範囲外にある競合するコンテンツを非表示にすることができます。
重複排除と分析間隔の選択の後、web_vital_sample_idごとの最新のレポートを保持します。レポートをoccurred_atで並べ替え、同点の場合はevent_idで順序を決定し、両方とも降順にします。この削減の後にパーセンタイルを計算します。
メトリクスの定義
時間間隔には start_time が含まれ、end_time は除外されます。タイムバケットには協定世界時(UTC)を使用します。
メトリクス | 定義 |
|---|---|
ページビュー | 重複排除された |
セッション | 選択したアナリティクスイベントにおける、重複しない、NULLではない |
追跡されたアクション | 重複排除された |
セッションあたりのページ数 | セッション数で割ったページビュー。セッション数がゼロの場合は値はありません。 |
上位のアクション |
|
上位ページ |
|
Web Vital p75 | イベントの重複排除とサンプルの削減後の、ニアレストランク 75 パーセンタイル。 |
Webバイタルのサンプルサイズ | 削減後の重複しないサンプルの数。 |
最新のイベント | 選択されたアナリティクスイベントの中で最大の |
N個の順序付きサンプルの場合、1ベースのインデックスを使用するnearest-rank p75では、位置ceil(0.75 × N)の値を使用します。30未満のWeb Vitalサンプルは、決定的な証拠ではなく、傾向を示すものとして扱ってください。
このスキーマでは、ユーザーID、デバイス、ブラウザ、または地理的ディメンションが定義されていません。製品サーフェスには、他のソースからの追加のメトリクスが表示される場合があります。特に、ダッシュボードのユニーク閲覧者数は、アナリティクスセッションをコンピュートされるわけではありません。
例:検証済みイベントからWebバイタルのp75を計算
次のクエリーは、衝突除外、重複排除、サンプル削減、および正確なパーセンタイル計算を示しています。未加工の otel_logs テーブルではなく、正規化されたデータセットを使用します。
入力を準備します
独自の処理 パイプライン で、検証順序 のステップ 1 から 3 を適用する入力ビューを作成します。ビューには次のデータが含まれている必要があります:
- 重複排除や時間範囲のフィルタリングを行う前に、検証を通過した配信につき1行。
event_id、occurred_at、event_type、event_name、web_vital_value、およびweb_vital_sample_idを含む、型付きの論理フィールド。- すべての正規化されたイベントフィールドとプロパティの決定論的表現を含む、null以外の
logical_content文字列。欠落しているオプショナルフィールドを統一的に表現し、元のイベント時刻を維持します。
分析しているアプリに入力をスコープ設定します。サポートされているすべてのイベントタイプの保持された配信を含めることで、タイプ間でイベント ID が再利用されたことが検出されるようにします。入力は、上記のすべての必須フィールド、数値の型と範囲、単位、評価、およびイベントタイプの制約を強制する必要があります。
この入力ビューは、アプリテレメトリを有効にして作成されたものではありません。これは処理パイプラインによって提供される前提条件です。少数の生属性のキャストは、この検証ステップの代わりにはなりません。
検証済みの入力を集約します
<catalog>.<schema>.<validated-events-view>を入力ビューに置き換えます。SQLエディターで、:start_timeと:end_timeをTimestampパラメーターとして設定します。
WITH event_id_quality AS (
SELECT event_id, COUNT(DISTINCT logical_content) AS content_count
FROM <catalog>.<schema>.<validated-events-view>
GROUP BY event_id
),
deduplicated AS (
SELECT events.*
FROM <catalog>.<schema>.<validated-events-view> AS events
JOIN event_id_quality AS quality USING (event_id)
WHERE quality.content_count = 1
QUALIFY ROW_NUMBER() OVER (
PARTITION BY event_id ORDER BY occurred_at
) = 1
),
samples AS (
SELECT *
FROM deduplicated
WHERE event_type = 'web_vital'
AND occurred_at >= :start_time
AND occurred_at < :end_time
QUALIFY ROW_NUMBER() OVER (
PARTITION BY web_vital_sample_id ORDER BY occurred_at DESC, event_id DESC
) = 1
)
SELECT
event_name,
COUNT(*) AS sample_size,
PERCENTILE_DISC(0.75) WITHIN GROUP (ORDER BY web_vital_value) AS p75
FROM samples
GROUP BY event_name
ORDER BY event_name;
PERCENTILE_DISC 近似値ではなく、要求されたランクで観測された値を返します。クエリーでは、時間範囲を選択する前に、競合するイベントIDが除外されます。content_countが1を超えるトラックIDを、データ品質エラーとして個別に追跡します。
たとえば、値が100、200、300ミリ秒の3つの削減されたLCPサンプルから、sample_size = 3とp75 = 300が生成されます。同一の再配信では、そのサンプル数は増加しません。正規化されたコンテンツが競合するイベントIDは、レコードとしてカウントされません。
バージョニング
schema_version プロデューサーパッケージのバージョンとは独立して、メジャーコントラクトのバージョンを特定します。
オプションのフィールドやアプリケーション定義のアクション名の追加は、後方互換性があります。必須フィールドの削除、またはその型、意味、識別子のスコープ、セッションセマンティクスの変更には、メジャーバージョンの変更が必要です。重複排除、サンプル削減、またはイベントタイプのセマンティクスの変更にも、新しいメジャーバージョンが必要です。
コンシューマーは、サポートされていないバージョンやイベントタイプをアクションとして解釈するのではなく、無視します。