Découvrez comment maîtriser l'art ancien qui consiste à choisir judicieusement vos niveaux de logs.

Introduction

La journalisation est une pratique fondamentale lors du développement logiciel. Les développeurs et les équipes support s'appuient sur ces logs pour comprendre le comportement des applications, diagnostiquer les problèmes et améliorer la qualité du code. Au cœur de cette pratique se trouvent les niveaux de logs qui définissent la sévérité des messages enregistrés.

Il est important de sélectionner le niveau de log approprié, car cela détermine si les informations sont enregistrées dans la sortie (filtrage) et peut influencer les actions spécifiques déclenchées par les outils de surveillance, ce qui peut avoir un impact sur les équipes de support.

Dans cet article, nous plongerons dans l'art de la gestion des niveaux de logs, en explorant leurs définitions, les stratégies et les exemples concrets qui vous permettront de prendre des décisions éclairées.

Présentation des Niveaux de Logs

Les différents niveaux de logs en programmation sont généralement les suivants :

  1. Trace / Verbose : Le niveau le plus détaillé, utilisé pour le suivi fin des opérations dans le code. Il est principalement utilisé pour le diagnostic détaillé.
  2. Debug : Utilisé pour fournir des informations détaillées, généralement lors du développement et du débogage. Il aide les développeurs à comprendre le flux d'exécution.
  3. Information : Fournit des messages informatifs qui mettent en évidence le progrès de l'application dans un environnement de production.
  4. Waning : Indique des situations potentiellement problématiques qui ne sont pas nécessairement des erreurs, mais qui pourraient nécessiter une attention particulière.
  5. Error : Signale des erreurs graves qui ont affecté le fonctionnement de l'application, mais ne l'ont pas arrêtée.
  6. Fatal : Indique des erreurs très graves qui ont probablement causé l'arrêt de l'application.

Les librairies de logs, au-delà de simplement marquer une ligne de log avec un niveau de sévérité, permettent de filtrer les logs par niveau. Cette capacité de filtrage fonctionne en établissant un seuil minimal de niveau de log que l'application doit enregistrer.

Ce seuil, défini dans la configuration du système de logging, détermine le niveau de détail des messages de log à enregistrer. Ce seuil peut être configuré de manière globale pour l'ensemble de l'application ou de façon spécifique par logger. Cette flexibilité permet aux développeurs de personnaliser les logs selon les besoins précis de différentes parties de l'application, optimisant ainsi la pertinence et l'efficacité de la collecte des données.

Trace / Verbose

Le niveau Trace (ou Verbose selon les librairies de logging) se distingue par sa capacité à fournir des informations extrêmement détaillées sur le fonctionnement interne d'une application. Il permet de suivre des chemins d'exécution précis, de surveiller les valeurs des variables à des moments clés, et d'offrir des insights précis sur le début et la fin des opérations.

Ce niveau est particulièrement utile lors du diagnostic de problèmes complexes ou inattendus. Il offre une vue d'ensemble, presque microscopique, nécessaire pour analyser ces situations délicates. Cependant, il convient de noter que l'utilisation du niveau Trace n'est pas sans inconvénients. La quantité massive de logs générée peut avoir un impact significatif sur les performances de l'application. De ce fait, son utilisation est généralement réservée à des cas spécifiques et n'est pas recommandée pour un déploiement régulier en environnement de production.

Debug

Le niveau Debug sert à fournir des informations détaillées, bien que moins exhaustives que celles du niveau Trace, tout en restant fortement orienté vers le débogage. Dans les scénarios typiques de développement, ce niveau est fréquemment utilisé pour comprendre le comportement de l'application, pour vérifier l'exécution correcte du code, ou pour résoudre des problèmes qui ne requièrent pas une complexité extrême. Bien que Debug génère moins de logs que Trace, le volume peut tout de même être conséquent. Par conséquent, son utilisation en environnement de production est rare. Il trouve son idéal dans les phases de développement et de tests, où une visibilité modérée est suffisante pour les besoins de débogage.

Information

Le niveau Information (nommé parfois Info) sert à capturer des informations essentielles sur le fonctionnement normal et les événements significatifs de l'application. Voici quelques exemples de cas d'utilisation :

  1. Opérations et Transactions Clés : enregistrement d'événements significatifs dans le flux de l'application, comme le démarrage ou la conclusion réussie d'une transaction ou d'un processus important.
  2. État de l'Application : suivi de l'état général de l'application, comme le démarrage ou l'arrêt réussi de services ou de composants clés.
  3. Audits et Conformité : suivi des événements liés à la conformité et aux audits, comme les modifications de configuration ou les accès aux fonctionnalités sensibles.
  4. Performance et Statistiques Clés : enregistrement d'indicateurs de performance ou des statistiques périodiques, aidant à comprendre le comportement de l'application sur le long terme.
  5. Actions des Utilisateurs dans le Cadre de Cas d'Utilisation Spécifiques : enregistrement des actions clés des utilisateurs qui sont pertinentes pour des cas d'utilisation spécifiques, comme les achats, les mises à jour de profil, ou les interactions critiques avec l'application.
  6. Intégration et Interaction avec d'Autres Services : suivi des interactions réussies avec des services externes ou des API (requêtes / réponses).

