Как использовать BufferingForwardingAppender вместе с приложением EventLog для получения уведомлений по электронной почте? - PullRequest
1 голос
/ 26 октября 2011

Мне нужна идея для реализации следующего требования в веб-приложении.

Я использую log4net в пользовательской dll для регистрации ошибок.Я завершил реализацию log4net и она работает нормально. [Ошибки aspx регистрируются в EventLog, а ошибки asp регистрируются в FileAppender]. Все методы loggerError () находятся в пользовательских dll.

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

Мои идеи,

1. Установите таймер и переменную подсчета для отслеживания количества попаданий.

2.После каждого попадания проверяйте количество попаданий и секунд.

3.Если оно превысит пороговый лимит. Затем вызовите электронное письмо ...

Не уверен, как это будет работать или есть ли другой способ добиться этого.

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 28 октября 2011

Я бы предложил написать свой собственный Appender для размещения этой логики. Appender может быть использован в качестве оболочки для другого Appender (может быть, SmtpAppender?). ForwardingAppender выглядит как хороший пример «упаковщика» Appender. При поступлении каждого сообщения журнала применяйте логику времени и серьезности. Если ваши критерии удовлетворены, перешлите сообщение «завернутому» заявителю.

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

Этот Appender можно настроить с помощью стандартного механизма конфигурации log4net (app.config, отдельная конфигурация и т. Д.), Чтобы можно было настраивать временной интервал, уровень ошибок, количество ошибок.

Вот идея, как что-то подобное может быть реализовано как Appender:

public class MultiThresholdNotifyingAppender : AppenderSkeleton
{
  private Queue<LoggingEvent> loggingEventQueue = new Queue<LoggingEvent>();

  private DateTime windowStart;

  public Level LevelThreshold { get; set; }
  public TimeSpan WindowLength { get; set; }
  public int HitThreshold { get; set; }

  public void Append(LoggingEvent loggingEvent)
  {
    if (loggingEvent.Level < LevelThreshold) 
    {
      if (loggingEventQueue.Count == 0) return;

      if (loggingEvent.TimeStamp - windowStart) >= WindowLength)
      {
        //Error level is less than threshold and the time window has elapsed.  Remove any queued LoggingEvents
        //until all LoggingEvents in the queue fall within the time window.
        while (loggingEventQueue.Count > 0 && loggingEventQueue.Peek().TimeStamp - windowStart >= WindowLength)
        {
          loggingEventQueue.Dequeue();
        }

        windowStart = loggingEventQueue.Peek().TimeStamp;

        return;
      }
    }

    //If we got here, then the Error level is >= the threshold.  We want to save the LoggingEvent and we MIGHT
    //want to notify the administrator if the other criteria are met (number of errors within time window).
    loggingEventQueue.Enqueue(loggingEvent);

    //If this is the first error in the queue, start the time window.
    if (loggingEventQueue.Count == 1) windowStart = loggingEvent.TimeStamp;

    //Too few messages to qualify for notification.
    if (loggingEventQueue.Count < HitThreshold - 1) return; 

    //Now we're talking!  A lot of error messages in a short period of time.    
    if (loggingEvent.TimeStamp - windowStart >= WindowLength)
    {
      //Build a notification message for the administrator by concatenating the "rendered" version of each LoggingEvent.
      string message = string.Join(Enviroment.NewLine, loggingEventQueue.Select(le => le.RenderedMessage));
      SendTheMessage(message);
    }

    //After sending the message, clear the LoggingEvents and reset the time window.
    loggingEventQueue.Clear();      
    windowStart = loggingEvent.TimeStamp;
  }

  public void Append(LoggingEvent[] loggingEvents)
  {
    foreach (var le in loggingEvents)
    {
      Append(le);
    }
  }
}

Идея состоит в том, чтобы настроить ваши пороговые значения (возможно, вместе с методом уведомления) в приложении. Сконфигурируйте свои регистраторы так, чтобы они отправляли свои сообщения этому приложению, в дополнение к любым другим добавителям, которым вы хотите их отправлять (EventLog, File и т. Д.). По мере прохождения каждого сообщения журнала этот аппендер может проверить его в контексте настроенных пороговых значений и при необходимости отправить уведомление.

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

Обратите внимание, что этот код не был скомпилирован и не был протестирован.

См. Эту ссылку для некоторых примеров пользовательских приложений в репозитории log4net:

http://svn.apache.org/viewvc/logging/log4net/trunk/examples/net/2.0/Appenders/

0 голосов
/ 26 октября 2011

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

...