Co łączy te trzy, z pozoru zupełnie ze sobą nie związane, pojęcia? Wszystkie trzy zastosowane razem pozwalają uzyskać bardzo dobry wgląd w to, co dzieje się z systemem podczas jego pracy. Za chwilę pokażę jak.

NetMX (jeśli ktoś jeszcze nie wie :-) ) jest stworzonym przeze mnie portem JMX dla .NET. Jego główną zaletą jest możliwość udostępniania informacji o stanie aplikacji zdalnie, w formie tzw. MBean-ów — obiektów zarządzalnych. Każdy MBean posiada zestaw swoich atrybutów oraz operacji. Te pierwsze pozwalają dowiedzieć się czegoś na temat jego stanu, te drugie zaś — zmodyfikować zachowanie systemu. Oczywiście zdalnie.

Domain events to swego rodzaju wzorzec, opisany przez Udiego Dahana, a wielokrotnie cytowany przeze mnie na tym blogu. Tak naprawdę, to chyba najczęściej wspominana przeze mnie koncepcja:-) Idea zdarzeń domenowych  jest bardzo prosta: obiekty domenowe mogą emitować zdarzenia, aby poinformować świat zewnętrzny o zmianie swojego stanu.

Spróbujmy to teraz połączyć. Obiekty domenowe emitują zdarzenia, kiedy chcą poinformować świat o czymś interesującym. Możemy przechwycić te zdarzenia i wyświetlić w formie liczników w ramach MBean-ów. Możemy też zalogować ich wystąpienie, aby pomóc sobie z debugowaniu. Na koniec, jak pokazał Erich, możemy wykorzystać NetMX do sterowania poziomem logowania w aplikacji, czyli np. włączać i wyłączać logowanie wszystkich (lub tylko niektórych) domain events.

Jeśli chodzi o modyfikację poziomu logowania, to Erich opisał tę kwestię świetnie, więc nie będę się tym zajmował. Logowanie zdarzeń domenowych to kwesta rozbudowy mechanizmu Udiego:

  • albo o dodanie interfejsu niegenerycznego IEventHandler, który pozwala obsługiwać wszystkie zdarzenia,
  • albo zmianę sposobu wyszukiwania handler-ów tak, aby dla typu T sprawdzane były obiekty obsługujące wszystkie typy bazowe i interfejsy implementowane przez T.

Dzięki temu będziemy mogli napisać uniwersalnego handler-a logującego. Ja osobiście wybrałem to pierwsze rozwiązanie, ponieważ wydaje mi się dużo prostsze. To drugie, jest za to dużo potężniejsze, ale przecież YAGNI! :-)

Integracja z NetMX jest dosyć prosta i można do niej podejść na kilka sposobów. Ja wybrałem sposób z klasą bazową i konfiguracją w konstruktorze a’la FluentNHibernate — w przyszłości być może rozbuduję ją o możliwość konfigurowania przez konwencje. Póki co mam klasę bazową EventDrivenDynamicMBean, która udostępnia metodę

EventDrivenAttribute<T>(string attributeName, Predicate<T> filter)

przy czym parametr “filter” jest opcjonalny. Przykładowy MBean wygląda tak:

public TransactionProcessingMBean : EventDrivenDynamicMBean
{
   public TransactionProcessingMBean() : base("Przetwarzanie transakcji") //Przyjazna nazwa MBean-a
   {
      EventDrivenAttribute<TransactionProcessed>("Przetworzone");
      EventDrivenAttribute<InsufficientFunds>("Brak środków");
   }
}

Jeśli uważacie, że podejście jest interesujące, mogę spróbować wydzielić ten kod i wrzucić go tu, na bloga. Mnie  pozwoliło ono zaoszczędzić całą masę kodowania. Poprzednia implementacja monitorowania (także korzystała z NetMX) oparta była na MBean-ach standardowych (statycznych). Każdy taki MBean wymagał napisania interfejsu (eksponowanego zdalnie), klasy go implementującej oraz poutykania tu i ówdzie w modelu domeny odwołań inkrementujących odpowiednie liczniki MBean-a. Szczególnie to ostatnie bardzo mi się nie podobało i było głównym powodem to poszukiwania alternatywnych rozwiązań.

VN:F [1.9.13_1145]
Rating: 0.0/5 (0 votes cast)