n8n:telemetry

Par n8n-io · n8n

Guide pour l'ajout, la modification et la revue de la télémétrie via le registre d'événements `@n8n/telemetry`. À utiliser lors de travaux sur la télémétrie, l'analytique, le tracking, les événements produit, les appels `track()`, ou les événements produit RudderStack/PostHog, en frontend ou backend — et chaque fois que vous avez besoin de savoir quels événements de télémétrie enregistrés existent, ce que signifie un événement, ou quelles propriétés il comporte.

npx skills add https://github.com/n8n-io/n8n --skill n8n:telemetry

Télémétrie

Le registre

Les événements migrés vers le registre se trouvent dans packages/@n8n/telemetry avec une entrée par événement — son nom exact émis, une description, et un schéma zod typant ses propriétés — organisés par domaine produit dans src/events/ et composés en TELEMETRY_EVENT.<DOMAIN>.<EVENT>. Le package définit les événements enregistrés et ne dépend jamais des SDKs de transport.

Pour trouver les événements enregistrés, leur signification, ou les propriétés qu'ils portent, lancez d'abord le catalogue :

pnpm --filter @n8n/telemetry catalog          # lisible, groupé par domaine
pnpm --filter @n8n/telemetry catalog --json   # structuré, pour usage programmatique

Le registre est adopté progressivement. Les événements non encore enregistrés n'apparaissent pas dans le catalogue, cherchez donc les sites d'appel track() quand le catalogue n'a pas de correspondance.

Passez l'entrée elle-même à track() — elle résout le nom émis en interne :

import { TELEMETRY_EVENT } from '@n8n/telemetry';

telemetry.track(TELEMETRY_EVENT.PLATFORM.USER_IS_PART_OF_EXPERIMENT, {
    name: experimentName,
    variant,
});

Les deux implémentations de track() acceptent les entrées du registre et les chaînes simples. Les chaînes simples restent supportées pour les événements non encore migrés :

  • Frontend : packages/frontend/editor-ui/src/app/plugins/telemetry/index.ts
  • Backend : packages/cli/src/telemetry/index.ts

Les entrées obtiennent l'autocomplétion des propriétés et les vérifications à la compilation — des propriétés mal orthographiées, manquantes, ou mal typées échouent la vérification de type. Quand le transport de télémétrie est initialisé, track() valide également les payloads des événements enregistrés via getEventValidationError (partagé depuis @n8n/telemetry) et enregistre un avertissement en cas de discordance, incluant les propriétés non reconnues qui ont échappé au typage structurel. Un avertissement de validation n'empêche pas l'événement d'être émis.

Ajouter un événement

  1. Vérifiez le catalogue d'abord (pnpm --filter @n8n/telemetry catalog). Si un événement existant couvre la même action utilisateur depuis une autre surface, augmentez-le avec une propriété au lieu d'ajouter un événement quasi-dupliqué.
  2. Choisissez le domaine par le sujet de l'événement — ce dont parle l'événement, jamais la surface qui l'a déclenché. User opened Credential modal est CREDENTIALS que ce soit ouvert depuis le NDV, la configuration de template, ou le chat. Le contexte du déclenchement va dans une propriété source.
  3. Nommez-le selon la grammaire maison : phrase case, acteur en premier, verbe au passé, objet spécifique (User pinned node data). Pas d'interpolation de template dans les noms — la variabilité va dans les propriétés. Le nom doit se convertir en snake_case proprement en nom de table BigQuery : pas de ponctuation au-delà des espaces, pas de casse qui crée une collision après snake_casing.
  4. Écrivez la description de l'entrée indiquant ce que signifie l'événement et quand il se déclenche — un test du registre rejette les descriptions vides. Documentez les propriétés individuelles avec .describe() où la clé seule n'est pas évidente.
  5. Typez les propriétés avec zod (import { z } from 'zod/v4') : clés en snake_case, .optional() explicite où un site d'appel peut omettre une valeur, z.looseObject()/.catchall() pour les restes véritablement dynamiques. Les schémas doivent rester représentables en JSON-Schema — pas de transforms, refinements, ou z.date() (un test du registre applique cela via z.toJSONSchema()).
  6. Placez l'émission : frontend via useTelemetry().track(...); backend soit par un handler RelayEventMap dans packages/cli/src/events/relays/telemetry.event-relay.ts (piloté par event-bus) soit par un appel Telemetry.track(...) direct — les deux référencent la même entrée du registre.

Règles strictes

  • Ne renommez jamais un événement émis. BigQuery matérialise une table par nom d'événement ; un renommage orpheline l'historique en aval. Un renommage est suppression + création, les noms ne sont jamais réutilisés, et les suppressions doivent être coordonnées avec l'équipe data avant de supprimer l'entrée du registre.
  • Ne dupliquez jamais un nom d'événement — une entrée par événement dans tous les domaines, référencée par chaque site d'appel (même FE + BE). Le CI échoue en cas de collision.
  • Les propriétés évoluent additivement seulement. Changer le type d'une propriété divise les colonnes d'entrepôt même sous un nom stable. Marquez les dépréciations sur le schéma (.meta({ deprecated: true })) au lieu de les supprimer.
  • Les breaking changes nécessitent une alerte de l'équipe data sur Slack plus une note Notion avant le déploiement.

Test

Ne redigitez pas les littéraux de noms d'événement dans les tests :

  • Dans les tests du site d'appel, mockez useTelemetry().track ou le service backend Telemetry.track et attendez l'entrée du registre elle-même avec le payload.
  • Dans les tests de transport frontend, attendez que window.rudderanalytics.track reçoive entry.name et le payload augmenté.
  • Dans les tests de transport backend, attendez que le champ event du payload RudderStack égale entry.name et que son properties inclue le payload de l'événement.

Connexes

L'exposition aux expériences et les événements de métrique suivent n8n:experiments (.agents/skills/experiments/SKILL.md).

Skills similaires