paint-brush
Bien gérer la journalisation : Fondation d'observabilitépar@feddena
842 lectures
842 lectures

Bien gérer la journalisation : Fondation d'observabilité

par Fedor Denisov6m2024/06/22
Read on Terminal Reader

Trop long; Pour lire

La journalisation est un élément crucial, mais souvent sous-estimé, du développement d'applications. Des pratiques de journalisation appropriées peuvent améliorer la visibilité de votre application et approfondir votre compréhension de son fonctionnement interne. Ce guide vise à vous fournir des informations et des pratiques fondamentales pour vous assurer que vous pouvez surveiller et dépanner vos services plus efficacement.
featured image - Bien gérer la journalisation : Fondation d'observabilité
Fedor Denisov HackerNoon profile picture

Ce guide vise à vous fournir des informations et des pratiques fondamentales pour vous assurer que vous pouvez surveiller et dépanner vos services plus efficacement.


Dans le développement d'applications, la journalisation est souvent négligée, mais elle constitue un élément crucial pour la construction d'un système robuste et observable. Des pratiques de journalisation appropriées peuvent améliorer la visibilité de votre application, approfondir votre compréhension de son fonctionnement interne et améliorer la santé globale de l’application.


Journalisation par défaut

L'intégration de mécanismes de journalisation par défaut aux points d'entrée de votre application est très bénéfique. Cette journalisation automatique peut capturer les interactions essentielles et potentiellement inclure les arguments du point d'entrée. Cependant, il est crucial d'être prudent, car la journalisation d'informations sensibles telles que les mots de passe peut présenter des risques en matière de confidentialité et de sécurité.

Points d'entrée communs

  • Points de terminaison de l'API : enregistrez les détails des demandes et des réponses entrantes
  • Travaux en arrière-plan : enregistrer les points de départ des travaux, les détails d'exécution et les résultats
  • Événements asynchrones : enregistrez la gestion des événements asynchrones et des interactions associées

Journalisation complète

Chaque action importante entreprise par votre application doit produire une entrée de journal, en particulier les actions qui modifient son état. Cette approche de journalisation exhaustive est essentielle pour identifier et résoudre rapidement les problèmes lorsqu'ils surviennent, offrant ainsi une vue transparente de l'état et des fonctionnalités de votre application. Une telle diligence dans l’exploitation forestière garantit un diagnostic et une maintenance plus faciles.

Choisir le niveau de journalisation approprié

L'adoption de niveaux de journalisation appropriés est cruciale pour gérer et interpréter la grande quantité de données générées par votre application. En catégorisant les journaux en fonction de leur gravité et de leur pertinence, vous garantissez que les problèmes critiques sont rapidement identifiés et résolus, tandis que les informations moins urgentes restent accessibles sans surcharger vos efforts de surveillance.


Vous trouverez ci-dessous des lignes directrices pour utiliser efficacement les niveaux de journalisation :

Niveau

Description et exemples

Utilisation acceptée

Pas accepté

ERROR

Événements fatals qui arrêtent les opérations du système. par exemple, connexion à la base de données perdue

Erreurs système critiques

Erreurs non critiques, comme les tentatives de connexion utilisateur infructueuses

WARN

Il y a un problème mais le système peut continuer l'exécution et terminer l'opération demandée

Problèmes potentiels menant à des problèmes

Changements d'état de routine

INFO

Aperçu des fonctions normales de l'application, comme la création de compte utilisateur ou l'écriture de données

Changements d'état

Opérations en lecture seule sans modifications

DEBUG

Informations de diagnostic détaillées, telles que le début/la fin du processus

Les étapes du processus de journalisation ne modifient pas l'état du système

Changements d'état de routine ou opérations à haute fréquence

TRACE

Le niveau le plus détaillé, y compris les entrées/sorties de méthode

Comprendre le flux et les détails d'un processus

Enregistrement d'informations sensibles

Quels identifiants enregistrer – Approche hiérarchique

Lors de la journalisation des actions dans votre application, l'inclusion des ID des entités directement impliquées est cruciale pour relier les informations du journal aux données de la base de données. Une approche hiérarchique vous aide à trouver rapidement tous les journaux connectés à une partie spécifique de votre application en reliant les éléments à leurs groupes ou catégories parents.


Par exemple, au lieu de consigner uniquement l'ID d'une discussion lorsqu'un message ne parvient pas à être envoyé, vous devez également enregistrer les identifiants de la salle de discussion et de l'entreprise à laquelle elle appartient. De cette façon, vous obtenez plus de contexte et pouvez voir l’impact plus large du problème.

Exemple d'entrée de journal :

Failed to send the message - chat=$roomId, chatRoomId=chatRoomId, company=$companyId

Exemple de journaux de production

Vous trouverez ci-dessous un exemple de ce à quoi pourraient ressembler les journaux de production lors de l'utilisation de l'approche hiérarchique :

Interface utilisateur des journaux Datadog avec des journaux qui utilisent l'approche hiérarchique suggérée

Cohérence et standardisation

Préfixes standards

La standardisation des formats de journaux dans toutes les équipes peut rendre vos journaux beaucoup plus faciles à lire et à comprendre. Voici quelques préfixes standardisés à prendre en compte :

  • Commencer à faire quelque chose
  • Je n'ai pas réussi à faire quelque chose
  • J'ai fini de faire quelque chose
  • J'ai sauté quelque chose
  • Réessayez de faire quelque chose

