Mise en place de log4net pour la journalisation dans les projets .NET

La journalisation est un aspect crucial des applications .NET pour le suivi des erreurs et des événements. log4net offre une solution flexible pour gérer les logs. Ce guide détaille son intégration, en modifiant les exemples de code pour plus de clarté et de personnalisation.

Configuration initiale

Pour séparer la configuration, créez un fichier log4net.xml avec le contenu suivant. Cet exemple inclut des appenders pour des logs journaliers et une sortie en base de données, avec des chemins et patterns ajustés.

<?xml version="1.0" encoding="UTF-8"?>
<log4net debug="false">
  <!-- Appender pour logs quotidiens -->
  <appender name="DailyRollingAppender" type="log4net.Appender.RollingFileAppender">
    <param name="AppendToFile" value="true" />
    <param name="LockingModel" value="log4net.Appender.FileAppender.MinimalLock" />
    <param name="StaticLogFileName" value="false" />
    <param name="File" value="C:\Journalisation\AppliLogs\" />
    <param name="DatePattern" value="dd-MM-yyyy.log" />
    <param name="RollingStyle" value="Date" />
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="Horodatage:%d %nSévérité:%level %nClasse:%c%nFichier:%F Ligne:%L%nMessage:%m%n---" />
    </layout>
  </appender>

  <!-- Appender pour enregistrement en base de données -->
  <appender name="DatabaseAppender" type="log4net.Appender.AdoNetAppender">
    <bufferSize value="50" />
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <connectionString value="Server=MONSERVEUR;Database=LogsDB;Integrated Security=false;User Id=admin;Password=secret;" />
    <commandText value="INSERT INTO Journal ([DateHeure],[Niveau],[Classe],[Message],[Exception]) VALUES (@date, @niveau, @classe, @message, @exception)" />
    <parameter>
      <parameterName value="@date" />
      <dbType value="DateTime" />
      <layout type="log4net.Layout.RawTimeStampLayout" />
    </parameter>
    <parameter>
      <parameterName value="@niveau" />
      <dbType value="String" />
      <size value="100" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%level" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@classe" />
      <dbType value="String" />
      <size value="200" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%logger" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@message" />
      <dbType value="String" />
      <size value="4000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%message" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@exception" />
      <dbType value="String" />
      <size value="2000" />
      <layout type="log4net.Layout.ExceptionLayout" />
    </parameter>
  </appender>

  <root>
    <level value="WARN" />
    <appender-ref ref="DailyRollingAppender" />
    <!-- Décommentez pour activer l'enregistrement en base -->
    <!--<appender-ref ref="DatabaseAppender" />-->
  </root>
</log4net>

Les niveaux de log (comme WARN) et les chemins sont configurables selon les besoins. Le nœud root détermine l'appender actif.

Intégration dans le projet

Pour les applications web, chargez la configuration au démarrage dans Global.asax.cs. Utilisez une méthode modifiée pour plus de flexibilité.

protected void Application_Start(object sender, EventArgs e)
{
    var configFilePath = Server.MapPath("~/Config/log4net.xml");
    log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(configFilePath));
}

Dans les applications de bureau, appelez cette méthode dans le point d'entrée principal, par exemple dans Program.cs.

Classe utilitaire pour la journalisation

Créez une classe d'aide pour centraliser l'accès aux logs. Voici une version refactorisée avec une approche différente.

public static class LoggerFactory
{
    private static readonly Dictionary<string, ILog> _loggers = new Dictionary<string, ILog>();

    public static ILog ObtainLogger(string configPath = null)
    {
        if (!string.IsNullOrEmpty(configPath))
        {
            log4net.Config.XmlConfigurator.Configure(new FileInfo(configPath));
        }

        var callerType = new StackFrame(1).GetMethod().DeclaringType;
        string loggerKey = callerType.FullName;

        if (!_loggers.ContainsKey(loggerKey))
        {
            _loggers[loggerKey] = LogManager.GetLogger(callerType);
        }

        return _loggers[loggerKey];
    }
}

Cette classe gère les instances de logger de manière dynamique et supporte la configuration personnalisée.

Utilisation dans l'application

Pour enregistrer des messages, utilisez la classe utilitaire. Voici des exemples.

// Avec configuration par défaut
var log = LoggerFactory.ObtainLogger();
log.Error("Une erreur s'est produite lors du traitement");

// Avec chemin de configuration spécifique
var customLog = LoggerFactory.ObtainLogger("C:\Custom\log4net.xml");
customLog.Info("Opération terminée avec succès");

Résolution des problèmes courants

Un problème fréquent est l'absence de logs due à une configuration non chargée. Vérifiez que la configuration est bien initialisée, par exemple en ajoutant log4net.Config.XmlConfigurator.Configure(); au démarrage pour les applications de bureau.

Si des logs INFO apparaissent en excès, ajustez le niveau dans la section root de la configuration, par exemple en passant à WARN pour réduire la verbosité.

Assurez-vous également que le fichier de configuration est correctement référencé et que les chemins d'accès sont valides dans l'environnement cible.

Étiquettes: log4net NET journalisation CSharp configuration-XML

Publié le 13 juin à 18h40