.net asp.net - Enregistrement des meilleures pratiques




core logging (9)

Mise à jour: pour les extensions de System.Diagnostics, en fournissant certains des écouteurs manquants, consultez Essential.Diagnostics sur CodePlex ( http://essentialdiagnostics.codeplex.com/ )

Cadres

Q: Quels cadres utilisez-vous?

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

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

Il existe des domaines où des fonctionnalités supplémentaires sont utiles, ou parfois la fonctionnalité existe mais n'est pas bien documentée, mais cela ne signifie pas que tout le cadre de journalisation (qui est conçu pour être extensible) doit être jeté et complètement remplacé comme certaines alternatives populaires (NLog, log4net, Common.Logging, et même EntLib Logging).

Plutôt que de modifier la façon dont vous ajoutez des instructions de journalisation à votre application et de réinventer la roue, vous n'avez qu'à étendre le framework System.Diagnostics aux endroits où vous en avez besoin.

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

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 en tant que références distinctes jusqu'à ce que Filter.ShouldTrace () ait réussi. Cela signifie qu'aucun appel coûteux à ToString () sur les valeurs de paramètres tant que le message n'a pas été confirmé par le système ne sera effectivement consigné.
  • Le Trace.CorrelationManager vous permet de corréler les instructions de journal à propos de la même opération logique (voir ci-dessous).
  • VisualBasic.Logging.FileLogTraceListener est bon pour écrire dans les fichiers journaux et prend en charge la rotation des fichiers. Bien que dans l'espace de noms VisualBasic, il peut être aussi facilement utilisé dans un projet C # (ou un autre langage) simplement en incluant 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 messages localisées.
  • L'outil Service Trace Viewer (à partir de WCF) est utile pour afficher des graphiques de fichiers journaux corrélés d'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 frais généraux en effaçant tous les écouteurs (ou en supprimant Default); sinon Default passera tout au système de trace (et encourra tous ces overheads ToString ()).

Les zones que vous pourriez vouloir agrandir (si nécessaire):

  • Analyseur de trace de base de données
  • Écouteur de trace de console colorée
  • Auditeurs de suivi MSMQ / Email / WMI (si nécessaire)
  • Implémenter un FileSystemWatcher pour appeler Trace.Refresh pour les modifications de configuration dynamiques

Autres recommandations

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

Avoir des identifiants d'événement uniques pour chaque événement (significatif) dans votre système est très utile pour corréler et trouver des problèmes spécifiques. Il est facile de retrouver le code spécifique qui enregistre / utilise les identifiants d'événement, et peut faciliter le guidage des 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énement doivent suivre une structure (similaire à la théorie des codes de réponse utilisée dans le courrier électronique et le protocole HTTP), ce qui vous permet de les traiter par catégorie sans connaître les codes spécifiques.

Le premier chiffre peut détailler la classe générale: 1xxx peut être utilisé pour les opérations 'Start', 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 'Stop', 9xxx pour les erreurs fatales, etc.

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

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

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

R: Trace.CorrelationManager est très utile pour corréler les instructions de log dans n'importe quel environnement multithread (ce qui est à peu près tout ce qui se passe de nos jours).

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

Start / Stop et LogicalOperationStack peuvent ensuite être utilisés pour un contexte basé sur une pile simple. Pour les contextes plus complexes (par exemple les 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 afficher des graphiques d'activité (même si vous n'utilisez pas WCF).

Q: Est-ce que vous écrivez ce code manuellement, ou utilisez-vous une forme de programmation orientée aspect pour le faire? Voulez-vous partager un extrait de code?

R: Vous pouvez créer une classe d'étendue, par exemple LogicalOperationScope, qui (a) configure le contexte une fois créé et (b) réinitialise le contexte lorsqu'il est éliminé.

Cela vous permet d'écrire du code comme celui-ci pour envelopper automatiquement les opérations:

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

Lors de la création, la portée peut d'abord définir ActivityId si nécessaire, appeler StartLogicalOperation, puis enregistrer un message TraceEventType.Start. Sur Dispose, il peut enregistrer un message d'arrêt, puis appeler StopLogicalOperation.

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

R: Oui, plusieurs sources de trace sont utiles / importantes à mesure que les systèmes deviennent plus grands.

Bien que vous souhaitiez probablement consigner systématiquement tous les messages Avertissement & ci-dessus, ou tous les messages d'information et supérieurs, pour tout système de taille raisonnable, le volume de traçage d'activité (démarrage, arrêt, etc.) et de consignation verbeuse devient trop important.

Plutôt que d'avoir un seul commutateur qui allume ou éteint tout, il est utile de pouvoir activer cette information pour une section de votre système à la fois.

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

Le nombre de sources de trace dont vous avez besoin dépend de votre application, par exemple, vous pouvez choisir une source de trace par assemblage ou par grande section de votre application.

Si vous avez besoin d'un contrôle encore plus précis, ajoutez des commutateurs booléens individuels pour activer / désactiver le suivi de grand volume spécifique, par exemple les vidages de messages bruts. (Ou une source de trace séparée pourrait être utilisée, similaire à WCF / WPF).

Vous pouvez également envisager des sources de trace séparées pour la trace d'activité par rapport à 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, utilisez-en autant que vous le souhaitez.

Les auditeurs

Q: Quelles sorties de journal utilisez-vous?

Cela peut dépendre du type d'application que vous écrivez et des éléments qui sont consignés. Habituellement, différentes choses vont dans des endroits différents (c'est-à-dire plusieurs sorties).

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

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

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

