encore-logging

Par encoredev · skills

Ajoutez ou améliorez la journalisation structurée dans Encore.ts en utilisant `encore.dev/log`. Couvre le placement des logs, les niveaux, les messages et champs stables, les erreurs, les loggers contextuels, les données sensibles et le volume de logs.

npx skills add https://github.com/encoredev/skills --skill encore-logging

Journalisation structurée Encore.ts

Utilisez encore.dev/log pour les événements applicatifs qui nécessitent des champs structurés ou une intégration de trace. Préservez les noms de champs et conventions d'événements établis d'une application lorsqu'ils sont cohérents avec ces recommandations.

Décider quoi enregistrer

Ajoutez des logs pour les informations qu'Encore ne peut pas déduire des opérations d'infrastructure :

  • Les transitions d'état métier
  • Les décisions et les entrées qui les ont déterminées
  • Les tentatives, basculements et opérations dégradées
  • Les défaillances à la limite qui décide s'il faut réessayer, récupérer ou abandonner
  • Les interactions avec les systèmes externes qui nécessitent du contexte métier
  • Les actions pertinentes pour la sécurité ou l'administration

Encore trace déjà les requêtes API, les requêtes de base de données, les appels de service, les opérations de cache et l'activité Pub/Sub. Ne narrez pas cette exécution avec des logs comme request started, querying database ou request completed.

Utilisez les métriques pour les comptes et niveaux agrégés. Utilisez les traces pour le flux d'appels et les chronométrages. Utilisez les logs pour le contexte nécessaire à l'investigation d'un événement individuel.

Émettre des logs structurés

Gardez le message stable et mettez les données variables dans les champs :

import log from "encore.dev/log";

log.info("order rejected", {
  event: "order.rejected",
  orderId,
  productId,
  reason: "insufficient_inventory",
  requestedQuantity,
  availableQuantity,
});

Évitez d'interpoler les identifiants dans le message. Les messages stables peuvent être regroupés, tandis que les champs restent searchables.

Pour les événements utilisés par les tableaux de bord, les alertes ou l'automatisation, incluez un champ event stable. Préférez <domain>.<past-tense-event>, comme payment.authorized ou subscription.cancelled. Les logs de diagnostic ne nécessitent pas un nom d'événement.

Gardez chaque nom de champ et type cohérents entre les événements. Préférez les valeurs numériques avec des unités explicites et les valeurs type énumération plutôt que du texte formaté :

log.info("payment authorized", {
  event: "payment.authorized",
  amountMinorUnits: 14900,
  currency: "SEK",
});

Choisir un niveau

  • error : une défaillance inattendue a empêché une opération de se terminer
  • warn : l'application s'est rétablie ou a continué dans un état dégradé
  • info : un événement métier significatif et relativement peu fréquent
  • debug : détail diagnostique non requis pour le fonctionnement normal
  • trace : état interne à haut volume

Les résultats attendus tels que les défaillances de validation, les ressources manquantes, les connexions rejetées ou les paiements refusés ne sont pas des événements error. Utilisez leur signification métier pour choisir un niveau.

Le niveau minimum par défaut est trace. Configurez log_level dans encore.app avant d'ajouter des appels debug ou trace au code fréquemment exécuté.

Enregistrer les erreurs une seule fois

error et warn acceptent l'erreur originale comme premier argument :

try {
  await chargeCustomer(customerId, amount);
} catch (err) {
  log.error(err, "payment authorization failed", {
    customerId,
    amountMinorUnits: amount,
    currency,
  });
  throw err;
}

Passer l'erreur originale préserve son type, message, stack trace et cause. La convertir en chaîne rejette ces informations.

Loggez une défaillance propagée à la couche qui possède la décision de récupération et a le contexte métier pour décrire son impact. Une couche inférieure ne devrait logger que lorsqu'elle traite ou supprime l'erreur, réessaie, détecte une violation d'invariant, ou détient un contexte que la propagation perdrait.

Ajouter du contexte partagé

Utilisez log.with() lorsque plusieurs événements d'une opération métier partagent des champs :

const logger = log.with({ importId, tenantId });

logger.info("user import completed", { succeededCount, failedCount });
logger.warn("user import row rejected", { rowNumber, reason: "invalid_email" });

Encore attache déjà le service, l'endpoint, l'ID de trace et l'ID d'utilisateur authentifié aux logs de requête. N'ajoutez pas de copies en doublon.

Protéger les données sensibles

Encore ne rédige pas les champs de log. Ne loggez jamais les credentials, tokens, identifiants de session, cookies, en-têtes d'autorisation, configuration secrète, détails de paiement ou objets de requête et réponse complets.

Préférez les identifiants internes aux données personnelles. Utilisez une empreinte non réversible stable lorsque la corrélation nécessite une valeur qui ne devrait pas être stockée.

L'option API sensitive rédige les payloads de requête et réponse des traces ; elle ne rédige pas les valeurs passées à log.

Contrôler le volume

Résumez les lots et les opérations longues par les résultats, les comptes et les durées. Évitez un log par élément à moins que chaque défaillance ne nécessite une investigation.

Loggez les métadonnées sélectionnées des grandes valeurs plutôt que les réponses de fournisseur complètes, les enregistrements, les objets de configuration, les tableaux ou les corps de document. Limitez les aperçus et examinez-les pour les données sensibles avant de les logger.

Lors de l'examen d'une application existante, vérifiez d'abord les boucles, les abonnés Pub/Sub, les middlewares et les helpers fréquemment appelés. Un petit nombre de ces points d'appel produit souvent la plupart du volume de log.

Consultez le guide de journalisation Encore.ts et la référence API encore.dev/log.

Skills similaires