Как устранить дублирование входа в log4net?

У меня есть программа, которая делает много вызовов 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?

16.03.2009 17:02:22
2 ОТВЕТА
РЕШЕНИЕ

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

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

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

78
1.10.2013 12:15:24
Это хорошо сработало для меня, когда я столкнулся с той же проблемой. Это также позволяет избежать проблемы аддитивности
Jeffrey Cameron 25.02.2010 20:15:31
@ Джеффри, ты знаешь, в чем проблемы с использованием аддитивности? Мне не удалось найти ничего задокументированного, о чем Google знает.
Tinister 7.09.2010 15:07:54
@Tinister проблема аддитивности состоит в том, чтобы установить additivity = false (как в вопросе выше), иначе ваш вывод будет дублирован.
Jeffrey Cameron 8.09.2010 15:08:39
@Джеффри Да, но, насколько я могу судить, использование «additivity = false» также является приемлемым решением проблемы ОП. Джем в своем ответе упоминает, что использование аддитивности может привести к «побочным эффектам»; однако учетная запись Jam, похоже, удалена или что-то в этом роде, поэтому я предполагаю, что он не сможет ответить. Ваш первый комментарий, кажется, указывает на то, что вы также знаете об этих «побочных эффектах», поэтому я решил спросить.
Tinister 8.09.2010 19:25:55
программно вы можете сделать это следующим образом: ((log4net.Repository.Hierarchy.Logger) log.Logger) .Additivity = false;
FrankyHollywood 14.03.2014 14:39:28

Попробуйте с этим изменением, установив аддитивность в 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>
69
1.10.2013 12:20:15
Это хороший способ убедиться, что все сообщения, зарегистрированные в журнале «myprogram», не попадают в корневой журнал.
Llyle 25.02.2011 11:00:01
Работает для меня; Я хочу, чтобы все записи журнала из определенного класса передавались другому приложению, чем другие классы.
David Keaveny 5.08.2011 05:51:48
@jaminator: На этот вопрос сложно ответить в комментариях, и я не совсем уверен, что вы спрашиваете. Вы спрашиваете, почему вы можете настроить что-то подобное?
Eddie 11.11.2014 06:12:46