Dans ce cas, tous les événements d'informations Fatal, Error, Warning et (au niveau du service) doivent être envoyés au journal des événements Windows. Le niveau d'information doit être réservé pour ces types d'événements de haut niveau, ceux que vous voulez aller dans le journal des événements, par exemple "Service Started", "Service Stopped", "Connecté à Xyz" et peut-être même "Schedule Initiated" , "Utilisateur connecté", etc.

Dans certains cas, vous pouvez écrire dans le journal des événements une partie intégrée de votre application et non via le système de trace (c'est-à-dire écrire directement les entrées du journal des événements). Cela signifie qu'il ne peut pas être désactivé accidentellement. (Notez que vous voulez toujours noter le même événement dans votre système de trace, donc vous pouvez corréler).

En revanche, une application Windows GUI signale généralement à l'utilisateur (bien qu'ils puissent également se connecter au journal des événements Windows).

Les événements peuvent également avoir des compteurs de performance associés (par exemple, nombre d'erreurs par seconde) et il peut être important de coordonner toute écriture directe dans le journal des événements, les compteurs de performance, l'écriture dans le système de trace et les rapports à l'utilisateur. le même temps.

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 Windows, puis le même événement avec le même horodatage dans le journal de suivi (ainsi que d'autres détails de trace).

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

C'est l'activité régulière d'un système, par exemple la page Web desservie, le commerce boursier déposé, la prise de commande, le calcul effectué, etc.

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

En outre, il est très courant d'utiliser un journal d'application spécifique (parfois appelé journal d'audit). Généralement, il s'agit d'une table de base de données ou d'un fichier journal d'application contenant des données structurées (c'est-à-dire un ensemble de champs).

Les choses peuvent devenir un peu floues selon votre application. Un bon exemple pourrait être un serveur Web qui écrit chaque demande dans un journal Web; Des exemples similaires peuvent ê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 exemple moins bon est les transactions boursières ou un système de commande de vente. Dans ces systèmes, vous êtes probablement déjà connecté à l'activité car ils ont une valeur commerciale importante, mais le principe de les corréler à d'autres actions est toujours important.

En plus des journaux d'application personnalisés, les activités ont souvent des compteurs de performance, par exemple le nombre de transactions par seconde.

En général, vous devez coordonner la consignation des activités entre différents systèmes, c'est-à-dire écrire dans le journal de vos applications en même temps que vous augmentez votre compteur de performance et que vous vous connectez à votre système de trace. Si vous faites tout en même temps (ou directement les uns après les autres dans le code), alors les problèmes de débogage sont plus faciles (que s'ils se produisent tous à des heures / endroits différents dans le code).

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

Il s'agit d'informations au niveau détaillé et inférieur (par exemple, des options booléennes personnalisées pour activer / désactiver les vidages de données brutes). Ceci fournit les entrailles ou les détails de ce qu'un système fait au niveau d'une sous-activité.

C'est le niveau que vous souhaitez activer / désactiver pour des sections individuelles de votre application (d'où les multiples sources). Vous ne voulez pas que ces choses encombrent le journal des événements Windows. Parfois, une base de données est utilisée, mais il est plus probable que les fichiers journaux de roulement soient purgés après un certain temps.

