Schéma d’événements et queries d’App Analytique
Aperçu
Cette fonctionnalité est en aperçu privé. Pour l'essayer, veuillez contacter votre contact Databricks.
Utilisez cette référence pour implémenter un producteur d'événements ou pour écrire des query sur les événements d'App Analytics. Il définit la version de schéma 1, son encodage OpenTelemetry Protocol (OTLP) et les étapes de traitement nécessaires avant l'agrégation.
Pour un exemple de premier événement, consultez Get start with App analytique. Pour le tableau de bord et ses données d'accès à l'application supplémentaires, consultez What is App Analytics?.
Schéma d'événement
Chaque événement est un enregistrement de log OpenTelemetry stocké dans la table otel_logs de l'application dans Unity Catalog. Utilisez le nom de table configuré, y compris l'éventuel préfixe. La table contient également d'autres enregistrements de log ; par conséquent, sélectionnez les événements d'analytique par leur version de schéma et leur type d'événement.
Exemples de charges utiles
Sélectionnez un type d'événement pour afficher sa charge utile. Chaque exemple est un enregistrement de log OTLP, placé dans resourceLogs[].scopeLogs[].logRecords[] lors de l'exportation. Le démarrage rapide illustre ce wrapper de requête.
Les ID et le Timestamp ci-dessous sont indicatifs. Générez un ID unique pour chaque nouvel événement et utilisez son heure d’occurrence réelle. Les exemples omettent l’élément optionnel session_id.
- Action
- Page view
- Web Vital
Enregistrer une exportation de rapport terminée. La propriété optionnelle format décrit l'exportation sans modifier le nom de l'événement.
{
"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" } }
]
}
Enregistrez une visite de /reports. Le type d'événement et le nom d'événement sont tous deux 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" } }
]
}
Enregistrer une mesure Largest Contentful Paint (LCP) de 1 800 millisecondes. Cette valeur a une note de 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" } }
]
}
Les rapports d’une même mesure partagent un web_vital.sample_id. Chaque nouveau rapport a son propre event.id. Voir les règles Web Vital.
Champs courants
Les champs logiques suivants s’appliquent à tous les types d’événement. Leurs noms d’attributs OTLP apparaissent dans les exemples ci-dessus.
Champ | Type | Exigence | Description |
|---|---|---|---|
|
| Obligatoire | Version majeure de contrat. Utilisez |
|
| Obligatoire | Identifiant opaque et globalement unique. Conservez-le lors d’une nouvelle tentative sur un événement. |
|
| Obligatoire |
|
|
| Obligatoire | Nom à faible cardinalité au sein du type d’événement. |
|
| Obligatoire | Lorsque l’événement s’est produit, et non lorsqu’il a été ingéré. |
|
| Facultatif | Un identifiant opaque pour une fenêtre d’activité analytique. Il n’identifie pas de personne. |
|
| Facultatif | Un chemin d’application concret assaini, tel que |
| Objet | Facultatif | Propriétés scalaires définies par l’application. |
session_id est optionnel dans le schéma d'événements. Les métriques basées sur les sessions utilisent les enregistrements qui les fournissent. Ne créez pas artificiellement d'identité et n'utilisez pas de chaîne vide pour représenter une session absente.
Les chaînes obligatoires ne doivent pas être vides et ne doivent contenir ni espaces, ni informations d'identification, ni données personnelles. Lorsqu'un champ facultatif est présent, il doit se conformer à ses règles de champ. Un attribut facultatif absent est lu comme null dans le schéma logique.
Types d'événement
Type d'événement | Nom d’événement | Champs supplémentaires |
|---|---|---|
| Un nom défini par l'application, tel que | Les propriétés optionnelles décrivent l'action. |
|
| Un ou une |
|
| Les champs Web Vital définis dans les règles Web Vital. |
Une action capturée décrit ce que le producteur a enregistré. Par exemple, un clic peut enregistrer une intention sans prouver que l'opération a réussi.
Encodage OTLP et champs de table
Les attributs analytiques utilisent le namespace databricks.app.analytics.. Le tableau suivant associe les champs logiques à l’OTLP et à la table de télémétrie :
Champ logique | Source OTLP |
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| La clé correspondante dans |
|
| La clé correspondante dans |
Utilisez les encodages JSON OTLP suivants :
- Timestamp : une chaîne décimale de nanosecondes Unix dans
timeUnixNano. - Integers : une chaîne décimale
intValue, telle que{ "intValue": "1" }. - Doubles : une
doubleValuenumérique, telle que{ "doubleValue": 1.25 }. - Chaînes :
stringValue. - Booléens :
boolValue.
Définissez le eventName de l'enregistrement de log sur la même valeur que l'attribut d'analytique event_name. L'instrumentation scope.name identifie le producteur, mais ne constitue pas un sélecteur pour les enregistrements d'analytique.
La table de télémétrie peut conserver un wrapper doubleValue à champ unique pour les valeurs numériques, y compris zéro. Décodez ce wrapper avant de valider les champs numériques. Validez le type de la valeur d’origine avant de la convertir, plutôt que d’accepter une chaîne ayant l’apparence d’un nombre en guise de nombre.
La colonne physique date est disponible pour l'élagage des partitions. Il ne fait pas partie du schéma d’événements logique.
Contraintes de champ
Désinfectez les champs avant l’exportation. La validation et la projection dans une query ne suppriment pas les données brutes déjà stockées dans la table de télémétrie.
Noms d’actions et propriétés
Les noms des actions contiennent de 1 à 128 caractères. Elles commencent par une lettre minuscule et utilisent des lettres minuscules, des chiffres, des points et des traits de soulignement. Les points et les traits de soulignement séparent les segments alphanumériques. La grammaire est ^[a-z][a-z0-9]*([._][a-z0-9]+)*$.
Utilisez des noms stables au lieu d'intégrer des identifiants, des adresses e-mail ou du texte saisi par l'utilisateur. Placez les détails variables dans les propriétés. Par exemple, utilisez report_exported avec une propriété format plutôt qu'un nom d'action différent pour chaque format.
Les clés de propriété suivent la même grammaire. N'utilisez pas d'espaces de noms réservés ni de segments sensibles, notamment 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 ou referrer. Ces restrictions s'appliquent également aux noms d'action.
Les propriétés peuvent contenir des chaînes scalaires, des nombres finis et des booléens. Les tableaux, les objets imbriqués, les valeurs nulles, les informations d’identification et les données personnelles ne sont pas autorisés.
Limite | Valeur |
|---|---|
Propriétés par événement | 50 |
Longueur de la clé de propriété | 128 caractères |
Longueur de la valeur de chaîne | 1 024 caractères |
Les projections de query omettent les propriétés qui ne satisfont pas à ces contraintes. Les producteurs restent responsables de la signification des valeurs qu’ils envoient. Les contrôles syntaxiques à eux seuls ne permettent pas d’établir qu’une valeur n’est pas personnelle.
Chemins d'accès de la page
Un page_path commence par / et contient le chemin d'accès de l'application concrète. Supprimez les chaînes de query et les fragments, et nettoyez les segments de chemin sensibles. Ne transmettez pas d'identifiants, de données personnelles ni de texte saisi par l'utilisateur dans un chemin d'accès.
Un chemin non valide est omis de la query projection. Une vue de page sans chemin reste valide, mais ne contribue pas aux agrégations au niveau de l'itinéraire.
Sessions
Une session d'analytique appartient à un contexte de navigateur de niveau supérieur. Lorsqu'un producteur fournit un ID de session, conservez-le de manière stable lors de la navigation et des rechargements côté client, et renouvelez-le après 30 minutes sans événement d'analytique enregistré.
Les ID de session doivent être opaques et ne doivent pas dériver d'identités d'utilisateurs, d'adresses e-mail, d'adresses IP, d'ID de requête, d'ID de job ou de jetons d'accès. Les événements du backend conservent la session d'origine lorsqu'elle est disponible. Les événements rejoués conservent leur session et leur heure d'événement d'origine.
Une session mesure une fenêtre d'activité, et non une personne unique. Les métriques des spectateurs dans le produit peuvent utiliser des données d'accès à l'application distinctes.
Règles Web Vital
Les événements Web Vital ajoutent les champs suivants. Encoder la valeur et le delta en tant qu’attributs OTLP doubleValue et les champs restants en tant qu’attributs stringValue. Les champs spécifiques à Web Vital doivent être absents sur les actions et les pages vues.
Champ | Exigence | Description |
|---|---|---|
| Obligatoire | Valeur cumulative finie et non négative pour l'échantillon. |
| Obligatoire |
|
| Obligatoire | Changement fini et non négatif depuis le rapport précédent. |
| Obligatoire | Identifiant unique global partagé par les rapports pour un échantillon. |
| Obligatoire |
|
| Facultatif |
|
Le tableau suivant définit les unités et les threshold :
Métrique | Nom | Unité | Bon | Médiocre |
|---|---|---|---|---|
| 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 |
| Temps jusqu'au premier octet (TTFB) |
| ≤ 800 | > 1 800 |
Les indicateurs LCP, INP et CLS sont des Core Web Vitals. FCP et TTFB fournissent des mesures de performance supplémentaires. Une valeur est good si elle est inférieure ou égale au threshold Good, poor si elle est supérieure au threshold Poor, et needs_improvement si elle se situe entre les deux. Une unité ou une évaluation non correspondante invalide l’enregistrement.
Un échantillon peut produire plusieurs rapports. Les métriques Web Vitals décrivent la navigation dans les documents. Un changement de route côté client peut produire une vue de page sans produire de nouvel échantillon Web Vital. Un serveur peut transmettre une mesure de navigateur, mais les minutages du serveur ne remplacent pas cette mesure.
Ordre de validation
Traitez les enregistrements dans l'ordre suivant :
- Sélectionnez des versions de schéma et des types d’événements pris en charge. Pour ce schéma, sélectionnez la version
1etaction,page_viewouweb_vital. - Décodez les attributs typés et exigez des valeurs
event_id,event_nameetoccurred_atvalides. - Validez les champs de type d'événement, les noms, les unités, les notes et les contraintes de champ. Excluez les enregistrements avec des champs obligatoires non valides et projetez uniquement les données facultatives autorisées.
- Détectez les ID d'événements en conflit et dédupliquez les livraisons identiques.
- Sélectionnez l'intervalle d'analyse et tous les filtres de chemin ou d'événement.
- Pour les indicateurs Web Vitals, réduisez les rapports répétés à un seul rapport par échantillon.
- Agrégez les événements ou échantillons résultants.
Veuillez dissocier la validation des diagnostics d'ingestion. Trouver une ligne dans otel_logs ne garantit pas qu'elle est conforme au schéma d'événement.
Déduplication et réduction d’échantillons
Les diffusions identiques d’un événement comptent pour un seul événement. Si un event_id est réutilisé pour un contenu d’événement logique différent, excluez chaque enregistrement de cet ensemble de conflits et signalez le conflit comme un problème de qualité des données. Ne choisissez pas de diffusion arbitraire dans l’ensemble.
Comparez le contenu logique normalisé, y compris les champs et les propriétés facultatifs. Utilisez une représentation déterministe des propriétés afin que l’ordre des clés ne crée pas de faux conflits. Les métadonnées de transport ne font pas partie du contenu de l’événement logique. Les nouvelles tentatives conservent le Timestamp de l’événement d’origine.
Vérifiez l’identité de l’ensemble des livraisons conservées pour chaque ID d’événement candidat avant d’appliquer l’analyse de la plage de temps. Le filtrage préalable des livraisons brutes peut masquer le contenu en conflit situé en dehors de cette plage.
Après la déduplication et la sélection de l'intervalle d'analyse, conservez le dernier rapport par web_vital_sample_id. Trier les rapports par occurred_at, en départageant les égalités avec event_id, tous deux par ordre décroissant. Calculez les centiles après cette réduction.
Définitions d'indicateurs
Les intervalles de temps incluent start_time et excluent end_time. Les blocs de temps utilisent le temps universel coordonné (UTC).
Métrique | Définition |
|---|---|
Vues de page | Nombre d'événements |
Sessions | Nombre de valeurs |
Actions suivies | Nombre d'événements |
Pages par session | Nombre de pages vues divisé par le nombre de sessions. Aucune valeur lorsque le nombre de sessions est nul. |
Principales actions | Actions regroupées par |
Top des pages | Vues de page regroupées par |
Web Vital p75 | 75e centile du rang le plus proche après la déduplication des événements et la réduction des échantillons. |
Taille d’échantillon des Web Vitals | Nombre d'échantillons distincts après réduction. |
Dernier événement |
|
Pour N échantillons ordonnés, le percentile p75 fondé sur le rang le plus proche utilise la valeur à la position ceil(0.75 × N), avec une indexation commençant à un. Traitez moins de 30 échantillons Web Vital comme des indications plutôt que comme la preuve concluante d’une tendance.
Ce schéma ne définit pas de dimensions d'identité utilisateur, d'appareil, de navigateur ou de géographie. Les surfaces produit peuvent afficher des métriques supplémentaires provenant d'autres sources. En particulier, les utilisateurs uniques du tableau de bord ne sont pas calculés en comptant les sessions analytiques.
Exemple : calculer le p75 de Web Vital à partir des événements validés
La query suivante démontre l'exclusion de collisions, la déduplication, la réduction d'échantillons et le calcul exact des percentiles. Elle consomme un dataset normalisé, et non la table brute otel_logs.
Préparer l'entrée
Créez une vue d'entrée dans votre propre pipeline de traitement qui applique les étapes 1 à 3 de l'ordre de validation. La vue doit contenir les données suivantes :
- Une ligne par livraison qui réussit la validation, avant la déduplication ou le filtrage par plage temporelle.
- Les champs logiques typés, y compris
event_id,occurred_at,event_type,event_name,web_vital_valueetweb_vital_sample_id. - Une chaîne
logical_contentnon nulle contenant une représentation déterministe de tous les champs et propriétés d'événements normalisés. Représentez les champs facultatifs absents de manière cohérente et préservez l'heure de l'événement d'origine.
Délimitez l'entrée pour l'application que vous analysez. Incluez les diffusions conservées de tous les types d’événements pris en charge afin de détecter la réutilisation d’un ID d’événement entre différents types. L'entrée doit appliquer tous les champs obligatoires, les types et plages numériques, les unités, les évaluations et les contraintes de type d'événement décrits ci-dessus.
Cette vue d'entrée n'est pas créée en activant la télémétrie de l'application. Il s'agit d'un prérequis fourni par votre pipeline de traitement. La conversion de quelques attributs bruts ne remplace pas cette étape de validation.
Agréguer l'entrée validée
Remplacez <catalog>.<schema>.<validated-events-view> par votre vue d’entrée. Définissez :start_time et :end_time comme des paramètres de Timestamp dans l’éditeur SQL.
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 renvoie la valeur observée au rang demandé plutôt qu’une approximation. La query exclut les ID d’événement conflictuels avant de sélectionner la période. Suivre séparément les ID de suivi dont le content_count dépasse un en tant qu’erreurs de qualité des données.
Par exemple, trois échantillons de LCP réduits avec des valeurs de 100, 200 et 300 millisecondes produisent sample_size = 3 et p75 = 300. Des rééditions identiques n'augmentent pas ce nombre d'échantillons. Un identifiant d’événement dont le contenu normalisé est en conflit ne fournit aucun enregistrement.
Gestion des versions
schema_version identifie la version principale du contrat indépendamment des versions de package du producteur.
L’ajout de champs facultatifs ou de noms d’action définis par l’application est compatible avec les versions précédentes. La suppression de champs requis ou la modification de leurs types, de leurs significations, de la portée de leur identifiant ou de leur sémantique de session nécessite un changement de version majeure. Les modifications apportées à la déduplication, à la réduction d'échantillons ou à la sémantique des types d'événements nécessitent également une nouvelle version majeure.
Les consommateurs ignorent les versions et les types d'événements non pris en charge au lieu de les interpréter comme des actions.