Устранить дублирование входа в log4net - PullRequest
61 голосов
/ 16 марта 2009

У меня есть программа, которая делает много вызовов log4net к регистраторам "myprogram". Он также вызывает другой код, который делает log4net-вызовы другим регистраторам. Я хочу захватить все журналы выше, чем INFO для "myprogram" и все журналы выше, чем WARN для всего остального. Таким образом, я получаю сообщения о незавершенном производстве, относящиеся к задаче, над которой я работаю, но я все еще получаю уведомления о потенциально плохих вещах, происходящих в поддерживающем коде. Я хочу, чтобы это было отправлено на консоль и в файл журнала.

У меня есть следующая конфигурация log4net:

<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>

Для меня это имеет смысл: log> WARN для всего и> INFO для конкретного регистратора myprogram.

Проблема в том, что я получаю сообщения INFO, занесенные в журнал дважды как в консоли, так и в файле журнала. Это происходит только в том случае, если у меня заполнены оба элемента <root> и <logger>; если я удаляю любой из них, то оставшийся работает так, как я ожидаю.

Я мог бы понять, получал ли я двойной журнал записей WARN (так как myprogram совпадает как с «root», так и с «myprogram»), но это происходит в INFO, даже если для ROOT (предположительно) установлено значение WARN.

Я что-то здесь не так делаю, или это ошибка / неоднозначность в log4net?

Ответы [ 2 ]

77 голосов
/ 19 марта 2009

Вы дублируетесь, потому что вы говорите, чтобы записывать сообщения дважды. Я бы не рекомендовал использовать здесь аддитивность, поскольку у вас могут возникнуть некоторые побочные эффекты, просто удалите ненужную конфигурацию:

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

Вам не нужно указывать appender-ref в логгере myprogram, поскольку он унаследует их от корневого логгера; если вы укажете их еще раз, он будет регистрироваться дважды.

68 голосов
/ 16 марта 2009

Попробуйте с этим изменением, установив аддитивность в 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>
...