Une grande différence entre ces informations et un fichier journal d'application est qu'il n'est pas structuré. Alors qu'un journal d'application peut avoir des champs To, From, Amount, etc., les traces de débogage Verbose peuvent être tout ce qu'un programmeur met, par exemple "vérifier les valeurs X = {valeur}, Y = false", ou des commentaires / marqueurs aléatoires comme " Fait, essayant encore ".

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

Si vous envisagez d'utiliser une visionneuse de journaux particulière parce que vous avez une corrélation complexe, par exemple la visionneuse de suivi des services, vous devez utiliser un format approprié, par exemple XML. Sinon, un simple fichier texte est généralement assez bon - aux niveaux les plus bas, les informations sont en grande partie non structurées, donc vous pourriez trouver des décharges de tableaux, des sauvegardes de pile, etc. va bien.

Q: Si vous utilisez des fichiers, utilisez-vous des journaux de roulement ou un seul fichier? Comment faites-vous les journaux disponibles pour les gens à consommer?

R: Pour les fichiers, vous voulez généralement faire rouler les fichiers journaux d'un 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, il suffit d'accéder aux fichiers roulants si nécessaire. (Le journal des événements Windows ou les journaux des applications de base de données ont leurs propres mécanismes d'accès).

Si vous n'avez pas un accès facile au système de fichiers, le suivi du débogage vers une base de données peut être plus facile. [ie implémenter une base de données TraceListener].

Une solution intéressante pour une application Windows GUI était qu'elle enregistrait des informations de traçage très détaillées sur un "enregistreur de vol" en cours d'exécution, puis lorsque vous l'éteigniez si elle n'avait aucun problème, elle supprimait simplement le fichier.

Si, cependant, il s'est écrasé ou a rencontré un problème, le fichier n'a pas été supprimé. Soit si elle attrape l'erreur, ou la prochaine fois qu'elle s'exécute, elle remarquera le fichier, puis elle peut agir, par exemple le compresser (par exemple 7zip) et l'envoyer par courrier électronique ou autrement rendre disponible.

De nos jours, de nombreux systèmes intègrent le reporting automatisé des pannes sur un serveur central (après vérification auprès des utilisateurs, par exemple pour des raisons de confidentialité).

Voir

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

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

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, 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 facile).

Comme je consigne généralement des informations de haut niveau dans le journal des événements de Windows, il fournit un moyen rapide d'obtenir une vue d'ensemble, de manière structurée (recherchez les icônes d'erreur / d'avertissement). Vous n'avez besoin de commencer à parcourir les fichiers texte que s'il n'y en a pas assez dans le journal, bien qu'au moins le journal vous donne un point de départ. (À ce stade, s'assurer que vos logs ont des coordonnées coordonnées devient utile).

Généralement, le journal des événements Windows met également ces événements importants à la disposition des outils de surveillance tels que 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 similaire pour filtrer le GUID que vous voulez)

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

Lors de l'exécution d'un service de débogage / test, je l'héberge habituellement dans une application de console pour plus de simplicité. Je trouve un enregistreur de console de couleur utile (par exemple rouge pour les erreurs, jaune pour les avertissements, etc.). Vous devez implémenter un écouteur de trace personnalisé.

Notez que la structure n'inclut pas un enregistreur de consoles de couleur ou un enregistreur de base de données. Pour le moment, vous devriez 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 la journalisation de base, le filtrage et la journalisation dans les fichiers texte, le journal des événements Windows et les fichiers XML. manière différente (les déclarations de journal sont différentes dans chaque cas); chacun a ensuite implémenté sa propre version de, par exemple, un enregistreur de base de données, alors que la plupart de ceux-ci existaient déjà et qu'il suffisait de deux autres écouteurs de trace pour System.Diagnostics. Parler d'un grand gaspillage d'efforts en double.

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

