web-dev-qa-db-fra.com

Manière correcte d’utiliser log4net (nommer les enregistreurs)

Il y a deux façons de configurer et d'utiliser log4net. Le premier est quand je peux configurer mon propre appender et son logger associé:

<!-- language: xml -->

<appender name="myLogAppender" type="log4net.Appender.RollingFileAppender" >
    <file value="Logs\myLog.log" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %level - %message%n" />
    </layout>
</appender>

<logger name="myLog">
    <level value="All"></level>
    <appender-ref ref="myLogAppender" />
</logger>

Et puis, quand je veux écrire quelque chose dans le journal, je peux faire ce qui suit:

ILog log = LogManager.GetLogger("myLog");
log.Info("message");

Une autre façon de l'utiliser consiste à configurer root pour qu'il soit aussi détaillé que je le souhaite:

<!-- language: xml -->

<root>
    <level value="Error" />
    <appender-ref ref="myLogAppender" />
</root>

Et dans ce cas, je peux enregistrer des messages comme ceci:

ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");

La seconde approche présente l’avantage de pouvoir activer ou désactiver certains messages à la volée. Mais le problème est que je développe dans EPiServer CMS et qu'il possède son propre système de journalisation qui utilise log4net. Si j'active la journalisation des informations au niveau racine, de nombreux journaux système seront écrits. 

Comment utilisez-vous log4net? Chaque partie d'un système écrit dans son propre enregistreur, ou tout est écrit dans l'enregistreur par défaut, et la configuration décide quoi faire ensuite? 

77
Sly

En ce qui concerne la manière dont vous enregistrez les messages dans le code, je choisirais la deuxième approche:

ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");

Les messages envoyés au journal ci-dessus seront "nommés" en utilisant le type entièrement qualifié Bar, par exemple.

MyNamespace.Foo.Bar [INFO] message

L’avantage de cette approche est qu’il s’agit du standard de facto pour l’organisation de la journalisation. Il vous permet également de filtrer vos messages de journalisation par espace de noms. Par exemple, vous pouvez spécifier que vous souhaitez consigner le message de niveau INFO, mais augmenter le niveau de consignation pour Bar spécifiquement à DEBUG:

<log4net>
    <!-- appenders go here -->
    <root>
        <level value="INFO" />
        <appender-ref ref="myLogAppender" />
    </root>

    <logger name="MyNamespace.Foo.Bar">
        <level value="DEBUG" />
    </logger>
</log4net>

La possibilité de filtrer votre journalisation via name est une fonctionnalité puissante de log4net. Si vous vous connectez simplement tous vos messages à "myLog", vous perdez beaucoup de ce pouvoir!

En ce qui concerne le CMS EPiServer, vous devriez pouvoir utiliser l'approche ci-dessus pour spécifier un niveau de journalisation différent pour le CMS et votre propre code.

Pour en savoir plus, voici un article de codeproject que j'ai écrit sur la journalisation:

92
ColinE

Ma réponse pourrait arriver en retard, mais je pense que cela peut aider les débutants. Vous ne verrez pas les journaux exécutés à moins que les modifications ne soient apportées comme ci-dessous.

2 Les fichiers doivent être modifiés lorsque vous implémentez Log4net.


  1. Ajouter une référence de log4net.dll dans le projet.
  2. app.config
  3. Class fichier dans lequel vous allez implémenter les journaux.

Dans [app.config]:

Premièrement, sous «configSections», vous devez ajouter un morceau de code ci-dessous;

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

Ensuite, sous le bloc 'configuration', vous devez écrire un morceau de code (ce morceau de code est personnalisé selon mes besoins, mais il fonctionne à merveille)

<log4net debug="true">
    <logger name="log">
      <level value="All"></level>
      <appender-ref ref="RollingLogFileAppender" />
    </logger>

    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="log.txt" />
      <appendToFile value="true" />
      <rollingStyle value="Composite" />
      <maxSizeRollBackups value="1" />
      <maximumFileSize value="1MB" />
      <staticLogFileName value="true" />

      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %C.%M [%line] %-5level - %message %newline %exception %newline" />
      </layout>
    </appender>
</log4net>

Inside Classe d'appel:

Dans la classe où vous allez utiliser ce log4net, vous devez déclarer un morceau de code ci-dessous.

 ILog log = LogManager.GetLogger("log");

Maintenant, vous êtes prêt journal des appels où vous voulez dans cette même classe. Vous trouverez ci-dessous l’une des méthodes que vous pouvez appeler lorsque vous effectuez des opérations.

log.Error("message");
8
Ankur Soni

Au lieu de nommer ma classe appelante, j'ai commencé à utiliser les éléments suivants:

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

De cette manière, je peux utiliser la même ligne de code dans chaque classe qui utilise log4net sans avoir à me souvenir de changer de code lorsque je copie/colle . Sinon, je pourrais créer une classe de journalisation et faire en sorte que toutes les autres classes héritent mon cours de journalisation.

4
Agent RhoShambo

L'inconvénient de la seconde approche est un grand référentiel avec des enregistreurs créés. Ces enregistreurs font la même chose si la racine est définie et que les enregistreurs de classe ne sont pas définis. Le scénario standard sur le système de production utilise quelques enregistreurs dédiés à un groupe de classes. Désolé pour mon anglais. 

0
user1785960