Каков наилучший способ записи записей журнала событий?

У меня недавно возникла проблема во время развертывания службы 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 или у вас есть лучшее предложение?

Ответы

Ответ 1

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

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

Ответ 2

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

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

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

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

Ключевым битом в документации log4net является следующее:

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

По завершении остановки мы подразумеваем, что log4net не будет генерировать неожиданные исключения во время выполнения, что может привести к сбою вашего приложения. Если по какой-либо причине log4net выбрасывает неперехваченное исключение (за исключением ArgumentException и ArgumentNullException, которое может быть выбрано), отправьте электронное письмо в список рассылки [email protected] Необлученные исключения обрабатываются как серьезные ошибки, требующие немедленного внимания.

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

(мой акцент)

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

Ответ 3

System.Diagnostics.EventLog log = 
    new System.Diagnostics.EventLog("YourLogNameHere");
log.ModifyOverflowPolicy(
    System.Diagnostics.OverflowAction.OverwriteAsNeeded, 0);

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

Ответ 4

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

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

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

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

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

Ответ 5

Посмотрите на использование Заблокировать блок приложений.

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

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

Ответ 6

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

Журнал системных событий должен предупредить системного администратора о том, что в системе возникла проблема с чем-либо. Вы должны разрешить запуск службы сбой. Это будет отображаться в журнале системных ошибок с сообщенным источником "Service Control Manager". Это означает, что администратор sys будет знать об ошибке.

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

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