Ces choses peuvent être activées / désactivées au besoin. Je trouve Trace.axd très utile pour déboguer comment un serveur répond à certaines choses, mais ce n'est généralement pas utile dans un environnement très utilisé ou pour le 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 à le voir entièrement instrumenté avec les compteurs de l'Analyseur de performances et la journalisation dans le journal des événements Windows. Ce sont les outils standard dans Windows et devraient être utilisés.

Vous devez vous assurer que vous incluez des programmes d'installation pour les compteurs de performance et les journaux d'événements que vous utilisez; ceux-ci doivent être créés lors 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 de journaux manquants).

C'est une bonne raison pour pratiquer le développement en tant que non-administrateur (ayez un compte d'administrateur séparé pour quand vous devez installer des services, etc.). Si vous écrivez dans le journal des événements, .NET crée automatiquement un journal manquant la première fois que vous y écrivez; Si vous développez en tant que non-administrateur, vous le remarquerez rapidement et éviterez une mauvaise surprise lorsqu'un client installe votre système et ne peut pas l'utiliser parce qu'il ne fonctionne pas en tant qu'administrateur.

J'aimerais avoir des histoires sur la façon dont les gens traitent le traçage et la connexion aux applications réelles. Voici quelques questions qui pourraient vous aider à expliquer votre réponse.

Cadres

Quels cadres utilisez-vous?

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

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

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

Fournissez-vous une forme de granularité sur les sources de traces? Par exemple, WPF TraceSources vous permet de les configurer à différents niveaux:

  • System.Windows - paramètres pour tous les fichiers WPF
  • System.Windows.Animation - remplacer spécifiquement pour l'animation.

Les auditeurs

Quelles sorties de journal utilisez-vous?

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

Si vous utilisez des fichiers, utilisez-vous des journaux de roulement ou un seul fichier? Comment faites-vous les journaux disponibles pour les gens à consommer?

Voir

Quels outils utilisez-vous pour afficher les journaux?

  • Bloc-notes
  • Queue
  • Observateur d'événements
  • Gestionnaire des opérations de Systems Center / Microsoft Operations Manager
  • WCF Service Trace Viewer
  • Autre?

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

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


Je ne développe pas souvent dans asp.net, cependant quand il s'agit de bûcherons, je pense que beaucoup de meilleures pratiques sont universelles. Voici quelques unes de mes réflexions sur l'exploitation forestière que j'ai apprises au cours des années:

Cadres

  • Utilisez un framework d'abstraction de consignation, comme slf4j (ou lancez le vôtre), afin de découpler l'implémentation de l'enregistreur de votre API. J'ai vu un certain nombre de cadres d'enregistreurs aller et venir et vous feriez mieux d'en adopter un nouveau sans trop de tracas.
  • Essayez de trouver un cadre qui prend en charge une variété de formats de sortie.
  • Essayez de trouver un framework qui supporte les plugins / filtres personnalisés.
  • Utilisez un framework qui peut être configuré par des fichiers externes, afin que vos clients / consommateurs puissent facilement modifier la sortie du journal afin qu'il puisse être facilement lu par les applications de gestion de journaux commerciales.
  • Assurez-vous de ne pas dépasser les niveaux de journalisation personnalisés, sinon vous risquez de ne pas pouvoir accéder à différents cadres de journalisation.

