Journalisation structurée avec Encore.go
Utilisez encore.dev/rlog pour les événements applicatifs qui nécessitent des champs structurés ou l'intégration de traces. Préservez les noms de champs établis et les conventions d'événements d'une application lorsqu'ils sont cohérents avec ce guide.
Décidez ce qu'il faut enregistrer
Ajoutez des logs pour les informations qu'Encore ne peut pas déduire des opérations d'infrastructure :
- Transitions d'état métier
- Décisions et les entrées qui les ont déterminées
- Tentatives, basculements et opérations dégradées
- Défaillances à la limite qui décide de recommencer, récupérer ou abandonner
- Interactions avec des systèmes externes qui nécessitent un contexte métier
- Actions pertinentes pour la sécurité ou administratives
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 racontez pas cette exécution avec des logs comme request started, querying database ou request completed.
Utilisez les métriques pour les comptages et les niveaux agrégés. Utilisez les traces pour le flux d'appels et la synchronisation. Utilisez les logs pour le contexte nécessaire pour enquêter sur un événement individuel.
Émettez des logs structurés
Gardez le message stable et passez les clés de chaîne alternées et les valeurs après :
import "encore.dev/rlog"
rlog.Info("order rejected",
"event", "order.rejected",
"order_id", orderID,
"product_id", productID,
"reason", "insufficient_inventory",
"requested_quantity", requestedQuantity,
"available_quantity", availableQuantity,
)
Évitez d'interpoler les identifiants dans le message. Les messages stables peuvent être regroupés, tandis que les champs restent cherchables.
Pour les événements utilisés par les tableaux de bord, les alertes ou l'automatisation, incluez un champ event stable. Préférez <domaine>.<événement-passé>, comme payment.authorized ou subscription.cancelled. Les logs de diagnostic ne nécessitent pas de nom d'événement.
Gardez chaque nom et type de champ cohérents d'un événement à l'autre. Préférez les valeurs numériques avec unités explicites et les valeurs de type énumération plutôt que du texte formaté :
rlog.Info("payment authorized",
"event", "payment.authorized",
"amount_minor_units", 14900,
"currency", "SEK",
)
Les champs runtime d'Encore utilisent snakecase. Les noms de champs commençant par `encoresont réservés ;rlogles réécrit avec un préfixex_`.
Choisissez un niveau
Encore.go fournit Error, Warn, Info et Debug. Il n'expose pas de fonction Trace via rlog.
Error: une défaillance inattendue a empêché une opération de se terminerWarn: l'application s'est rétablie ou a continué dans un état dégradéInfo: un événement métier significatif, à volume relativement faibleDebug: détail diagnostique non requis pour le fonctionnement normal
Les résultats attendus comme les défaillances de validation, les ressources manquantes, les logins rejetés 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, donc tous les quatre niveaux rlog sont émis. Configurez log_level dans encore.app avant d'ajouter des appels Debug au code fréquemment exécuté.
Enregistrez les erreurs une seule fois
Passez l'error original comme valeur de champ :
if err := chargeCustomer(ctx, customerID, amount); err != nil {
rlog.Error("payment authorization failed",
"err", err,
"customer_id", customerID,
"amount_minor_units", amount,
"currency", currency,
)
return err
}
Passer la valeur error permet à rlog d'appliquer sa sérialisation des erreurs. Appeler err.Error() d'abord passe une simple chaîne.
Enregistrez une défaillance retournée à la couche qui possède la décision de récupération et qui a le contexte métier pour décrire son impact. Une couche inférieure ne doit enregistrer que si elle gère ou supprime l'erreur, effectue des tentatives, détecte une violation d'invariant ou détient un contexte que l'erreur retournée ne contiendra pas.
Ajoutez un contexte partagé
Utilisez rlog.With lorsque plusieurs événements d'une opération de domaine partagent des champs :
logger := rlog.With("import_id", importID, "tenant_id", tenantID)
logger.Info("user import completed", "succeeded_count", succeededCount, "failed_count", failedCount)
logger.Warn("user import row rejected", "row_number", rowNumber, "reason", "invalid_email")
Encore attache déjà le service, l'endpoint, l'ID de trace et l'ID utilisateur authentifié aux logs de requête. N'ajoutez pas de doublons.
Protégez les données sensibles
Encore ne rédige pas les champs de log. Ne consignez jamais les credentials, les tokens, les identifiants de session, les cookies, les en-têtes d'autorisation, la configuration secrète, les détails de paiement ou les valeurs de requête et réponse complètes.
Préférez les identifiants internes aux données personnelles. Utilisez une empreinte numérique stable et non réversible lorsque la corrélation nécessite une valeur qui ne doit pas être stockée.
L'annotation API sensitive et le tag struct encore:"sensitive" rédactent les payloads de requête et de réponse des traces ; ils ne rédactent pas les valeurs passées à rlog.
Contrôlez le volume
Résumez les lots et les opérations de longue durée avec les résultats, les comptages et les durées. Évitez un log par élément sauf si chaque défaillance nécessite une enquête.
Enregistrez les métadonnées sélectionnées de grandes valeurs plutôt que les réponses complètes du fournisseur, les enregistrements, les valeurs de configuration, les tranches ou les corps de document. Limitez les aperçus et examinez-les pour les données sensibles avant de les enregistrer.
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 sites d'appel produit généralement la plupart du volume de log.
Consulter le guide de journalisation Encore.go et la référence du package rlog.