Logowanie dla leniwych

Nie lubię logowania

Nie lubię logowania — brudzi mi w kodzie; narzekam, gdy podczas ratowania produkcji brak logów — jak żyć?!

Jestem leniwy, nie lubię pamiętać o tym i tamtym — lubię, gdy rzeczy dzieją się same i nie muszę sobie zawracać tym głowy. Ale bez przesady! Logi to najgorsze i najlepsze co może spotkać programistów — z jednej strony logi zaśmiecają kod, z drugiej strony dają podgląd na to, co użytkownicy wymyślili na produkcji.

AOP

Logowanie przy pomocy AOP oczyszcza kod w przypadku typowego i klasycznego podejścia do logów, ok — może to zrobić. Często szukam w logach tego, co zostało uruchomione i z jakim parametrem, aby zrozumieć, co poszło nie tak. Nie lubię ^C^V takiego kodu na początku każdej metody. Niestety nie znalazłem dobrego rozwiązania AOP (czytaj darmowego) a interfejs IIntercept z jakiegoś powodu nie chce zostać uruchomiony (ale jest tworzony — kiedyś to zrozumiem); z tego powodu przy pomocy internetów znalazłem DispatchProxy które świetnie robi swoją robotę.

DispatchProxy

Otóż chciałbym mieć możliwość logowania tego, co i jak się wywołuje z możliwością włączenia / wyłączenia detali (poziomy logowania w moim przypadku, lub inna forma konfiguracji). Chce móc przeczytać logi i dowiedzieć się co się wywołuje i z jakim parametrami, dla każdej metody, dodatkowo bez potrzeby modyfikacji kodu, gdy dana metoda się zmieni.

Można to zrobić przy pomocy DispatchProxy które przechwyci wywołanie metody i umożliwi wykonanie dowolnego kodu; przed; po czy też podczas błędu.

Otóż taka klasa opina ładnie swoją docelową klasę T , a następnie podczas tworzenia zwraca takie proxy, udając klasę typu podstawowego. Tutaj uwaga: konstruktor musi być pusty, a ewentualne przekazanie parametrów i ich  przypisanie następuje w metody fabrykującej (wewnątrz if)

Gdy użytkownik takiej klasy wywołuje metodę docelową, na proxy wcześniej zostanie zawołane Invoke gdzie można czynić cuda.
Ja na przykład na poziomie `Information` loguje nazwę wywoływanej metody, a na poziomie Debug dorzucam także nazwy i wartości przekazanych argumentów.

Rejestracja

Piękne jest to, że DispatchProxy nie wymaga zewnętrznych bibliotek i działa na czysto z .net. Zależność do klasy rejestruje w taki sposób:

Akcja

Działa to tak:

Tutaj przykład konsumpcji oraz wykorzystania przykładowego serwisu

A tutaj logi:

Serwis jest nudny do bólu i prawie o nim zapomniałem:

Siup

W tak przygotowanym kodzie, zależności rejestrowane z pomocą logera powinny samodzielnie wrzucać informację o tym, co i jak się wykonało. Oczywiście można dodać sobie flagi do optymalizacji tego, czy przed, czy po co w sytuacjach wyjątkowych ma się logować i na jakim poziomie. Warto także pomyśleć o tym, jak takie logi ze sobą łączyć za pomocy correlationId – ale to pozostawiam już waszej wyobraźni.

 

ps.
dzisiaj bez obrazka

Wspólne modele dla dotnet i typescript

Trawa za płotem bardziej zielona

W Blazor’ze bardzo podoba mi się to, że brane są modele z dotnet (czy to api, czy to dowolna warstwa) i że każda zmiana na “backendzie” za darmo i od razu dostępna na “froncie”. Typescript ma fajne to, że można sobie silnie typować obiekty i że ten javascript jest takie ciut pewniejszy. Angular dla mnie mocno przypomina MVC więc z niego korzystam – ale! Jestem dobry w narzekanie; ale nie ma tego co ma blazor – a ja bym chciał. Bo takie przepisywanie modeli z dotnet na typescript to jest nudne, coś zmienisz, albo machniesz literówkę i trzeba szukać. Lubię też się wyręczać robotą kogoś innego 😉

google is your friend

Także poszukałem jak to ogarnąć. Co? No to, jak z klas w dotnet generować  klasy / kod do typescript, który można potem wykorzystać w projekcie na froncie.

Continue reading

Konfiguracja aplikacji

Konfiguracja aplikacji wydaje się być prosta, 😊 appsettings.json i jazda. Trochę tak, można trochę  więcej, bo przecież jest 🙂 azure key vault,
😅enviroment settings lokalnie, 😂enviroment settings na hoście,
😹appsettings.json.local, 😭appsettings.json.develop czy wreszcie
🤪Azure App Configuration.

Co wybrać jak żyć? To może po kolei 🚂

Continue reading

Autofixture

Dlaczego

Gdy testuje kod często / zawsze pojawia się potrzeba generowania jakichś danych, czasem mają one sens, czasem są zupełnie niepotrzebne z punktu widzenia testu, a jednocześnie wymagane przez kod.
Pojawiają się wtedy najczęściej zapisy “foo”, “bar”,”dupa”, “not-important”, “asdqweadasdf0923409” czy inne.
Zamiast takich wartości można mieć inne, jakie? Nie ważne! Co?! 😲

Gdy testujesz kod, to potrzebujesz zawsze sprawdzić, czy tekst to “jakiś_tekst” jest równy “jakiś_tekst”? Czy może po prostu jest taki jaki powinien być nie ważne, jaką będzie mieć wartość? (to samo tyczy się wartości liczbowych)

Skąd brać dane

Jarek, cwaniaku, to jak? Ano można przez pisanie tego inline w teście, co spowoduje, że testy osiągną rozmiary amerykańskie 😉 i będą duplikowane w każdy teście.
Można przez mother object pattern (nie ma sensownego linka, poszukajcie różnych opisów) – to taki wielki obiekt, który zajmuje się generowaniem takich danych.
Można przez: autofixture 👈😲👏

Continue reading

Kompresja na azure?

Intro

Poprzednio (tutaj) było o gzipe w odpowiedziach z aplikacji, tym razem o jeszcze jednym gzipie.


Problem

Ściągam dużo danych (nie big data, ale sam za to płacę), trzymam to w wersji surowej na przyszłość, bo gdy będę chciał wyświetlić więcej informacji, to mogę przejechać od początku wszystkie dane, tak mam plan :). Część surówki zostaje przeparsowana i zamieniona na jsona. Jeszcze jedna część z tych danych będzie zwracana do klienta, a klient (frontend) ten obsługuje gzipa – także combo profit; mniej miejsca, mniejszy transfer.

Continue reading