.net - practices - serilog




Enregistrement des meilleures pratiques (7)

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?



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 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 .


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.


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.


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.





tracing