Sortie de l'enregistreur

  • Essayez d'éviter les journaux de style XML / RSS pour la journalisation qui pourraient rencontrer des échecs catastrophiques. Ceci est important car si l'interrupteur d'alimentation est éteint sans que votre enregistreur n'écrive la </xxx> fermeture </xxx> , votre journal est brisé.
  • Journaliser les discussions. Sinon, il peut être très difficile de suivre le déroulement de votre programme.
  • Si vous devez internationaliser vos journaux, vous souhaiterez peut-être qu'un développeur se connecte uniquement en anglais (ou dans la langue de votre choix).
  • Parfois, avoir la possibilité d'insérer des instructions de journalisation dans des requêtes SQL peut être une bouée de sauvetage dans les situations de débogage. Tel que:
    -- Invoking Class: com.foocorp.foopackage.FooClass:9021
    SELECT * FROM foo;
  • Vous voulez une journalisation au niveau de la classe. Normalement, vous ne voulez pas d'instances statiques de loggers - cela ne vaut pas la micro-optimisation.
  • Le marquage et la catégorisation des exceptions consignées sont parfois utiles car toutes les exceptions ne sont pas créées de la même manière. Connaître un sous-ensemble d'exceptions importantes est donc utile si vous avez un moniteur de journal qui doit envoyer des notifications sur les états critiques.
  • Les filtres de duplication vont sauver 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 mieux d'avoir un message tel que: This is my logging statement - Repeated 100 times

Voir aussi cette question à moi .


Il y a beaucoup de bonnes recommandations dans les réponses.

Une meilleure pratique générale consiste à déterminer qui lira le journal. Dans mon cas, ce sera un administrateur sur le site client. J'enregistre donc les messages qui leur donnent quelque chose sur lequel ils peuvent agir. Par exemple, "Impossible d'initialiser l'application, généralement provoquée par ......"


Nous utilisons Log4Net au travail en tant que fournisseur de journalisation, avec un wrapper singleton pour l'instance de journal (bien que le singleton soit en cours de révision, se demandant si c'est une bonne idée ou non).

Nous l'avons choisi pour les raisons suivantes:

  • Configuration / reconfiguration simple sur différents environnements
  • Bon nombre d'appenders préconstruits
  • L'un des CMS que nous utilisons déjà l'avait intégré
  • Bon nombre de niveaux de log et de configurations autour d'eux

Je devrais mentionner, cela parle d'un point de vue de développement ASP.NET

Je peux voir quelques avantages à utiliser le Trace qui est dans le framework .NET mais je ne suis pas entièrement vendu dessus, principalement parce que les composants avec lesquels je travaille ne font pas vraiment d'appels Trace. La seule chose que j'utilise fréquemment c'est System.Net.Mail après ce que je peux dire.

Nous avons donc une bibliothèque qui enveloppe log4net et dans notre code nous avons juste besoin de choses comme ceci:

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é, donc vous n'avez pas d'appels redondants à l'API log4net (donc si le débogage n'est pas activé, les instructions de débogage sont ignorées), mais quand j'ai le temps Je vais le mettre à jour pour les exposer afin que vous puissiez faire les vérifications vous-même. Cela empêchera les évaluations d'être effectuées alors qu'elles ne le devraient pas, 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);

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

Par défaut, nous nous connectons à deux endroits:

  1. Système de fichiers du site Web (dans une extension de fichier non desservie)
  2. Email d'envoi pour Error & Fatal

Les fichiers sont faits comme roulant de chaque jour ou 10mb (IIRC). Nous n'utilisons pas le journal des événements car il peut nécessiter une sécurité plus élevée que celle que nous souhaitons souvent attribuer à un site.

Je trouve le bloc-notes fonctionne très bien pour lire les journaux.


Quels cadres utilisez-vous?

Nous utilisons un mélange du bloc d'application de journalisation et un assistant de journalisation personnalisé qui fonctionne autour des bits du framework .Net. Le LAB est configuré pour générer des fichiers journaux assez volumineux comprenant des fichiers de trace généraux séparés pour l'entrée / la sortie de la méthode de service et des fichiers d'erreurs spécifiques pour les problèmes inattendus. La configuration inclut la date / heure, le thread, le pId, etc. pour l'assistance au débogage ainsi que le détail et la pile de l'exception (dans le cas d'une exception inattendue).

L'aide de journalisation personnalisée utilise la fonction Trace.Correlation et est particulièrement utile dans le contexte de la journalisation dans WF. Par exemple, nous avons une machine d'état qui appelle une série de flux de travail séquentiels. À chacune de ces activités d'invocation, nous enregistrons le début (en utilisant StartLogicalOperation), puis à la fin nous arrêtons l'opération logique avec un gestionnaire d'événement de retour gereric.

