вторник, 10 июня 2008 г.

Enterprise logging system. Part 4. Facade.

Ура, я проснулся от летаргического сна.

Предлагаю сразу взяться, например за дело.

Итак вперед.

В первой части я кратко описал требования к системе и архитектуру. В этой части я расскажу как эти требования были реализованы.

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

Как вы помните в системе предусмотрено 5 уровней логирования:

  • Trace;
  • Info;
  • Warn;
  • Error;
  • Status;
, соответственно и интерфейс фасада определен количеством и именами этих уровней.

Что же скрывают за собой эти методы? Давайте рассмотрим работу LogBook по шагам.

При первом обращении к фасаду, прежде чем выполнить метод, clr будет вызван инициализатор типа. В этом статическом конструкторе LogBook пытается сконифигурировать себя. Этот процесс он делегирует статическому классу-загрузчику Bootstrapper, который сначала пытается получить настройки для текущего клиента от сервиса, а затем производит инициаллизацию хозяина (LogBook) из локального конфига (если вдруг в момент старта сервис будет недоступен, то он сможет поднять LogBook по локальным настройкам, которые сохраняются в конфигурационном файле клиента, а если не сможет, то кинет исключение).

Далее, в зависимости от уровня логирования LogBook создаст соответствующее сообщение и отправит его на валидацию в список подключенных фильтров (важно сделать это до окончательного заполнения сообщения, чтобы не тратить память и время зря, если оно не проходит по условиям фильтров). После этого, дабы не блокировать клиента, фасад LogBook делегирует отправку сообщения RequestManager'у, который в асинхронном режиме постарается отправить его куда следует. Куда следует - это сюда: первым делом он сохранит его в локальной стратегии, а затем попытается отправить его сервису. В случае неудачной попытки, он увеличит счетчик неудачных попыток, проверит условия устаревания сообщения (по времени хранения и количеству неудачных попыток) и сохранит обратно сообщение в локальную очередь, если оно все еще валидно. За подключением сервиса следит ConnectionMonitor, который при изменении статуса подключения генерирует событие, перехватываемое RequestManager'ом.

Все методы перегружены одним дополнительным параметром - контекстом, о котором я писал здесь. Если вызывается метод без котекста, или вместо него передается null, то в качестве контекста будет автоматически подставлен LogContext.Current.

Вот в очень сжатом виде механизм работы моего enterprise LogBook'а.

Подумываю завести проект на CodePlex. Займусь этим на досуге.

Удачи!

Комментариев нет: