grimboite/old/log4net.md

4.4 KiB

Title: Log4Net Status: draft Date: 2099-01-01

Log4Net est une librairie permettant d'écrire des informations semi-structurées sur plusieurs canaux de sortie, notamment des fichiers textes, bases de données, emails, ... Le code se content de dire `attrape l'info!", et la magie opère pour sortir cette donnée vers tout ce qui aura été défini dans la configuration. L'enregistrement est donc réparti en trois étapes principales:

  • Le code source, qui va envoyer l'information en fonction d'un évènement ou d'une condition particulière
  • Le niveau de sévérité (Debug, Info, Warning, Error, Fatal)
  • La configuration en elle-même.

C'est pratique, facile à mettre en place, flexible et évolutif. Tout se gère au travers d'un fichier de configuration à stocker (et à charger) depuis l'application; le code se contentant simplement de mettre le logger au courant des nouvelles données.

Grâce à Nuget, l'installation est simple : un petit coup de Install-Package log4net dans la console de Package-Manager, et on est bon. Il faut ensuite instancier un nouvel enregistreur grâce (par exemple...) à la ligne de code suivante :

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Ceci permet de déclarer une nouvelle instance, qui conservera le type de la classe appelante. Ajoutez également tout en haut de votre fichier l'information de chargement du fichier de conf', et vous aurez terminé la configuration basique du logger.

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]

Pas beseoin de redéfinir cette ligne à chaque fichier du projet; la valeur est définie au niveau de l'assembly. En fait, cela indique à Log4Net que la configuration est renseignée dans le fichier Log4Net.config (que j'ai placé à la racine du projet), et qui est de la forme suivante :

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <appender name="A1" type="log4net.Appender.ConsoleAppender">
	<layout type="log4net.Layout.PatternLayout">
	  <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
	</layout>
  </appender>
  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
	<file value="application.log" />
	<appendToFile value="true" />
	<maximumFileSize value="100KB" />
	<maxSizeRollBackups value="10" />
	<layout type="log4net.Layout.PatternLayout">
	  <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
	</layout>
  </appender>
  <root>
	<level value="DEBUG" />
	<appender-ref ref="A1" />
	<appender-ref ref="RollingFile"/>
  </root>
</log4net>

Comme je le disais ci-dessus, il suffit de définir une série d'appenders, qui sont autant de canaux d'écriture différents (l'un va écrire dans la console, l'autre va écrire dans un fichier texte avec un roulement, ...). La liste des différents types disponibles se trouve ici : http://logging.apache.org/log4net/release/sdk/log4net.Appender.html. Attention que ces canaux seront appelés et feront l'action associée à la réception d'un message immédiatement. Si on prend le SmtpAppender par exemple, il enverra un mail à l'adresse spécifiée pour chaque message reçu. Il ne remplacera donc pas l'envoi d'un rapport coloré et structuré, mais fera par contre parfaitement l'affaire pour informer une personne ou une équipe en cas de crash violent de l'application (ouioui, le gros try { ... } catch() {... } qui englobe l'application).

Un appender reprend une série de propriétés, définies en fonction de son type.

N'oubliez pas de copier le fichier lors de la compilation du projet.

Pour définir plusieurs enregistreurs différents dans un même projet, on peut définir deux loggers dans le fichier de configuration et les appeler de la manière suivante :

<logger name="FileLogger">
  <level value="ALL" />
  <appender-ref ref="LogFileAppender" />
</logger>

<logger name="EventLogger">
  <level value="ALL" />
  <appender-ref ref="EventLogAppender" />
</logger>
private static readonly ILog fileLogger = LogManager.GetLogger("FileLogger");
private static readonly ILog eventLogger = LogManager.GetLogger("EventLogger");