W którym miejscu logować zdarzenia?

0

Załóżmy ze mam aplikację webową, jakiś kontroler, kilka service'ow do których odwołuje się kontroler, żeby pobierać dane. Chciałbym logować problemy do pliku. Są jakieś zasady, gdzie powinno się to robić, czy w kontrolerze, czy w service?
Na przykłąd kontroler wywołuje metodę z service'a i okazuje się ze wyszło dzielenie przez zero. Błąd przekazywany jest do kontrolera gdzie wyswietlam uzytkownikowi informacje co się stało. Chciałbym to zalogować do pliku jako błąd. Czy kod Log.Error(...) powinien zostać umieszczony w metodzie servicea ktora rzuciła wyjątek, czy w kontrolerze ktory ten błąd przekazuje użytkownikowi?

0

W sumie nie dałbym jednoznacznej odpowiedzi na to pytanie - można podejść dwojako:

  1. Logować przy każdym try / catch (w catchu w sumie powinno być obowiązkowe) oraz wszędzie tam gdzie chcemy w danym miejscu (czyli w serwisach)

  2. Nie wiem jak w .NET, ale w Javowym / Springowym świecie jest coś takiego jak @ControllerAdvice czyli miejsce, gdzie przechwytujesz wszystkie wyjątku przed zwróceniem ich z serwera. Wtedy w takim miejscu jak najbardziej można również logować wyjątki, tylko że tutaj to jest podejście bardziej generyczne - wiemy że poleciał wyjątek, ale nie wiemy dokładnie dlaczego.

1

Globalny filter/middleware do łapania wyjątków w kontrolerach, gdzie raz piszesz kod logujący błędy plus wszędzie gdzie obslugujesz wyjątki i chcesz coś zalogować.

3

To zależy od tego jak bardzo dokładnych logów potrzebujesz. Czasami potrzebujesz jednego loga w ramach use case'a a czasami nawalone znacznie więcej, w zależności od na przyklad krytyczności danego ficzeru aplikacji (czyli jak szybko chcesz móc znaleźć przyczynę błędu). Na pewno warto logować jakieś błędy integracji np. po REST czy SOAP do innych API blisko ich wywołania :)

0

Nie wiem czy używasz mediatR ale w wersji 8 pojawiła się możliwość obsługi exceptionow https://medium.com/aeturnuminc/microservices-using-mediatr-on-net-core-3-1-with-exception-handling-c273a7aa4a70
https://github.com/jbogard/MediatR/wiki
sam nie miałem okazji sprawdzać ale wygląda ciekawie.

1

@kalimata: Takie sytuacje powinieneś wychwycić przez walidację danych wejściowych i zwrócić błąd w postaci jakiegoś kodu HTTP. Wyjątki jak sama nazwa wskazuje powinny być używane do sytuacji wyjątkowych, czyli takich, które nie zostały przewidziane przez programistę. Jeśli już dojdzie do takiej sytuacji, że walidacja nie wychwyci jakiś błędnych danych wejściowych i przez to serwis wyrzuci wyjątek według mnie powinien być on obsłużony w warstwie API, czyli w kontrolerze. Być może najlepszym rozwiązaniem będzie napisanie jakiejś własnej klasy BazowyKontroler (po angielsku :P) która będzie miała metodę obsługującą te wyjątki. Albo metoda w klasie statycznej, jeśli logger ma być singletonem. Opcji na pewno jest kilka.

Jeśli używasz MediatR to rada @szydlak jest jak najbardziej zasadna.

0
kalimata napisał(a):

Załóżmy ze mam aplikację webową, jakiś kontroler, kilka service'ow do których odwołuje się kontroler, żeby pobierać dane. Chciałbym logować problemy do pliku. Są jakieś zasady, gdzie powinno się to robić, czy w kontrolerze, czy w service?

Na przykłąd kontroler wywołuje metodę z service'a i okazuje się ze wyszło dzielenie przez zero. Błąd przekazywany jest do kontrolera gdzie wyswietlam uzytkownikowi informacje co się stało. Chciałbym to zalogować do pliku jako błąd. Czy kod Log.Error(...) powinien zostać umieszczony w metodzie servicea ktora rzuciła wyjątek, czy w kontrolerze ktory ten błąd przekazuje użytkownikowi?

Różnych rodzajów błędów w aplikacji możesz mieć bardzo wiele, jeśli będziesz je logował w serwisach, to w każdym z nich prawdopodobnie powielisz te same fragmenty kodu. Podobnie będzie, jeśli zrobisz to w kontrolerach.
Dlatego lepiej zrobić to "nad kontrolerami", w jakimś middlewarze/filtrze, który zgarnie wszystkie exceptiony, przetworzy na HTTP 500 i do tego zaloguje.

Aleksander32 napisał(a):

To zależy od tego jak bardzo dokładnych logów potrzebujesz. Czasami potrzebujesz jednego loga w ramach use case'a a czasami nawalone znacznie więcej, w zależności od na przyklad krytyczności danego ficzeru aplikacji (czyli jak szybko chcesz móc znaleźć przyczynę błędu). Na pewno warto logować jakieś błędy integracji np. po REST czy SOAP do innych API bliso ich wywołania :)

Niekoniecznie musi to być blisko, wyjątek rzucony przez warstwę integracji z jakimś serwisem można przechwycić gdzieś wysoko i wyciągnąć z niego wszystkie szczegóły.

"Blisko" trzeba logować (i ogólnie łapać wyjątki), gdy coś z tym wyjątkiem chcemy zrobić (np. zignorować i jedynie zalogować), bo nie przerywa on nam procesu, a chcemy po prostu mieć informację o nieprawidłowości.

Robiąc to na poziomie MediatR pomijamy wszelkie wyjątki z warstwy webowej (autoryzacja, model binding, zepsute IoC, i wiele innych rzeczy), więc znowu musimy zduplikować kod.

1 użytkowników online, w tym zalogowanych: 0, gości: 1