Каков наилучший способ записи записей журнала событий? - PullRequest
14 голосов
/ 24 ноября 2008

У меня недавно была проблема во время развертывания службы Windows. Четыре компьютера не вызвали проблем, но на пятом попытка запустить службу не удалась из-за исключения. Трассировка стека исключений записывается в журнал событий, поэтому я должен легко определить причину:

protected override void OnStart(string[] args)
{
    EventLog.WriteEntry("Starting service", EventLogEntryType.Information);

    try
    {
        //...
        base.OnStart(args);
    }
    catch (Exception ex)
    {
        EventLog.WriteEntry("Service can not start. Stack trace:" + ex.StackTrace, EventLogEntryType.Error);
        Stop();
        return;
    }

    EventLog.WriteEntry("Service started", EventLogEntryType.Information);           
}

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

Каковы рекомендации по записи в журнал событий, учитывая, что я не могу изменить конфигурацию журнала событий приложения?

Должен ли я всегда помещать EventLog.WriteEntry в блок try, если да, как мне обработать исключение (запись его в журнал событий, вероятно, плохая идея), должен ли я проверять состояние журнала событий в моем OnStart метод, или у вас есть лучшее предложение?

Ответы [ 6 ]

11 голосов
/ 24 ноября 2008

Использовать log4net

Преимущество использования log4net состоит в том, что вы можете проверять ведение журнала и управлять им с гораздо большей гибкостью, чем вы будете учитывать в своем коде.

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

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

Ключевой бит в документации log4net таков:

[log4net] - лучшая система регистрации ошибок и аварийного останова.

Под аварийным остановом мы подразумеваем, что log4net не будет генерировать непредвиденные исключения во время выполнения, что может привести к сбою приложения . Если по какой-либо причине log4net генерирует необработанное исключение (за исключением ArgumentException и ArgumentNullException, которые могут быть выброшены), пожалуйста, отправьте электронное письмо в список рассылки log4net-user@logging.apache.org. Неизученные исключения обрабатываются как серьезные ошибки, требующие немедленного внимания.

Более того, log4net не будет возвращаться к System.Console.Out или System.Console.Error, когда назначенный ему выходной поток не открыт, недоступен для записи или заполняется. Это позволяет избежать повреждения работающей в противном случае программы из-за переполнения терминала пользователя из-за сбоя регистрации. Однако log4net будет выводить одно сообщение в System.Console.Error и System.Diagnostics.Trace, указывающее, что ведение журнала невозможно.

(мой акцент)

Для большинства вещей есть библиотека, которая делает это лучше, чем вы. Лучше всего никогда не изобретать заново, log4net решает вход в систему .Net и сделает вашу жизнь проще.

4 голосов
/ 24 ноября 2008
System.Diagnostics.EventLog log = 
    new System.Diagnostics.EventLog("YourLogNameHere");
log.ModifyOverflowPolicy(
    System.Diagnostics.OverflowAction.OverwriteAsNeeded, 0);

Это должно исправить вашу проблему переполнения. Журнал событий, как правило, очень надежный, если он настроен правильно. При использовании журнала событий я использовал быстрый регистратор аварийного резервного копирования, который просто записывал в текстовый файл (запись занимает около 5 минут). Его никогда не называли.

3 голосов
/ 25 ноября 2008

Разве вы не можете просто использовать механизм регистрации событий по умолчанию, который уже предоставляется классом ServiceBase? Если ваша служба не запускается, она автоматически запишет запись в журнал событий с указанием (с помощью stacktrace).

Кроме того, что касается комментариев о log4net (или о любой другой наилучшей работе, такой как система регистрации), я думаю, что это действительно зависит от того, чего вы пытаетесь достичь.

В вашем примере использование log4net (или встроенной поддержки ведения журнала ServiceBase), скорее всего, нормально.

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

Итак, иногда вам нужно знать, когда попытка регистрации не удалась, и обрабатывать ее самостоятельно. Конечно, есть ограничения (проблема куриного яйца), и то, что вы делаете, очень специфично для конкретного приложения или сценария.

2 голосов
/ 24 ноября 2008

Узнайте, как использовать Блок приложения регистрации .

Блок приложения ведения журнала Enterprise Library упрощает реализацию общих функций ведения журнала. Разработчики могут использовать Блок регистрации для записи информации в различные места:

  • Журнал событий
  • Сообщение электронной почты
  • База данных
  • Очередь сообщений
  • Текстовый файл
  • Событие WMI
  • Пользовательские местоположения с использованием точек расширения блока приложения
2 голосов
/ 24 ноября 2008

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

Но зачем ты сам пишешь свой код входа? Используйте фреймворк, такой как NLog или Log4Net! Они также поглощают исключения, как я только что сказал, но вы можете перенаправить вывод журнала в другое место (файл, ящик сообщений и т. Д.), Просто изменив конфигурацию. Это значительно облегчает решение подобных проблем.

0 голосов
/ 04 июня 2009

Давайте сделаем шаг назад:

Журнал системных событий предназначен для предупреждения системного администратора о том, что с системой что-то произошло. Вы должны разрешить запуск службы сбой. Это отобразится в системном журнале ошибок с указанным источником «Диспетчер управления службами». Это означает, что администратор системы будет знать о сбое.

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

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

...