Приложение Log4Net smtp отправляет электронное письмо только при ошибке с полным журналом (отладка, информация и ошибка). Только когда приложение закончится

Я пытаюсь настроить приложение smtp в имеющемся у меня файле log4net.config. Проблема в том, что я просмотрел весь Интернет и не могу найти, как отправить электронное письмо, когда возникает ошибка со всей другой включенной информацией журнала, такой как информация, отладка, ошибка, фатальный. Только когда приложение заканчивается (НЕ каждый раз, когда возникает ОШИБКА).

Поэтому я хочу получать это письмо только тогда, когда: приложение завершается + со всей информацией журнала (DEBUG, INFO, ERROR, FATAL) + только если произошла ОШИБКА.

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

Спасибо.


person Pasha Immortals    schedule 05.05.2011    source источник


Ответы (3)


SmtpAppender не может этого сделать самостоятельно. Итак, я создал еще один аппендер для аппендера типа MemoryAppender. Я установил порог для этого регистратора, чтобы включать только сообщения, которые должны запускать SmtpAppender, например Error. Мы используем это, чтобы позже определить, хотим ли мы отправить электронное письмо с большим количеством зарегистрированных уровней.

На самом деле мы не заботимся о сообщениях в _5 _ - мы просто заботимся о том, чтобы они содержали сообщения в конце. Сообщения, которые мы получаем по электронной почте, на самом деле приходят от SmtpAppender.

В конце своей программы я проверяю приложение памяти, чтобы увидеть, содержит ли его GetEvents () какие-либо события. В таком случае я не останавливаю нормальную работу SmtpAppender.

Конфиги Log4Net для обоих приложений:

<appender name="ErrorHolder" type="log4net.Appender.MemoryAppender" >
    <onlyFixPartialEventData value="true" />
    <!-- if *any* message is logged with this level, the email appender will 
         be used with its own level -->
    <threshold value="ERROR" />
</appender>

<appender name="Email" type="log4net.Appender.SmtpAppender">    
    <!-- the level you want to see in the email IF ErrorHolder finds anything -->
    <threshold value="INFO"/> 
    <bufferSize value="512" />
    <lossy value="false" /> <!-- important! -->   
    <to value="[email protected]" />
    <from value="[email protected]" />
    <subject value="ERROR: subject" />
    <smtpHost value="smtpserver" />    
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
    </layout>    
</appender>

<root>
  <level value="ALL" />
  <appender-ref ref="ErrorHolder" />
  <appender-ref ref="Email" />
</root>

В конце приложения запустите это, чтобы отключить SmtpAppender, если приложение ErrorHolder пусто:

// trigger loggers if errors occurred:
var memoryAppender = ((Hierarchy)LogManager.GetRepository())
    .Root.Appenders.OfType<MemoryAppender>().FirstOrDefault();

if (memoryAppender != null && memoryAppender.GetEvents().Length == 0)
{
    // there was no error so don't email anything
    var smtpAppender = ((Hierarchy)LogManager.GetRepository())
        .Root.Appenders.OfType<SmtpAppender>().FirstOrDefault();

    if (smtpAppender != null)
    {
        smtpAppender.Threshold = Level.Off;
        smtpAppender.ActivateOptions();
    }
}
person Pasha Immortals    schedule 06.05.2011
comment
Это кажется довольно сложной версией того, что я предложил в своем решении. - person IAmTimCorey; 07.05.2011
comment
Правильно, вы были правы, я решил проверить в конце, это правда. Но когда вы ищете, как заглянуть внутрь приложений для событий определенного уровня (находясь здесь). Я не мог найти ничего в отношении каких-либо приложений, где я мог бы получить события внутри них. Так что единственное, что я смог найти, это MemoryAppender, и я использовал его. - person Pasha Immortals; 11.05.2011
comment
Вот сообщение об отслеживании проблем log4net: stackoverflow .com / questions / 756125 / - person Nickz; 22.12.2011

Это похоже на проблему конфигурации приложения, а не на проблему конфигурации log4net. Я бы предложил добавить метод в конце вашего приложения, который отправит вам файл журнала по электронной почте, если обнаружит, что в нем есть ошибка. Вы можете обнаружить эту ошибку, переключив глобальную переменную с false на true в каждом месте, где вы регистрируете ошибки, или вы можете дождаться завершения вашего приложения, а затем прочитать файл журнала, чтобы увидеть, содержит ли он ошибки. Первый метод будет быстрее при завершении работы, но это означает изменение вашего кода в нескольких местах. Последний позволит вам просто добавить один метод, но для большого файла это может занять больше времени.

Третий вариант - отправлять ошибки во второй файл журнала (так что они идут в двух местах) с помощью log4net. Затем, когда ваше приложение закрывается и вы проверяете, следует ли отправить журнал по электронной почте, просто проверьте наличие файла, содержащего только ошибки. Если он существует, удалите его (чтобы его не было в следующий раз) и отправьте полный журнал по электронной почте.

person IAmTimCorey    schedule 05.05.2011
comment
Как вы проверяете в конце программы, нет ли ошибок, что вы ищете? в logger, appender ?, какие методы и поля использовались. Не могли бы вы вставить код? - person Pasha Immortals; 06.05.2011
comment
Я обнаружил, что вы можете столкнуться с проблемами ввода-вывода файла при попытке отправить фактический файл журнала (он открыт другим процессом). Даже если вы очистите fileAppender, снимете блокировку и скопируете его, я все равно столкнулся с проблемами ввода-вывода, если log4Net в то время скатывал файлы журнала. - person John J Smith; 14.06.2013

измените порог на Ошибка. Также журнал 4net отправляет электронное письмо только тогда, когда приложение закрывается. Вы можете отправить его раньше. но сначала вам нужно скопировать его (потому что файл org все еще используется), а затем вы можете отправить копию по электронной почте.

person Community    schedule 18.02.2016