Как я могу условно подавить исключения приложения, записанные в журнал событий? - PullRequest
2 голосов
/ 30 октября 2008

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

Но, скажем, одно из устройств не работает в течение дня или более. Я заполняю журнал исключений одним и тем же исключением каждые 15 секунд. Существует ли стандартный способ предотвращения записи исключения в журнал событий, если создаваемое исключение не изменилось за последние x часов?

Ответы [ 5 ]

3 голосов
/ 30 октября 2008

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

Впервые я прочитал об этом в книге Майкла Т. Найгарда «Освободи его! Проектирование и развертывание готового программного обеспечения для производства», из Pragmatic Press, стр. 104–107.

Идея автоматического выключателя заключается в том, что он находится на пути соединения между системами, пропуская соединения, наблюдая за «условием обрыва». Например, он может сработать только в случае сбоя всех пяти подключений подряд.

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

Быстрый гугл нашел пост Тима Росса , который хорошо читается и более подробно.

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

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

1 голос
/ 30 октября 2008

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

Увеличение продолжительности между попытками подключения, вероятно, решит вашу проблему. Например. newTimeout = n * atomicTimeout, где n - номер обслуживающего персонала.

1 голос
/ 30 октября 2008

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

Если честно, описанный выше рабочий процесс действительно не решает вашу проблему. На вашем месте я бы изменил рабочий процесс. Вместо того, чтобы опрашивать серверы, почему бы не сделать это наоборот? Когда устройство подключено к сетевому компьютеру, ваша клиентская служба отправляет сообщение на сервер, чтобы сервер знал, что устройство подключено и работает.

Надеюсь, это поможет ...

RWendi

0 голосов
/ 17 июля 2010

Шаблоны выключателей - это хорошая идея, скажем,

ознакомьтесь с некоторыми вариантами реализации PHP, но применимы к любому языку

http://artur.ejsmont.org/blog/PHP-Circuit-Breaker-initial-Zend-Framework-proposal

0 голосов
/ 12 декабря 2008

А как же ...

 int count = 0;
 while (true)
 {
      try
      {
           AttemptStuff()
      }
      catch (Exception ex)
      {
           if(count < 10)
           {
                EventLog.WriteEntry("my service", ex.ToString(), EventLogEntryType.Error);
                count++;
           }
      }
 }
...