2009-03-16 6 views
58

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

У меня есть следующие 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> 

Это имеет смысл для меня: журнал> WARN для всего и> INFO для конкретного "MyProgram" регистратор.

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

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

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

ответ

72

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

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

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

+0

Это работало хорошо для меня, когда я столкнулся с той же проблемой. Это позволяет избежать проблемы с аддитивностью, а также –

+1

Это правильный ответ. Регистраторы наследуют приложения от root. Благодаря! –

+1

@ Джеффри, вы знаете, какие проблемы с использованием аддитивности? Мне не удалось найти что-либо задокументированное, о котором знает Google. – Tinister

67

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

Это сделало это; спасибо пакет. –

+2

Это хороший способ гарантировать, что все сообщения, записанные в журнал «myprogram», не попадают в корневой журнал. – Llyle

+0

Спасибо, что решил проблему, которую я искал в Google. – Kugel

Смежные вопросы