Ainsi, le niveau Info offre une une globale sur les opérations normales et les événements significatifs, en fournissant des informations pour comprendre le déroulement des cas d'utilisation sans la surcharge de détails présente dans les niveaux Trace ou Debug.

Warning

Le niveau Warning est conçu pour signaler des situations qui, bien que n'étant pas des erreurs critiques, indiquent des conditions anormales ou inattendues dans l'application. Il est idéal pour attirer l'attention sur des problèmes potentiels qui pourraient nécessiter une attention ou une intervention dans le futur.

Par exemple, il peut être utilisé pour alerter sur une utilisation inhabituelle des ressources, comme une mémoire ou un espace disque faible, ou sur des délais de réponse plus longs que la normale. Le niveau Warning est également approprié pour des validations qui ne bloquent pas le processus, mais qui peuvent indiquer des données incorrectes ou des configurations problématiques. De plus, il est utile pour signaler des exceptions gérées qui n'arrêtent pas l'application, mais qui pourraient affecter certaines fonctionnalités.

Considérons l'exemple d'un appel à une API Rest où nous employons la librairie Polly pour mettre en place une politique de ré-essai. Voici une méthode recommandée pour gérer le logging de ces tentatives :

Pour les premières tentatives (1ère, 2ème, 3ème) :

  • Niveau de Log : Warning
  • Justification : Ces tentatives initiales font partie intégrante de la politique de ré-essai. Un échec à ce stade ne constitue pas un échec total de l'opération, étant donné qu'il reste des chances de succès dans les tentatives suivantes. En classant ces échecs comme des "Warnings", nous reconnaissons l'existence d'un problème qui mérite une surveillance, sans pour autant le qualifier d'échec complet de l'opération.

Pour la dernière tentative (4ème) :

  • Niveau de Log : Error
  • Justification : L'échec de la dernière tentative indique un échec global de l'opération après plusieurs essais. Cet événement, de par son importance, doit être enregistré comme une Error. Cela signale un impact direct sur le fonctionnement de l'application et suggère qu'une action corrective peut être nécessaire, puisque toutes les tentatives de récupération ont échoué.

Cette approche permet de distinguer clairement entre les échecs intermédiaires, qui sont dans une certaine mesure anticipés et gérés par la stratégie de ré-essai, et un échec final plus critique. Elle aide également à éviter la surcharge des logs avec des messages d'erreur pour chaque tentative échouée, tout en assurant que les échecs significatifs sont convenablement identifiés et signalés.

Error

Le niveau Error est crucial pour identifier les problèmes graves qui nécessitent une attention immédiate. Ce niveau est utilisé dans des situations comme :

  • Échecs Critiques de l'Application : signalement des erreurs qui interrompent les opérations normales de l'application ou empêchent certaines fonctionnalités de fonctionner correctement. Cela peut inclure des erreurs de système, des exceptions non gérées, ou des problèmes critiques de base de données.
  • Problèmes Affectant les Utilisateurs : Lorsque les utilisateurs rencontrent des erreurs qui les empêchent d'utiliser l'application comme prévu. Cela inclut des problèmes comme l'échec des processus de connexion, des erreurs dans les transactions ou des dysfonctionnements dans l'interface utilisateur.
  • Problèmes de Connectivité et de Communication : Des erreurs telles que l'échec des connexions réseau, des problèmes de communication avec des services externes ou des API, ou des défaillances dans l'envoi et la réception de données sont classées au niveau Error, signalant des problèmes qui peuvent avoir un impact significatif sur les performances de l'application.
  • Alertes pour l'Intervention : avertissement destinés aux équipes de développement ou de support technique qu'une intervention est nécessaire pour résoudre les problèmes qui ne peuvent pas être résolus automatiquement par l'application.

En résumé, le niveau Error est utilisé pour enregistrer les événements indiquant des dysfonctionnements sérieux dans l'application, nécessitant souvent une action corrective immédiate pour éviter des perturbations majeures ou des pertes de données.

Fatal

Le niveau Fatal représente la catégorie la plus critique et est réservé pour les situations où l'application rencontre une erreur si grave qu'elle ne peut pas continuer à fonctionner normalement. Il est utilisé pour signaler des erreurs catastrophiques qui entraînent l'arrêt de l'application ou un dysfonctionnement majeur qui empêche toute opération ultérieure. Cela inclut des situations comme une défaillance systémique, une corruption de données irréversible, ou un crash complet du système.

Il peut également être utilisé lors d'impacts sur l'intégrité du système. Ces erreurs sont souvent de nature à compromettre l'intégrité ou la sécurité du système. Elles peuvent indiquer des problèmes critiques comme des violations de sécurité, des pertes de données importantes, ou des défaillances matérielles.

Les incidents logués au niveau Fatal nécessitent généralement une alerte immédiate et une intervention rapide des équipes techniques. Ils signalent des conditions sous lesquelles l'application ne peut pas fonctionner correctement et où des mesures urgentes sont nécessaires pour prévenir ou limiter les dommages.

