J'utilise logback dans mon projet actuel.
Il offre six niveaux de journalisation: TRACE DEBUG INFO WARN ERROR OFF
Je cherche une règle générale pour déterminer le niveau de journalisation des activités courantes. Par exemple, si un thread est verrouillé, le message de journalisation doit-il être défini sur le niveau de débogage ou le niveau d'informations? Ou, si un socket est utilisé, son identifiant spécifique doit-il être enregistré au niveau de débogage ou au niveau de la trace?.
J'apprécierai les réponses avec plus d'exemples pour chaque niveau de journalisation.
Je construis la plupart du temps des systèmes de type haute disponibilité et à grande échelle; ma réponse est donc orientée vers le point de vue du support de production; Cela dit, nous assignons à peu près comme suit:
error : le système est en détresse, les clients sont probablement affectés (ou le seront bientôt) et le correctif nécessite probablement une intervention humaine. La "règle 2AM" s'applique ici - si vous êtes en appel, souhaitez-vous être réveillé à 2h00 si cette condition se produit? Si oui, alors enregistrez-le comme "erreur".
warn : un événement technique ou commercial imprévu s'est produit, les clients peuvent être affectés, mais aucune intervention humaine immédiate n'est probablement requise. Les personnes sur appel ne seront pas appelées immédiatement, mais le personnel du support technique voudra examiner ces problèmes le plus rapidement possible afin de comprendre leur impact. Fondamentalement, tout problème nécessitant un suivi mais ne nécessitant pas une intervention immédiate.
info : éléments que nous souhaitons voir à volume élevé au cas où nous aurions besoin d'analyser de manière scientifique un problème. Les événements du cycle de vie du système (démarrage et arrêt du système) sont indiqués ici. Les événements du cycle de vie "session" (connexion, déconnexion, etc.) vont ici. Les événements limites significatifs doivent également être pris en compte (par exemple, appels de base de données, appels API distants). Les exceptions métier classiques peuvent aller ici (par exemple, échec de la connexion en raison de mauvaises informations d'identification). Tout autre événement dont vous pensez avoir besoin de voir dans la production à volume élevé est ici.
debug : à peu près tout ce qui ne rend pas l'information "coupée" ... tout message utile pour suivre le flux dans le système et l'isoler problèmes, en particulier pendant les phases de développement et d’AQ. Nous utilisons des journaux de niveau "débogage" pour l’entrée/la sortie de la plupart des méthodes non triviales et pour marquer les événements et les points de décision intéressants dans les méthodes.
trace : nous l’utilisons rarement, mais il s’agit de journaux extrêmement volumineux et potentiellement très volumineux que vous ne souhaitez généralement pas activer même pendant développement normal. Les exemples incluent le vidage d'une hiérarchie d'objet complète, la journalisation d'un état lors de chaque itération d'une grande boucle, etc.
Le plus important ou plus important que de choisir les bons niveaux de journaux est de veiller à ce que les journaux soient significatifs et présentent le contexte nécessaire. Par exemple, vous souhaiterez presque toujours inclure l'ID de thread dans les journaux afin de pouvoir suivre un seul thread si nécessaire. Vous pouvez également utiliser un mécanisme pour associer des informations commerciales (par exemple, un ID utilisateur) au thread afin que celui-ci soit également enregistré. Dans votre message de journal, vous voudrez inclure suffisamment d’informations pour que le message puisse être traité. Un journal du type "Une exception FileNotFound capturée" n’est pas très utile. Un meilleur message est "Une exception FileNotFound interceptée lors de la tentative d'ouverture du fichier de configuration: /usr/local/app/somefile.txt. UserId = 12344."
Il existe également un certain nombre de bons guides de journalisation ... par exemple, voici un extrait modifié de JCL (Jakarta Commons Logging) :
- error - Autres erreurs d'exécution ou conditions inattendues. Attendez-vous à ce qu'ils soient immédiatement visibles sur une console d'état.
- warn - Utilisation d'API obsolètes, mauvaise utilisation de l'API, erreurs "presque", autres situations d'exécution indésirables ou inattendues, mais pas nécessairement "fausses". Attendez-vous à ce qu'ils soient immédiatement visibles sur une console d'état.
- info - Événements d'exécution intéressants (démarrage/arrêt). Attendez-vous à ce qu'ils soient immédiatement visibles sur une console, soyez prudent et limitez-vous à un minimum.
- debug - informations détaillées sur le flux dans le système. Attendez-vous à ce qu'ils soient écrits uniquement dans les journaux.
- trace - informations plus détaillées. Attendez-vous à ce qu'ils soient écrits uniquement dans les journaux.
Mon approche, je pense venir plus d'un développement que d'un point de vue opérationnel, est la suivante:
Cela peut aussi aider de manière tangentielle, pour comprendre si une demande de journalisation (à partir du code) à un certain niveau aura pour conséquence qu'elle sera réellement enregistrée étant donné le niveau de consignation effectif avec lequel un déploiement est configuré. Décidez quel niveau effectif vous voulez configurer pour votre déploiement à partir des autres réponses ici, puis reportez-vous à ceci pour voir si une journalisation particulière demande à partir de votre code sera effectivement connecté alors ...
Par exemple :
de documentation de journalisation:
De manière plus graphique, voici comment fonctionne la règle de sélection. Dans le tableau suivant, l'en-tête vertical indique le niveau de la demande de journalisation, désigné par p, tandis que l'en-tête horizontal indique le niveau effectif de l'enregistreur, désigné par q. L'intersection des lignes (demande de niveau) et des colonnes (niveau effectif) est le booléen résultant de la règle de sélection de base.
Ainsi, une ligne de code qui demande la consignation ne sera réellement consignée que si le niveau de consignation effectif de son déploiement est inférieur ou égal à celui de cette ligne de code demandé niveau de gravité.
Je réponds à cela avec une architecture à base de composants, dans laquelle une organisation peut exécuter de nombreux composants pouvant s'appuyer les uns sur les autres. Lors d'une propagation d'échec, les niveaux de journalisation devraient aider à identifier les composants affectés et les causes fondamentales.
ERROR - Ce composant a eu une défaillance dont la cause est supposée être interne (toute exception interne non gérée, défaillance de la dépendance encapsulée ... par exemple, base de données, REST exemple serait avoir reçu une erreur 4xx d'une dépendance). Faites-moi sortir du lit (responsable de ce composant).
WARN - Ce composant a eu une défaillance supposée être causée par un composant dépendant (l'exemple REST serait un statut 5xx à partir d'une dépendance). Obtenez les mainteneurs de CE composant hors du lit.
INFO - Tout ce que nous souhaitons faire parvenir à un opérateur. Si vous décidez de vous connecter avec des chemins d'accès non sécurisés, il est recommandé de limiter à un message de journalisation par opération importante (par exemple, par requête http entrante).
Pour tous les messages de journal, assurez-vous de consigner le contexte utile (et donnez la priorité à la création de messages lisibles/utiles au lieu d’avoir beaucoup de "codes d’erreur")
Un bon moyen de visualiser les niveaux de journalisation ci-dessus consiste à imaginer un ensemble d’écrans de surveillance pour chaque composant. Quand tout fonctionne bien, ils sont verts. Si un composant enregistre un AVERTISSEMENT, il deviendra orange (orange). Si quelque chose enregistre une ERREUR, il passera au rouge.
En cas d’incident, un composant (cause fondamentale) deviendra rouge et tous les composants concernés deviendront orange/orange.
Pas différent pour les autres réponses, mon cadre a presque les mêmes niveaux: