323 votes

Meilleures pratiques en matière de journalisation

J'aimerais avoir des témoignages sur la façon dont les gens gèrent le traçage et la journalisation dans des applications réelles. Voici quelques questions qui pourraient vous aider à expliquer votre réponse.

Cadres de travail

Quels cadres utilisez-vous ?

  • log4net
  • System.Diagnostics.Trace
  • System.Diagnostics.TraceSource
  • Bloc d'application de journalisation
  • Autre ?

Si vous utilisez le traçage, faites-vous usage de Trace.Correlation.StartLogicalOperation ?

Écrivez-vous ce code manuellement, ou utilisez-vous une forme de programmation orientée aspect pour le faire ? Vous voulez partager un extrait de code ?

Fournissez-vous une forme de granularité sur les sources de traçage ? Par exemple, les TraceSources de WPF vous permettent de les configurer à différents niveaux :

  • System.Windows - pour l'ensemble de WPF
  • System.Windows.Animation - spécialement pour l'animation.

Auditeurs

Quelles sorties de journaux utilisez-vous ?

  • Fichiers texte
  • Fichiers XML
  • Journal des événements
  • Autre ?

Si vous utilisez des fichiers, utilisez-vous des journaux continus ou un seul fichier ? Comment mettez-vous les journaux à la disposition des gens ?

Visualisation de

Quels outils utilisez-vous pour visualiser les journaux ?

  • Bloc-notes
  • Queue
  • Visionneuse d'événements
  • Gestionnaire des opérations du centre des systèmes / Gestionnaire des opérations de Microsoft
  • Visualisateur de trace de service WCF
  • Autre ?

Si vous construisez une solution ASP.NET, utilisez-vous également la surveillance de santé ASP.NET ? Incluez-vous la sortie de trace dans les événements de surveillance de la santé ? Qu'en est-il de Trace.axd ?

Qu'en est-il des compteurs de performance personnalisés ?

232voto

Sly Points 2992

Mise à jour : Pour des extensions de System.Diagnostics, fournissant certains des listeners manquants que vous pourriez vouloir, voir Essential.Diagnostics sur CodePlex ( http://essentialdiagnostics.codeplex.com/ )


Cadres de travail

Q : Quels cadres de travail utilisez-vous ?

R : System.Diagnostics.TraceSource, intégré à .NET 2.0.

Il fournit une journalisation puissante, flexible et performante pour les applications. Cependant, de nombreux développeurs ne sont pas conscients de ses capacités et ne les utilisent pas pleinement.

Il y a certains domaines où une fonctionnalité supplémentaire est utile, ou parfois la fonctionnalité existe mais n'est pas bien documentée, cependant cela ne signifie pas que l'ensemble du cadre de journalisation (qui est conçu pour être extensible) devrait être jeté et complètement remplacé comme certaines alternatives populaires (NLog, log4net, Common.Logging, et même EntLib Logging).

Plutôt que de changer la façon dont vous ajoutez les déclarations de journalisation à votre application et de réinventer la roue, il suffit d'étendre le cadre System.Diagnostics aux quelques endroits où vous en avez besoin.

Il me semble que les autres frameworks, même EntLib, souffrent tout simplement du syndrome du "Not Invented Here", et je pense qu'ils ont perdu du temps à réinventer les bases qui fonctionnent déjà parfaitement bien dans System.Diagnostics (comme la façon d'écrire les déclarations de journal), plutôt que de combler les quelques lacunes qui existent. En bref, ne les utilisez pas - ils ne sont pas nécessaires.