Cela s'est avéré utile plusieurs fois pour tenter de déboguer des échecs dans des séquences métier complexes car cela nous permet de déterminer plus rapidement des choses comme les décisions de branchement If / Else etc. en fonction de la séquence d'exécution de l'activité.

Quelles sorties de journal utilisez-vous?

Nous utilisons des fichiers texte et des fichiers XML. Les fichiers texte sont configurés via le bloc d'application, mais nous avons aussi des sorties XML de notre service WF. Cela nous permet de capturer les événements d'exécution (persistance, etc.) ainsi que les exceptions génériques de type métier. Les fichiers texte sont des journaux de roulement qui sont déroulés par jour et par taille (je crois que la taille totale de 1 Mo est un point de survol).

Quels outils utilisez-vous pour afficher les journaux?

Nous utilisons Bloc-notes et WCF Service Trace Viewer selon le groupe de sortie que nous recherchons. Le WCF Service Trace Viewer est vraiment très pratique si vous avez correctement configuré votre sortie et que vous pouvez rendre la lecture beaucoup plus simple. Cela dit, si je sais à peu près où l'erreur est de toute façon - juste lire un fichier texte bien annoté est bon aussi.

Les journaux sont envoyés à un seul répertoire qui est ensuite divisé en sous-répertoires basés sur le service source. Le répertoire racine est exposé via un site Web dont l'accès est contrôlé par un groupe d'utilisateurs de support. Cela nous permet d'examiner les journaux de production sans avoir à soumettre de demandes et de passer par de longues procédures administratives pour les données de production.


Nous utilisons log4net sur nos applications web.

Sa capacité à personnaliser la journalisation au moment de l'exécution en modifiant le fichier de configuration XML est très pratique lorsqu'une application ne fonctionne pas correctement au moment de l'exécution et que vous avez besoin de plus d'informations.

Il vous permet également de cibler des classes ou des attributs spécifiques pour vous connecter. C'est très pratique lorsque vous avez une idée où l'erreur se produit. Un exemple classique est NHibernate où vous voulez voir juste le SQL allant à la base de données.

Modifier:

Nous écrivons tous les événements dans une base de données et dans le système Trace. Le journal des événements que nous utilisons pour les erreurs ou les exceptions. Nous enregistrons la plupart des événements dans une base de données afin que nous puissions créer des rapports personnalisés et laisser les utilisateurs afficher le journal s'ils veulent directement à partir de l'application.


En tant qu'auteurs de l'outil, nous utilisons bien sûr SmartInspect pour la journalisation et le traçage des applications .NET. Nous utilisons généralement le protocole de canal nommé pour la journalisation en direct et les fichiers journaux binaires (cryptés) pour les journaux de l'utilisateur final. Nous utilisons la console SmartInspect comme outil de visualisation et de surveillance.

Il existe en fait un certain nombre de frameworks et d'outils de journalisation pour .NET. Il y a une vue d'ensemble et une comparaison des différents outils sur DotNetLogging.com .


Je dois rejoindre le refrain recommandant log4net, dans mon cas venant d'un point de vue de flexibilité de plate-forme (bureau .Net / Compact Framework, 32/64-bit).

Toutefois, l'envelopper dans une API de marque privée est un anti-pattern majeur . log4net.ILogger est déjà la contrepartie .Net de l' API wrapper Commons Logging , donc le couplage est déjà minimisé pour vous, et comme c'est aussi une librairie Apache, ce n'est généralement pas un problème car vous n'abandonnez aucun contrôle: fork si tu le dois.