Étant donné la gravité des événements signalés par ce niveau, il est a utiliser avec parcimonie.

Les logs Fatal sont rares et indiquent des situations où l'application ne peut pas se remettre d'elle-même et où une action manuelle est essentielle, déclenchant souvent une analyse post-événement pour comprendre ce qui a mal tourné et comment des incidents similaires peuvent être évités à l'avenir.

Filtrage par Niveau de Log

Le filtrage des logs par niveau est une technique fondamentale dans la gestion des logs, permettant de sélectionner les informations à enregistrer en fonction de leur sévérité ou importance. Bien que ce chapitre se concentre sur le filtrage par niveau, il est important de noter qu'il existe d'autres méthodes de filtrage, telles que par catégorie ou source, qui peuvent compléter efficacement cette approche.

Concrètement, lorsque vous configurez le niveau de log à Information par exemple, le système enregistre automatiquement tous les messages de log de niveau Information ainsi que ceux des niveaux , supérieurs (Warning, Error et Fatal). Les niveaux inférieurs (Debug et Trace), ne seront pas inclus dans les logs. Cette hiérarchisation des niveaux de log assure que chaque niveau supérieur englobe tous les niveaux en dessous de lui, permettant ainsi un contrôle précis sur la quantité et la qualité des informations loguées en fonction du niveau choisi.

L'Importance du Filtrage par Niveau

  1. Contrôle des Volumes de Données : Le filtrage par niveau aide à contrôler le volume des données loguées, enregistrant uniquement les informations pertinentes pour un contexte donné.
  2. Optimisation des Performances : En réduisant le nombre de logs, cette méthode contribue à optimiser les performances de l'application et à alléger la charge sur les systèmes de stockage.
  3. Amélioration de la Lisibilité : En filtrant les niveaux moins critiques, on améliore la lisibilité des logs, rendant l'identification des problèmes plus rapide et plus efficace.

Voici un exemple de filtrage en C# utilisant la librairie Serilog:

Dans le fichier appsettings.json, configurons le niveau minimum à Information :

{
    "Serilog": {
        "MinimumLevel": "Information"
    }
}

Exemple de code en C#:

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(configuration)
    .CreateLogger();

Log.Verbose("This is a Verbose log."); // Niveau inférieur à Info
Log.Debug("This is a Debug log.");     // Niveau inférieur à Info
Log.Information("This is an Info log."); // Niveau égal à Info
Log.Warning("This is a Warning log.");   // Niveau supérieur à Info
Log.Error("This is an Error log.");      // Niveau supérieur à Info
Log.Fatal("This is a Fatal log.");       // Niveau supérieur à Info

Résultat dans la console:

This is an Info log.
This is a Warning log.
This is an Error log.
This is a Fatal log.

Conclusion

Choisir le niveau de logs approprié est crucial pour une surveillance efficace, un débogage précis, et une analyse opérationnelle des applications.

Points Clés pour Choisir les Niveaux de Log

  1. Comprendre les Niveaux de Log : Chaque niveau (Trace, Debug, Info, Warning, Error, Fatal) a son utilité spécifique, allant des détails très fins aux informations critiques sur les erreurs graves.
  2. Tenir compte de l'environnement: En environnement de développement, des niveaux plus détaillés comme Trace ou Debug sont privilégiés pour une analyse approfondie. En environnement de test, les niveaux Debug et Information seront plus adaptés. En production, des niveaux plus modérés comme Warning ou Error peuvent être suffisants pour optimiser les performances tout en capturant les problèmes importants.
  3. Détail et Performance : Un logging trop détaillé peut surcharger les systèmes et affecter les performances, tandis qu'un logging insuffisant peut manquer d'informations cruciales pour le diagnostic des problèmes.
  4. Stratégie de Logging Ciblée : Utiliser des stratégies de logging ciblées, en choisissant le niveau de log par logger fourni une surveillance efficace des processus métier sans surcharger les logs.
  5. Adaptabilité et Ajustement Dynamique : La capacité d'ajuster les niveaux de log dynamiquement en fonction des besoins actuels peut être extrêmement utile, en particulier en environnement de production.

Expérimentation et Affinement

il est essentiel d'expérimenter et d'affiner continuellement votre utilisation des logs. Chaque application a ses spécificités et ce qui fonctionne pour une application peut ne pas être idéal pour une autre. N'hésitez pas à :

  • Tester différents niveaux de logs dans divers environnements et scénarios.
  • Analyser l'impact du logging sur les performances et l'utilisabilité des logs générés.
  • Adapter votre stratégie de logging en fonction des retours d'expérience et des changements dans l'application ou son environnement.
  • Explorer d'autres techniques de journalisation, comme la catégorisation ou les logs structurés.

En fin de compte, l'art de bien logger est un processus évolutif et adaptatif. Une approche réfléchie et expérimentale vous aidera à tirer le meilleur parti de vos systèmes de logs, assurant ainsi une meilleure compréhension, surveillance et maintien de vos applications.