Des caractéristiques que vous ne connaissiez peut-être pas :

  • L'utilisation des surcharges TraceEvent qui prennent une chaîne de format et des arguments peut améliorer les performances car les paramètres sont conservés comme références séparées jusqu'à ce que Filter.ShouldTrace() ait réussi. Cela signifie qu'il n'y a pas d'appels coûteux à ToString() sur les valeurs des paramètres jusqu'à ce que le système ait confirmé que le message sera effectivement enregistré.
  • Le gestionnaire de corrélation Trace.CorrelationManager permet de mettre en corrélation les déclarations de journal concernant la même opération logique (voir ci-dessous).
  • VisualBasic.Logging.FileLogTraceListener permet d'écrire dans des fichiers journaux et prend en charge la rotation des fichiers. Bien qu'il se trouve dans l'espace de noms VisualBasic, il peut être utilisé tout aussi facilement dans un projet C# (ou autre langage) en incluant simplement la DLL.
  • Lorsque vous utilisez EventLogTraceListener, si vous appelez TraceEvent avec plusieurs arguments et avec une chaîne de format vide ou nulle, les arguments sont transmis directement à EventLog.WriteEntry() si vous utilisez des ressources de message localisées.
  • L'outil Service Trace Viewer (de WCF) est utile pour visualiser les graphiques des fichiers journaux corrélés à l'activité (même si vous n'utilisez pas WCF). Cela peut vraiment aider à déboguer des problèmes complexes où plusieurs threads/activités sont impliqués.
  • Évitez les surcharges en effaçant tous les listeners (ou en supprimant Default) ; sinon Default transmettra tout au système de suivi (et subira toutes les surcharges de ToString()).

Les domaines que vous pourriez envisager d'étendre (si nécessaire) :

  • Écoute de la trace de la base de données
  • Écouteur de trace de console coloré
  • Écouteurs de traces MSMQ / Email / WMI (si nécessaire)
  • Implémenter un FileSystemWatcher pour appeler Trace.Refresh pour les changements de configuration dynamique

Autres recommandations :

Utilisez des identifiants d'événements structurés et conservez une liste de référence (par exemple, documentez-les dans une énumération).

Le fait de disposer d'un identifiant unique pour chaque événement (significatif) de votre système est très utile pour établir des corrélations et trouver des problèmes spécifiques. Il est facile de remonter jusqu'au code spécifique qui enregistre/utilise les identifiants d'événements et de fournir des conseils pour les erreurs courantes, par exemple, l'erreur 5178 signifie que la chaîne de connexion à la base de données est incorrecte, etc.

Les identifiants d'événements doivent suivre une certaine structure (similaire à la théorie des codes de réponse utilisée dans le courrier électronique et le protocole HTTP), qui vous permet de les traiter par catégorie sans connaître les codes spécifiques.

Par exemple, le premier chiffre peut indiquer la classe générale : 1xxx peut être utilisé pour les opérations de "démarrage", 2xxx pour le comportement normal, 3xxx pour le suivi des activités, 4xxx pour les avertissements, 5xxx pour les erreurs, 8xxx pour les opérations d'arrêt, 9xxx pour les erreurs fatales, etc.

Le deuxième chiffre peut détailler la zone, par exemple 21xx pour les informations relatives à la base de données (41xx pour les avertissements relatifs à la base de données, 51xx pour les erreurs relatives à la base de données), 22xx pour le mode de calcul (42xx pour les avertissements relatifs aux calculs, etc.), 23xx pour un autre module, etc.

Les identifiants d'événements attribués et structurés vous permettent également de les utiliser dans des filtres.

Q : Si vous utilisez le traçage, faites-vous usage de Trace.Correlation.StartLogicalOperation ?

R : Trace.CorrelationManager est très utile pour corréler les déclarations de journal dans n'importe quel type d'environnement multithread (c'est-à-dire à peu près tout de nos jours).

Vous devez au moins définir l'ActivityId une fois pour chaque opération logique afin d'établir une corrélation.

Start/Stop et le LogicalOperationStack peuvent alors être utilisés pour un contexte simple basé sur la pile. Pour des contextes plus complexes (par exemple, des opérations asynchrones), l'utilisation de TraceTransfer vers le nouvel ActivityId (avant de le modifier), permet la corrélation.

L'outil Service Trace Viewer peut être utile pour visualiser les graphiques d'activité (même si vous n'utilisez pas WCF).

Q : Écrivez-vous ce code manuellement ou utilisez-vous une forme de programmation orientée aspect pour le faire ? Vous voulez partager un extrait de code ?

R : Vous pouvez créer une classe d'étendue, par exemple LogicalOperationScope, qui (a) définit le contexte lors de sa création et (b) réinitialise le contexte lors de sa destruction.

Cela vous permet d'écrire un code tel que le suivant pour envelopper automatiquement les opérations :

  using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
  {
    // .. do work here
  }

Lors de sa création, l'étendue pourrait d'abord définir ActivityId si nécessaire, appeler StartLogicalOperation, puis enregistrer un message TraceEventType.Start. Lors de la suppression, elle peut enregistrer un message Stop, puis appeler StopLogicalOperation.

Q : Fournissez-vous une forme de granularité sur les sources de trace ? Par exemple, les TraceSources de WPF vous permettent de les configurer à différents niveaux.

R : Oui, les sources de traçage multiples sont utiles/importantes lorsque les systèmes deviennent plus grands.

Bien que vous souhaitiez probablement consigner systématiquement tous les messages d'avertissement et plus, ou tous les messages d'information et plus, pour tout système de taille raisonnable, le volume du suivi des activités (démarrage, arrêt, etc.) et de la consignation Verbose devient tout simplement trop important.

Plutôt que d'avoir un seul interrupteur pour tout activer ou désactiver, il est utile de pouvoir activer ces informations pour une section de votre système à la fois.

De cette façon, vous pouvez localiser les problèmes importants à partir de la journalisation habituelle (tous les avertissements, erreurs, etc.), puis "zoomer" sur les sections que vous souhaitez et les définir sur des niveaux de suivi d'activité ou même de débogage.

Le nombre de sources de traçage dont vous avez besoin dépend de votre application. Par exemple, vous pouvez vouloir une source de traçage par assemblage ou par section majeure de votre application.

Si vous avez besoin d'un contrôle encore plus précis, ajoutez des interrupteurs booléens individuels pour activer/désactiver le traçage de gros volumes spécifiques, par exemple les vidages de messages bruts. (Ou une source de traçage séparée pourrait être utilisée, comme pour WCF/WPF).

Vous pouvez également envisager des sources de traçage distinctes pour le suivi des activités et la journalisation générale (autre), car cela peut faciliter la configuration des filtres exactement comme vous le souhaitez.

Notez que les messages peuvent toujours être corrélés via ActivityId même si différentes sources sont utilisées, alors utilisez-en autant que nécessaire.


Auditeurs

Q : Quelles sorties de journaux utilisez-vous ?

Cela peut dépendre du type d'application que vous écrivez, et des éléments qui sont enregistrés. En général, différentes choses vont à différents endroits (c'est-à-dire des sorties multiples).

Je classe généralement les sorties en trois groupes :

(1) Événements - Journal des événements de Windows (et fichiers de trace)

Par exemple, si vous écrivez un serveur/service, la meilleure pratique sous Windows est d'utiliser le journal des événements de Windows (vous n'avez pas d'interface utilisateur à laquelle faire rapport).

Dans ce cas, tous les événements fatals, d'erreur, d'avertissement et d'information (au niveau du service) doivent aller dans le journal des événements de Windows. Le niveau Information doit être réservé à ce type d'événements de haut niveau, ceux que vous voulez voir apparaître dans le journal des événements, par exemple "Service démarré", "Service arrêté", "Connecté à Xyz", et peut-être même "Planification initiée", "Utilisateur connecté", etc.

Dans certains cas, vous pouvez souhaiter que l'écriture dans le journal des événements fasse partie intégrante de votre application et ne passe pas par le système de suivi (c'est-à-dire écrire directement les entrées du journal des événements). Cela signifie qu'elle ne peut pas être accidentellement désactivée. (Notez que vous souhaitez toujours noter le même événement dans votre système de suivi afin de pouvoir établir une corrélation).

En revanche, une application Windows GUI les signale généralement à l'utilisateur (bien qu'elles puissent également être enregistrées dans le journal des événements de Windows).