La plupart des librairies que j'ai vues commettent aussi une ou plusieurs erreurs:

  1. Utilisation d'un enregistreur singleton global (ou, de manière équivalente, d'un point d'entrée statique) qui perd la résolution fine du modèle logger par classe recommandé pour aucun autre gain de sélectivité.
  2. Avoir omis d'exposer l'argument Exception facultatif , entraînant plusieurs problèmes:
    • Cela rend la gestion des exceptions encore plus difficile à gérer, donc rien n'est fait de manière cohérente avec des exceptions.
    • Même avec une stratégie cohérente, la mise en forme de l'exception dans une chaîne perd prématurément des données. J'ai écrit un décorateur ILayout personnalisé qui effectue une ILayout détaillée d'une exception pour déterminer la chaîne d'événements.
  3. Ne pas afficher les propriétés Is Level Enabled , ce qui élimine la possibilité d'ignorer le code de mise en forme lorsque les zones ou les niveaux de journalisation sont désactivés.

Je pense que log4net fait tout ce que vous avez énuméré pour moi.

Les écouteurs enfichables ressemblent à des appenders - ils sont nombreux et en fait j'ai même piraté le fichier journal de roulement pour toujours se terminer en .log (pour les associations de fichiers), ajouté un champ cc à l'appender e-mail, et ai finalement mes valeurs préférées pour l'appender de console coloré. Si je peux être si audacieux - mon bonheur de console colorée:

<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<!-- Can Use:
        Blue
        Green
        Red
        White
        Yellow
        Purple
        Cyan
        HighIntensity
        -->
<mapping>
  <level value="FATAL" />
  <foreColor value="Yellow, HighIntensity" />
  <backColor value="Red" />
</mapping>
<mapping>
  <level value="ERROR" />
  <foreColor value="White" />
  <backColor value="Purple, HighIntensity" />
</mapping>
<mapping>
  <level value="WARN" />
  <backColor value="Blue" />
  <foreColor value="White" />
</mapping>
<mapping>
  <level value="INFO" />
  <backColor value="Green" />
  <foreColor value="White" />
</mapping>
<mapping>
  <level value="DEBUG" />
  <foreColor value="White" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
  <!--<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />-->
  <!--<conversionPattern value="%-5level %file:%line - %message%newline" />-->
  <conversionPattern value="%level %logger:%line %newline     %message%newline" />
</layout>

Commutateurs de suivi personnalisables: Log4net est uniquement fourni avec FATAL ERROR WARN INFO DEBUG dans l'ordre d'augmentation de la verbosité. Le seul qui me manque est AUDIT pour qui a fait quoi.

Configuration personnalisable: J'utilise un fichier log4net.config que je charge à l'exécution (ou écris un journal dans c: \ whining que je ne trouve pas la config.)

    Try
        ' Get log4net configuration from file
        Dim logConfigFile As FileInfo
        logConfigFile = New FileInfo(".\log4net.config")

        If logConfigFile.Exists Then
            XmlConfigurator.Configure(logConfigFile)
        Else
            CreateEmergenceLogFile(logConfigFile.FullName)
        End If

    Catch ex As Exception
        Console.Out.WriteLine("Could not load the log4net config file")
    End Try

juste un grand nombre de TraceListeners: désolé de sauter celui-là - je vais vous croire sur parole.

Corrélation des activités / étendues: voulez-vous dire que chaque fichier (classe de lecture) obtient son propre journal nommé qui peut avoir des seuils de niveau de journalisation distincts. En fait, vous pouvez segmenter la journalisation même dans une seule classe (qui en vérité peut avoir grandi pour en faire trop ...)

Dans un fichier de classe:

    Private Shared _logger As log4net.ILog = _
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

Private Shared _loggerAttribute As log4net.ILog = _
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName & ".Attribute")

Private Shared _loggerCache As log4net.ILog = _
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName & ".Cache")

Service View Trace Viewer: dans le fichier log4net.config:

  <logger name="NipissingU.ADWrapper.EntryTools.Attribute">
    <level value="INFO" />
  </logger>
  <logger name="NipissingU.ADWrapper.EntryTools.Cache">
    <level value="WARN" />
  </logger>

Tout est configurable dans app.config / web.config: bien peut-être que c'est une bonne chose dans ASP.NET, je ne sais pas, mais quand je fais des applications de comptage de beans clients riches, j'aime un fichier de configuration séparé.

Tout ici est juste mes propres petites astuces d'utilisation.

hth, -Mike





.net asp.net logging tracing