[Logs] Utiliser Log4Net dans son application 2/8

Auteur du billet de blog : Nicolas Hilaire - Neotech Solutions

Nicolas Hilaire

Consultant .NET
  Publié le jeudi 19 mai 2016

Artisan logiciel particulièrement intéressé par les technologies .NET. Polyvalent et curieux, je suis néanmoins à l'écoute des autres technologies du marché. MVP (Microsoft Most Valuable Professional) de 2007 à 2014, je suis également auteur d'un ouvrage pour apprendre le C#, à destination des débutants et de plusieurs MOOCs sur le C#, Windows Phone ou ASP.NET MVC...

Après avoir parlé de pourquoi il faut loguer, intéressons-nous maintenant au plus célèbre des outils de log, et particulièrement sa version pour le framework .NET : Log4Net.

Ce billet fait partie d’une série sur les logs dont voici les différents liens :

  1. Pourquoi avoir recours à des logs dans une application
  2. Utiliser Log4Net dans son application
  3. Ecrire un message de log utile
  4. Les appenders Log4Net
  5. Ecrire son propre appender Log4Net pour loguer dans MongoDB
  6. Centraliser les logs avec GrayLog
  7. Loguer dans GrayLog depuis une application Windows Phone
  8. Centralisation de logs avec ELK

 

Log4Net est un outil permettant d’aider les développeurs à créer des logs à destination de diverses sorties, la plus connue étant les fichiers. Il s’agit d’un portage de Apache log4j permettant d’utiliser les briques du framework .NET.

Les logs sont très utiles pour identifier des problèmes sur des applications et une des grandes forces de Log4Net est la capacité d’activer des niveaux de log pendant le runtime. Du coup, il devient possible de multiplier les logs dans l’application et de les activer uniquement lorsque l’on en a besoin. Bien sûr, lorsque l’application rencontre un log non-activé, elle ne le traite pas et les performances générales de l’application ne sont pas pénalisées.

Log4Net est disponible sous la forme d’un package Nuget, le plus simple étant de l’installer via Visual Studio.

Créons donc un petit projet pour illustrer ça, disons une application console, et ajoutons une référence à Log4Net :

 

Le plus important est la référence à l’assembly log4net :

Et voici quelques lignes de code pour réaliser notre premier log :

On utilise la méthode LogManager.GetLogger pour obtenir une instance d’un loggueur. Une petite ligne de configuration avec BasicConfigurator.Configure(); et il n’y a plus qu’à afficher un log avec Log.Error("Mon premier log avec log4net");.

Si vous démarrez l’application, vous pourrez voir que le log apparait sur la console :

 

Pourquoi la console ? Et bien cela vient du BasicConfigurator qui sert à configurer le minimum pour un log et qui utilise un loggeur qui écrit dans la console avec le format suivant : %-4timestamp [%thread] %-5level %logger %ndc - %message%newline.

Dans la sortie, on peut voir les différents éléments du format par défaut, un timestamp (38), un id de thread (1), le niveau de log (ERROR), le nom du logger ([Mon Logger], un contexte de diagnostic (null) ainsi que le message de log.

Vous pouvez bien sûr influer sur ces paramètres, le plus important à mon sens étant le niveau de log qui ici a été fixé à ERROR parce que nous avons utilisé la méthode Log.Error. Avec Log.Debug("Mon premier log avec log4net"); on aurait eu : 38 [1] DEBUG [Mon Logger] (null) - Mon premier log avec log4net. Il existe plusieurs niveaux de logs : DEBUG, INFO, WARN, ERROR, FATAL. A savoir qu’un niveau DEBUG est moins important qu’un niveau ERROR par exemple.

Je ne vais pas rentrer en détail dans toutes ces considérations car bons nombres d’articles l’ont déjà fait. Si vous voulez approfondir le sujet, n’hésitez pas à consulter la documentation officielle ou des tutoriels approfondis comme celui-ci.

Ce qui nous intéresse, c’est la possibilité de filtrer au runtime par rapport à un niveau de log. En mode développement, on pourra afficher des messages de debug et en production on pourra se concentrer sur les ERROR. Sachant que si l’on demande un niveau DEBUG par exemple, on aura tout ce qui est DEBUG ainsi que tout ce qui est plus important (INFO + WARN + ERROR + FATAL). Un autre élément intéressant c’est qu’on va pouvoir définir des appenders qui vont permet d’écrire ailleurs que sur la console, par exemple dans un fichier.

Et tout ceci se fait par de la configuration.

Voyons un exemple un peu plus réel que le BasicConfigurator utilisant la configuration XML :

 

Avec le fichier App.config suivant :

Ce qui est intéressant de voir ici c’est qu’on a défini deux appenders, un qui écrit sur la console et un autre qui écrit dans un fichier. Ils peuvent fonctionner en même temps.

(note : L’appender qui écrit dans un fichier est configuré pour changer de nom tous les jours et pour faire des ajouts au fichier à chaque log.)

Si je lance mon petit programme, je vais avoir des logs dans la console :

 

Ainsi que dans un fichier monlog_20160423.log :

2016-04-23 13:49:01,512 [DEBUG] Mon premier log avec log4net

2016-04-23 13:49:01,553 [ERROR] Une erreur s'est produite

Et maintenant, si on modifie seulement le app.config pour passer

en

 

on n'a plus que le log d’erreur qui apparaît… Et ça, c’est super pratique car du coup, on va pouvoir afficher exactement ce qu’on veut et quand on veut. On peut créer des loggers différents que l’on active également via de la config. De quoi pouvoir déboguer en détail des bouts de code particuliers.

Une pratique courante est de définir un logger par classe, que l’on peut activer indépendamment avec un niveau de log particulier. Par exemple dans la config suivante :

Je crée un logger pour la classe Program qui va mettre toutes les ERROR dans un fichier et un logger pour la classe Test qui va mettre tout ce qui est DEBUG et supérieur dans la console.

Ainsi, avec le code suivant :

J’aurai ma console qui va contenir :

 

 

Et mon fichier de texte qui aura seulement le message d’erreur :

2016-04-23 13:49:01,553 [ERROR] Error dans program

Et donc, à partir du moment où vous construisez bien vos logs, vous pourrez activer différents niveaux sur différentes classes directement au runtime. Pratique !

N’hésitez pas à approfondir le sujet car j’ai choisi de ne pas rentrer dans le détail, mais il y a plein de choses à voir comme les filters et les layouts. Et puis, il y a une myriade d’appender de toutes les sortes, j’y reviendrai dans un prochain billet.

Commentaires