Les événements peuvent également être associés à des compteurs de performance (par exemple, le nombre d'erreurs par seconde). Il peut être important de coordonner l'écriture directe dans le journal des événements, les compteurs de performance, l'écriture dans le système de suivi et les rapports à l'utilisateur, de manière à ce qu'ils se produisent en même temps.

Par exemple, si un utilisateur voit un message d'erreur à un moment donné, vous devriez pouvoir trouver le même message d'erreur dans le journal des événements de Windows, puis le même événement avec le même horodatage dans le journal de suivi (avec d'autres détails de suivi).

(2) Activités - Fichiers journaux de l'application ou table de la base de données (et fichiers de trace)

Il s'agit de l'activité régulière d'un système, par exemple une page web servie, une transaction boursière effectuée, un ordre pris, un calcul effectué, etc.

Le suivi des activités (démarrage, arrêt, etc.) est utile ici (à la bonne granularité).

Il est également très courant d'utiliser un journal d'application spécifique (parfois appelé journal d'audit). Il s'agit généralement d'une table de base de données ou d'un fichier journal d'application qui contient des données structurées (c'est-à-dire un ensemble de champs).

Les choses peuvent devenir un peu floues ici en fonction de votre application. Un bon exemple pourrait être un serveur web qui écrit chaque requête dans un journal web ; des exemples similaires pourraient être un système de messagerie ou un système de calcul où chaque opération est enregistrée avec des détails spécifiques à l'application.

Un moins bon exemple est celui des transactions boursières ou d'un système de commande des ventes. Dans ces systèmes, vous enregistrez probablement déjà l'activité car elle a une valeur commerciale importante, mais le principe de la corrélation avec d'autres actions reste important.

Outre les journaux d'application personnalisés, les activités sont souvent associées à des compteurs de performance, par exemple le nombre de transactions par seconde.

En général, vous devez coordonner l'enregistrement des activités sur différents systèmes, c'est-à-dire écrire dans le journal de votre application en même temps que vous augmentez votre compteur de performance et que vous enregistrez dans votre système de suivi. Si vous faites tout en même temps (ou directement l'un après l'autre dans le code), le débogage des problèmes est plus facile (que s'ils se produisent tous à des moments/emplacements différents dans le code).

(3) Debug Trace - Fichier texte, ou peut-être XML ou base de données.

Il s'agit d'informations de niveau Verbose et inférieur (par exemple, des interrupteurs booléens personnalisés pour activer/désactiver les vidages de données brutes). Elles fournissent les détails de ce que fait un système au niveau de la sous-activité.

Il s'agit du niveau que vous souhaitez pouvoir activer/désactiver pour des sections individuelles de votre application (d'où les sources multiples). Vous ne voulez pas que ces éléments encombrent le journal des événements de Windows. Parfois, une base de données est utilisée, mais il est plus probable qu'il s'agisse de fichiers journaux roulants qui sont purgés après un certain temps.

Une grande différence entre ces informations et un fichier journal d'application est qu'elles ne sont pas structurées. Alors qu'un journal d'application peut comporter des champs pour les valeurs To, From, Amount, etc., les traces de débogage verbeuses peuvent être constituées de ce que le programmeur y inscrit, par exemple "vérification des valeurs X={valeur}, Y=faux", ou de commentaires/marqueurs aléatoires tels que "Terminé, réessayer".

Une pratique importante consiste à s'assurer que les éléments que vous consignez dans les fichiers journaux des applications ou dans le journal des événements de Windows sont également enregistrés dans le système de suivi avec les mêmes détails (par exemple, l'horodatage). Cela vous permet de corréler les différents journaux lors de vos recherches.

Si vous envisagez d'utiliser un visualisateur de journaux particulier parce que vous avez une corrélation complexe, par exemple le visualisateur de traces de service, vous devez utiliser un format approprié, c'est-à-dire XML. Sinon, un simple fichier texte est généralement suffisant - aux niveaux inférieurs, l'information est en grande partie non structurée, de sorte que vous pouvez trouver des vidages de tableaux, de piles, etc. Pour autant que vous puissiez établir une corrélation avec des journaux plus structurés aux niveaux supérieurs, tout devrait bien se passer.

Q : Si vous utilisez des fichiers, utilisez-vous des journaux continus ou un seul fichier ? Comment mettez-vous les journaux à la disposition des gens ?

R : Pour les fichiers, vous voulez généralement des fichiers de logs roulants du point de vue de la gestion (avec System.Diagnostics, utilisez simplement VisualBasic.Logging.FileLogTraceListener).

La disponibilité dépend à nouveau du système. Si vous ne parlez que de fichiers, alors pour un serveur/service, les fichiers roulants sont accessibles uniquement lorsque cela est nécessaire. (Le journal des événements de Windows ou les journaux des applications de base de données auraient leurs propres mécanismes d'accès).

Si vous ne disposez pas d'un accès facile au système de fichiers, il peut être plus facile d'effectuer un suivi de débogage vers une base de données. [Pour ce faire, il suffit d'implémenter un TraceListener de base de données.]

Une solution intéressante que j'ai vue pour une application Windows GUI consistait à enregistrer des informations de traçage très détaillées dans un "enregistreur de vol" pendant qu'elle fonctionnait, puis, lorsque vous l'arrêtiez, si elle ne présentait aucun problème, elle supprimait simplement le fichier.

Si, toutefois, il s'est écrasé ou a rencontré un problème, le fichier n'a pas été supprimé. S'il détecte l'erreur, ou la prochaine fois qu'il s'exécute, il remarquera le fichier, et pourra alors prendre des mesures, par exemple le compresser (par exemple avec 7zip) et l'envoyer par courrier électronique ou le rendre disponible.

De nos jours, de nombreux systèmes intègrent le signalement automatique des défaillances à un serveur central (après vérification auprès des utilisateurs, par exemple pour des raisons de confidentialité).


Visualisation de

Q : Quels outils utilisez-vous pour visualiser les journaux ?

R : Si vous avez plusieurs journaux pour différentes raisons, vous utiliserez plusieurs visionneurs.

Notepad/vi/Notepad++ ou tout autre éditeur de texte est la base pour les journaux en texte brut.

Si vous avez des opérations complexes, par exemple des activités avec des transferts, alors vous utiliserez évidemment un outil spécialisé comme le Service Trace Viewer. (Mais si vous n'en avez pas besoin, un éditeur de texte est plus simple).

Comme je consigne généralement les informations de haut niveau dans le journal des événements de Windows, il s'agit d'un moyen rapide d'obtenir une vue d'ensemble, de manière structurée (recherchez les jolies icônes d'erreur/d'avertissement). Il vous suffit de commencer à chercher dans les fichiers texte si le journal n'en contient pas suffisamment, mais au moins le journal vous donne un point de départ. (À ce stade, il est utile de s'assurer que vos journaux ont des entiers coordonnés).

En général, le journal des événements de Windows met également ces événements importants à la disposition d'outils de surveillance comme MOM ou OpenView.

Autres --

Si vous vous connectez à une base de données, il peut être facile de filtrer et de trier les informations (par exemple, zoomer sur un identifiant d'activité particulier) (avec les fichiers texte, vous pouvez utiliser Grep/PowerShell ou un outil similaire pour filtrer sur le GUID partiel que vous souhaitez).

MS Excel (ou un autre tableur). Cela peut s'avérer utile pour analyser des informations structurées ou semi-structurées si vous pouvez les importer avec les bons délimiteurs afin que des valeurs différentes soient placées dans des colonnes différentes.

Lorsque j'exécute un service en débogage/test, je l'héberge généralement dans une application console ; pour plus de simplicité, je trouve utile d'avoir un logger console coloré (par exemple rouge pour les erreurs, jaune pour les avertissements, etc). Vous devez implémenter un écouteur de trace personnalisé.

Notez que le framework n'inclut pas de collecteur de console coloré ou de collecteur de base de données. Pour l'instant, vous devez donc les écrire si vous en avez besoin (ce n'est pas trop difficile).

Cela m'ennuie vraiment que plusieurs frameworks (log4net, EntLib, etc.) aient perdu du temps à réinventer la roue et à réimplémenter l'enregistrement de base, le filtrage et l'enregistrement dans des fichiers texte, le journal des événements de Windows et les fichiers XML, chacun à sa manière (les instructions d'enregistrement sont différentes dans chacun) ; chacun a ensuite implémenté sa propre version, par exemple, d'un enregistreur de base de données, alors que la plupart de ces éléments existaient déjà et que tout ce qui était nécessaire était quelques écouteurs de trace supplémentaires pour System.Diagnostics. Vous parlez d'un grand gaspillage d'efforts redondants.

Q : Si vous construisez une solution ASP.NET, utilisez-vous également la surveillance de la santé d'ASP.NET ? Incluez-vous la sortie de trace dans les événements de surveillance de la santé ? Qu'en est-il de Trace.axd ?

Ces éléments peuvent être activés ou désactivés selon les besoins. Je trouve Trace.axd assez utile pour déboguer la façon dont un serveur répond à certaines choses, mais il n'est généralement pas utile dans un environnement très utilisé ou pour un traçage à long terme.

Q : Qu'en est-il des compteurs de performance personnalisés ?

Pour une application professionnelle, en particulier un serveur/service, je m'attends à ce qu'elle soit entièrement instrumentée à l'aide des compteurs de Performance Monitor et de l'enregistrement dans le journal des événements de Windows. Ce sont les outils standard de Windows et ils doivent être utilisés.

Vous devez vous assurer que vous incluez des installateurs pour les compteurs de performance et les journaux d'événements que vous utilisez ; ceux-ci doivent être créés au moment de l'installation (lors de l'installation en tant qu'administrateur). Lorsque votre application fonctionne normalement, elle ne devrait pas avoir besoin de privilèges d'administration (et ne pourra donc pas créer les journaux manquants).

C'est une bonne raison de s'entraîner à développer en tant que non-administrateur (ayez un compte administrateur distinct pour les cas où vous devez installer des services, etc.) Si vous écrivez dans le journal des événements, .NET créera automatiquement un journal manquant la première fois que vous écrirez dans ce journal. Si vous développez en tant que non-administrateur, vous vous en apercevrez rapidement et éviterez une mauvaise surprise lorsqu'un client installera votre système et ne pourra pas l'utiliser parce qu'il n'est pas exécuté en tant qu'administrateur.

40voto

Jeffrey Hantin Points 19272

Je dois me joindre au chœur qui recommande log4net, dans mon cas du point de vue de la flexibilité de la plate-forme (bureau .Net/Compact Framework, 32/64 bits).

Cependant, l'envelopper dans une API de marque privée est une anti-modèle majeur . log4net.ILogger est l'équivalent .Net de la fonction Enregistrement des communes emballage API De plus, comme il s'agit également d'une bibliothèque Apache, ce n'est généralement pas un problème, car vous n'abandonnez aucun contrôle : vous pouvez la bifurquer si vous le souhaitez.

La plupart des bibliothèques de wrapper maison que j'ai vues commettent également un ou plusieurs défauts parmi une litanie de défauts :

  1. Utilisation d'un logger global singleton (ou équivalent à un point d'entrée statique) qui perd la résolution fine de la recommandation modèle d'enregistreur par classe pour aucun autre gain de sélectivité.
  2. Le fait de ne pas exposer l'option Exception argument ce qui entraîne de multiples problèmes :
    • Cela rend une politique de consignation des exceptions encore plus difficile à maintenir, de sorte que rien n'est fait de manière cohérente avec les exceptions.
    • Même avec une politique cohérente, le formatage de l'exception dans une chaîne de caractères perd prématurément des données. J'ai écrit un programme personnalisé ILayout qui effectue une analyse détaillée d'une exception afin de déterminer la chaîne des événements.
  3. Le fait de ne pas exposer le Is_Level_Enabled propriétés qui ne permet pas d'ignorer le code de formatage lorsque des zones ou des niveaux d'enregistrement sont désactivés.

18voto

Elijah Points 6464

Je ne développe pas souvent en asp.net, mais lorsqu'il s'agit de journalisation, je pense que beaucoup de bonnes pratiques sont universelles. Voici quelques unes de mes réflexions aléatoires sur la journalisation que j'ai apprises au fil des ans :

Cadres de travail

  • Utilisez un cadre d'abstraction de collecteur, comme slf4j (ou créez le vôtre), afin de découpler la mise en œuvre du collecteur de votre API. J'ai vu un certain nombre de frameworks de journalisation aller et venir et il est préférable de pouvoir en adopter un nouveau sans trop de problèmes.
  • Essayez de trouver un cadre qui prend en charge une variété de formats de sortie.
  • Essayez de trouver un cadre qui prend en charge les plugins / filtres personnalisés.
  • Utilisez un cadre qui peut être configuré par des fichiers externes, de sorte que vos clients / consommateurs peuvent facilement modifier la sortie du journal afin qu'il puisse être lu par des applications commerciales de gestion des journaux avec facilité.
  • Veillez à ne pas dépasser les niveaux de journalisation personnalisés, sinon vous risquez de ne pas pouvoir passer à d'autres cadres de journalisation.

Sortie de l'enregistreur

  • Essayez d'éviter les journaux de style XML/RSS pour l'enregistrement qui pourrait rencontrer des défaillances catastrophiques. C'est important car si l'interrupteur d'alimentation est coupé sans que votre logger n'écrive la fermeture </xxx> tag, your log is broken. `* Log threads. Otherwise, it can be very difficult to track the flow of your program.

  • If you have to internationalize your logs, you may want to have a developer only log in English (or your language of choice).

  • Sometimes having the option to insert logging statements into SQL queries can be a lifesaver in debugging situations. Such as:`

    -- Invoking Class: com.foocorp.foopackage.FooClass:9021
    SELECT * FROM foo;
  • Vous voulez une journalisation au niveau de la classe. Normalement, vous ne voulez pas non plus d'instances statiques de loggers - cela ne vaut pas la peine de procéder à une micro-optimisation.

  • Il est parfois utile de marquer et de catégoriser les exceptions enregistrées, car toutes les exceptions ne se valent pas. Il est donc utile de connaître à l'avance un sous-ensemble d'exceptions importantes, si vous avez un moniteur de journaux qui doit envoyer des notifications en cas d'états critiques.

  • Les filtres de duplication épargneront votre vue et votre disque dur. Voulez-vous vraiment voir la même déclaration de journalisation répétée 10^10000000 fois ? Ne serait-il pas préférable d'obtenir un message du type : This is my logging statement - Repeated 100 times

Voir aussi cette question que je me pose .

17voto

Steve Moyer Points 4312

Je ne suis pas qualifié pour faire des commentaires sur la journalisation pour .Net, puisque mon pain et mon beurre sont Java, mais nous avons eu une migration dans notre journalisation au cours des 8 dernières années que vous pouvez trouver une analogie utile à votre question.

Nous avons commencé par un logger Singleton utilisé par chaque thread de la JVM, et nous avons défini le niveau de logging pour l'ensemble du processus. Il en résultait d'énormes journaux si nous devions déboguer ne serait-ce qu'une partie très spécifique du système. La leçon numéro un est donc de segmenter votre journalisation.

Notre incarnation actuelle de l'enregistreur permet plusieurs instances, une seule étant définie par défaut. Nous pouvons instancier n'importe quel nombre de loggers enfants qui ont différents niveaux de logging, mais la facette la plus utile de cette architecture est la possibilité de créer des loggers pour des packages et des classes individuels en changeant simplement les propriétés de logging. La leçon numéro deux est de créer un système flexible qui permet de remplacer son comportement sans modifier le code.

Nous utilisons la bibliothèque Apache commons-logging enveloppée dans Log4J.

J'espère que cela vous aidera !

* Editer *

Après avoir lu le billet de Jeffrey Hantin ci-dessous, j'ai réalisé que j'aurais dû noter ce que notre wrapper de journalisation interne est devenu. C'est maintenant essentiellement une usine et il est strictement utilisé pour obtenir un logger fonctionnel en utilisant le fichier de propriétés correct (qui pour des raisons d'héritage n'a pas été déplacé vers la position par défaut). Puisque vous pouvez maintenant spécifier le fichier de configuration de l'enregistrement sur la ligne de commande, je soupçonne qu'il deviendra encore plus maigre et si vous démarrez une nouvelle application, je serais définitivement d'accord avec sa déclaration selon laquelle vous ne devriez même pas prendre la peine d'envelopper le logger.

9voto

Aaron Powell Points 15598

Au travail, nous utilisons Log4Net comme fournisseur de journalisation, avec un wrapper singleton pour l'instance de journalisation (bien que le singleton soit en cours de révision, pour savoir si c'est une bonne idée ou non).

Nous l'avons choisi pour les raisons suivantes :

  • Configuration/ reconfiguration simple sur différents environnements
  • Un bon nombre d'appenders préconstruits
  • L'un des CMS que nous utilisons l'a déjà intégré.
  • Un nombre intéressant de niveaux de journalisation et de configurations autour d'eux

Je dois préciser que c'est un point de vue de développement ASP.NET.

Je vois certains avantages à utiliser la fonction Trace du cadre .NET, mais je ne suis pas entièrement convaincu, principalement parce que les composants avec lesquels je travaille ne font pas vraiment d'appels Trace. La seule chose que j'utilise fréquemment et qui le fait est System.Net.Mail d'après ce que je peux dire.

Nous avons donc une bibliothèque qui englobe log4net et dans notre code, nous avons juste besoin de ce genre de choses :

Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());

try {
  var i = int.Parse("Hello World");
} catch(FormatException, ex) {
  Logger.Instance.Error(ex);
}

Dans les méthodes, nous vérifions si le niveau de journalisation est activé, afin d'éviter les appels redondants à l'API log4net (si Debug n'est pas activé, les instructions de débogage sont ignorées), mais lorsque j'aurai un peu de temps, je mettrai à jour ces méthodes pour que vous puissiez effectuer les vérifications vous-même. Cela empêchera les évaluations d'être entreprises quand elles ne devraient pas l'être, par exemple :

Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

Cela deviendra :

if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

(Gagner un peu de temps d'exécution)

Par défaut, nous enregistrons à deux endroits :

  1. Système de fichiers du site web (dans une extension de fichier non réservée)
  2. Envoi d'un courriel en cas d'erreur ou de décès

Les fichiers se font par roulement de chaque jour ou 10mb (IIRC). Nous n'utilisons pas l'EventLog car il peut exiger une sécurité plus élevée que celle que nous voulons souvent donner à un site.

Je trouve que Notepad fonctionne très bien pour lire les journaux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X