web-dev-qa-db-fra.com

Éliminer la journalisation en double dans log4net

J'ai un programme qui fait de nombreux appels log4net aux enregistreurs "myprogram". Il appelle également un autre code qui effectue des appels log4net vers d'autres enregistreurs. Je veux capturer tous les journaux supérieurs à INFO pour "monprogramme" et tous les journaux supérieurs à WARN pour tout le reste. De cette façon, je reçois les messages de travail en cours spécifiques à la tâche sur laquelle je travaille, mais je suis toujours informé des choses potentiellement mauvaises qui se produisent dans le code de support. Je veux que cela soit envoyé à la fois à la console et à un fichier journal.

J'ai la configuration log4net suivante:

<log4net>
    <root>
        <level value="WARN" />
        <appender-ref ref="Console" />
        <appender-ref ref="LogFile" />
    </root>
    <logger name="myprogram">
        <level value="INFO" />
        <appender-ref ref="Console" />
        <appender-ref ref="LogFile" />
    </logger>
    <appender name="Console" type="log4net.Appender.ConsoleAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%message%newline" />
        </layout>
        <threshold value="INFO" />
    </appender>
    <appender name="LogFile" type="log4net.Appender.RollingFileAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="- %utcdate %level %logger %ndc %thread %message%newline" />
        </layout>
        <appendToFile value="false" />
        <staticLogFileName value="true" />
        <rollingStyle value="Once" />
        <file value="mylogfile" />
        <immediateFlush value="true" />
        <threshold value="INFO" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    </appender>
</log4net>

Cela me semble parfaitement logique: log> WARN pour tout et> INFO pour le logger "myprogram" spécifique.

Le problème est que je reçois des messages INFO enregistrés deux fois sur la console et le fichier journal. Cela ne se produit que si j'ai à la fois le <root> et <logger> éléments remplis cependant; si je supprime l'un ou l'autre, alors le reste fonctionne comme prévu.

Je pouvais comprendre si j'obtenais une double journalisation des entrées WARN (car mon programme correspond à la fois à "root" et "mon programme"), mais cela se produit à INFO même si ROOT est (vraisemblablement) réglé sur WARN.

Suis-je en train de faire quelque chose de mal ici, ou est-ce un bug/ambiguïté log4net?

61
Craig Walker

Vous obtenez dupliqué parce que vous lui dites d'enregistrer les messages deux fois. Je ne recommanderais pas d'utiliser l'additivité ici car vous pourriez rencontrer des effets secondaires, supprimez simplement la configuration inutile:

<root>
    <level value="WARN" />
    <appender-ref ref="Console" />
    <appender-ref ref="LogFile" />
</root>
<logger name="myprogram">
    <level value="INFO" />
</logger>

Vous n'avez pas besoin d'indiquer l'appender-ref dans le myprogram de l'enregistreur car il les héritera de l'enregistreur racine; si vous les spécifiez à nouveau, il se connectera deux fois.

78
Jam

Essayez avec ce changement, définissant l'additivité sur false.

<root>
    <level value="WARN" />
    <appender-ref ref="Console" />
    <appender-ref ref="LogFile" />
</root>
<logger name="myprogram" additivity="false">
    <level value="INFO" />
    <appender-ref ref="Console" />
    <appender-ref ref="LogFile" />
</logger>
68
Eddie