Consigner les valeurs des variables séparément

Séparer les noms et valeurs des variables du corps des messages de journal offre plusieurs avantages :

  • Simplifie la recherche et l'analyse des journaux : facilite le filtrage et la recherche d'informations spécifiques.
  • Rationalise la création de messages de journal : simplifie le processus d'écriture des messages de journal
  • Empêche l'encombrement des messages : les valeurs élevées ne perturberont pas la lisibilité du message du journal

Exemple de format de journal :

 Log message - valueName=value

Exemples de journaux utilisant les pratiques proposées

Exemple théorique

Voici des exemples d’entrées de journal bien structurées suivant les meilleures pratiques discutées :

 2023-10-05 14:32:01 [INFO] Successful login attempt - userId=24543, teamId=1321312 2023-10-05 14:33:17 [WARN] Failed login attempt - userId=536435, teamId=1321312

Ces exemples démontrent :

  • Préfixes de journaux standardisés : des préfixes clairs et cohérents tels que "Tentative de connexion réussie" et "Tentative de connexion échouée" rendent les journaux faciles à comprendre.


  • Valeurs de variables séparées : les noms et valeurs des variables sont séparés du message du journal, ce qui garantit la clarté et simplifie les recherches.


  • Lisibilité et cohérence : le format structuré garantit que les journaux sont faciles à lire et à analyser, ce qui facilite un dépannage et une surveillance efficaces.

Exemple de journaux de production

Vous trouverez ci-dessous un exemple de ce à quoi pourraient ressembler les journaux de production lors de l'utilisation des pratiques proposées :

Datadog enregistre l'interface utilisateur avec un filtre par préfixe « Commencer à »

ID de trace

Pour associer efficacement les journaux à une action utilisateur spécifique, il est crucial d'inclure un traceId ou comme on l'appelle également correlationId dans vos journaux. L'ID doit rester cohérent dans tous les journaux générés par la logique déclenchée par ce point d'entrée, offrant une vue claire de la séquence des événements.

Exemple de mise en œuvre

Bien que certains services de surveillance comme Datadog proposent un regroupement de journaux prêt à l'emploi, cela peut également être implémenté manuellement. Dans une application Kotlin utilisant Spring, vous pouvez implémenter un ID de trace pour les requêtes REST à l'aide d'un HandlerInterceptor.

 @Component class TraceIdInterceptor : HandlerInterceptor { companion object { private const val TRACE_ID = "traceId" } override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean { val traceId = UUID.randomUUID().toString() MDC.put(TRACE_ID, traceId) return true } override fun afterCompletion(request: HttpServletRequest, response: HttpServletResponse, handler: Any, ex: Exception?) { MDC.remove(TRACE_ID) } }

Cet intercepteur génère un traceId unique pour chaque requête, en l'ajoutant au MDC au début de la requête et en le supprimant une fois la requête terminée.

Exemples de journaux avec traceId

La mise en œuvre d'une telle agrégation de journaux vous permettra de filtrer les journaux de la même manière que dans l'exemple ci-dessous.


Journaux générés lors du traitement des demandes de suppression d'actifs

Utilisation de l'UUID et des identifiants longs dans les journaux

Dans de nombreux systèmes, les entités peuvent utiliser soit UUID , soit des identifiants Long comme identifiants principaux, tandis que certains systèmes peuvent utiliser les deux types d'identifiants à des fins différentes. Comprendre les implications de chaque type à des fins d'exploitation forestière est crucial pour faire un choix éclairé.


Voici un aperçu des éléments à prendre en compte :


Lisibilité : les identifiants Long sont plus faciles à lire et considérablement plus courts, surtout s'ils ne se situent pas dans la partie supérieure de la plage Long .


Valeur unique : les ID UUID offrent un caractère unique dans tout le système, vous permettant de rechercher des journaux à l'aide d'un ID sans rencontrer de problèmes de collisions d'ID. Les collisions signifient ici qu'il est possible que 2 entités de tables de base de données non liées aient le même ID Long .


Limitations du système : dans les systèmes qui utilisent des clés primaires longues comme identifiants d'entité, l'ajout d'un identifiant UUID aléatoire est généralement simple. Dans un système distribué avec des identifiants d'entité UUID , il peut être difficile ou coûteux d'avoir des identifiants Long spécifiquement pour la journalisation.


Journaux existants : la cohérence du type d'ID utilisé dans les journaux est essentielle, au moins par entité. Si le système produit déjà des journaux pour certaines entités et que vous n'envisagez pas de toutes les modifier, il est préférable de s'en tenir au type déjà utilisé pour identifier l'entité. La journalisation des deux identifiants peut être envisagée pendant une période de transition, mais le fait d'avoir plusieurs identifiants en permanence encombrera inutilement les journaux.


Conclusion

Des pratiques de journalisation appropriées sont essentielles pour une observabilité efficace des services. En intégrant une journalisation complète, des niveaux de journalisation appropriés, des ID de trace et des formats de journal standardisés, vous pouvez améliorer considérablement votre capacité à surveiller et à dépanner vos applications. Ces pratiques améliorent la clarté et la cohérence de vos journaux, facilitant ainsi le diagnostic et la résolution rapide des problèmes.


Merci d'avoir pris le temps de lire cet article !