Niedawno musiałem zbadać problem dotyczący naszej aplikacji dla dużych przedsiębiorstw. Byłem przerażony dziennikami, które musiałem przeczesać, próbując znaleźć problem, a na koniec dzienniki wcale nie pomogły w identyfikacji / izolacji błędu.
Uwaga: Rozumiem, że nie wszystkie błędy można wykryć za pomocą dzienników. Nie zmienia to faktu, że kłody są okropne.
Istnieją pewne oczywiste problemy z logowaniem, które możemy już spróbować naprawić. Nie chcę ich tutaj wymieniać i nie mogę po prostu pokazać wam naszych plików dziennika, abyście mogli udzielić porady, co robić.
Zamiast tego, aby ocenić, jak źle sobie radzimy przy logowaniu, chciałbym wiedzieć:
- Jakie są ewentualne wytyczne dotyczące rejestrowania aplikacji, zwłaszcza dużych aplikacji.
- Czy są jakieś wzorce, których powinniśmy przestrzegać, lub anty-wzorce, o których powinniśmy wiedzieć?
- Czy jest to ważna rzecz do naprawienia, czy może to nawet zostać naprawione, czy wszystkie pliki dziennika są po prostu ogromne i potrzebujesz dodatkowych skryptów do ich analizy?
Uwaga dodatkowa: używamy log4j.
Pracuję z krytycznymi dla bezpieczeństwa systemami czasu rzeczywistego, a logowanie jest często jedynym sposobem na złapanie rzadkich błędów, które pojawiają się raz niebieski księżyc w każdy 53 wtorek, gdy jest pełnia, jeśli złapiesz mój dryf. Ten rodzaj powoduje, że masz obsesję na punkcie tego tematu, więc przepraszam teraz, jeśli zacznę pienić się w usta. Poniższe napisano dla dzienników debugowania kodu natywnego, ale większość z nich dotyczy również zarządzanego świata ...
Użyj plików dziennika tekstowego. Wydaje się to oczywiste, ale niektórzy próbują generować binarne pliki dziennika: to po prostu głupie, ponieważ nie muszę szukać narzędzia czytającego, gdy jestem w terenie. Plus, jeśli jest to tekst, a debugowanie jest pełne, istnieje duża szansa, że inżynier terenowy może odczytać plik i zdiagnozować problem, nie wracając do mnie. Wszyscy wygrywają.
Projektuję systemy, które są w stanie zarejestrować prawie wszystko, ale domyślnie nie włączam wszystkiego. Informacje debugowania są wysyłane do ukrytego okna dialogowego debugowania, które sygnalizuje je znacznikiem czasowym i wysyła do pola listy (ograniczone do około 500 linii przed usunięciem), a okno dialogowe pozwala mi je zatrzymać, automatycznie zapisać w pliku dziennika lub przekierować do dołączony debugger. To przekierowanie pozwala mi zobaczyć, jak dane wyjściowe debugowania z wielu aplikacji są porządnie zserializowane, co może czasem uratować życie. I wykorzystywane do korzystania numerycznych poziomów rejestrowania (wyższa ustawić poziom, tym więcej można uchwycić):
ale jest to zbyt mało elastyczne - gdy zmierzasz w stronę błędu, bardziej efektywne jest skupienie się na logowaniu dokładnie na tym, czego potrzebujesz, bez konieczności przechodzenia przez mnóstwo detrytusu, i może to być jeden szczególny rodzaj transakcji lub operacji to powoduje błąd. Jeśli wymaga to włączenia wszystkiego, po prostu utrudniasz sobie pracę. Potrzebujesz czegoś drobniejszego.
Teraz przechodzę do logowania w oparciu o system flag. Wszystko, co jest rejestrowane, ma flagę opisującą rodzaj operacji, a zestaw pól wyboru pozwala mi zdefiniować, co zostanie zarejestrowane. Zazwyczaj ta lista wygląda następująco:
Ten system rejestrowania jest dostarczany z wersją kompilacji wersji , domyślnie włączoną i zapisującą do pliku. Jest za późno, aby dowiedzieć się, że powinieneś się logować PO wystąpieniu błędu, jeśli błąd występuje tylko raz na sześć miesięcy i nie możesz go odtworzyć. Rejestrowanie, które działa tylko z kompilacjami debugowania, jest po prostu. Równina. głupi.
Oprogramowanie zazwyczaj jest dostarczane z włączonymi BŁĘDAMI, PODSTAWOWYMI, STANEM_ZMIANY i WYJĄTKIEM, ale można to zmienić w terenie za pomocą okna dialogowego debugowania (lub ustawienia rejestru / ini / cfg, w którym te rzeczy są zapisywane).
No i jedno - mój system debugowania generuje jeden plik dziennie. Twoje wymagania mogą być inne. Ale upewnij się, że kod debugowania rozpoczyna każdy plik od daty, wersji uruchomionego kodu i, jeśli to możliwe, jakiegoś znacznika identyfikatora klienta, lokalizacji systemu lub cokolwiek innego. Możesz dostać miszmasz plików dziennika przychodzących z pola i potrzebujesz trochę informacji o tym, skąd pochodzą i jaka wersja systemu, na którym działali, która jest w samych danych, i nie możesz ufać klientowi / inżynier terenowy, który powie ci, którą wersję ma - może po prostu powiedzieć, którą wersję MYŚLĄ, którą mają. Co gorsza, mogą zgłaszać wersję exe, która znajduje się na dysku, ale stara wersja nadal działa, ponieważ zapomniały zrestartować się po wymianie. Niech Twój kod powie ci sam.
Wreszcie, nie chcesz, aby Twój kod generował własne problemy, więc włącz funkcję timera, aby wyczyścić pliki dziennika po tylu dniach lub tygodniach (po prostu sprawdź różnicę między czasem teraz a czasem utworzenia pliku). Jest to OK w przypadku aplikacji serwerowej, która działa cały czas, w aplikacji po stronie klienta możesz uzyskać usunięcie starych danych podczas uruchamiania. Zwykle oczyszczamy się po około 30 dniach, w systemie bez częstych wizyt inżyniera możesz chcieć zostawić go na dłużej. Oczywiście zależy to również od rozmiaru plików dziennika.
źródło
Moim ulubionym zasobem publicznym dotyczącym wskazówek dotyczących rejestrowania są Apache JCL Best Practices .
Pomimo celowania w JCL, wydają się one na tyle ogólne, że można je ogólnie przyjąć do logowania.
Najsłynniejszym anty-wzorem jest prawdopodobnie „połykanie wyjątków” - wystarczy wyszukać go w Internecie.
Jeśli chodzi o ogromne pliki logowania, w mojej praktyce był to w większości normalny przypadek. I tak, dodatkowe skrypty, jak je nazywasz i / lub narzędzia takie jak Piła łańcuchowa również dla mnie wyglądają normalnie.
PS. Jeśli chodzi o anty-wzory, inne, które przychodzą na myśl, to „powódź” i bezsensowne wiadomości.
Nazywam to zalewaniem, gdy widzę wiele podobnych wiadomości pochodzących z pętli z wieloma iteracjami. Dla mnie powódź jest na tyle denerwująca, że próbuję się jej pozbyć po wykryciu w kodzie źródłowym. Zwykle ulepszanie go wymaga trochę sztuki - ponieważ cóż, rzeczy, które dzieją się w pętli, mogą być interesujące. Kiedy nie mam czasu na głębszą poprawę, staram się przynajmniej zmienić poziom rejestrowania takich wiadomości na najniższy, aby ułatwić odfiltrowanie.
Wiadomości bezsensowne wydają się być dość popularnym śmieciem. Wyglądają one nieszkodliwie, gdy wczytywane są w kodzie źródłowym - chyba trzeba przejść przez proces analizowania wyników debugowania wyglądających jak ...
... aby głęboko docenić ich nieodłączną brzydotę. Moją ulubioną heurystyką do wykrywania tego rodzaju problemów na poziomie kodu źródłowego (zaproponowaną przez współpracownika w jednym z moich wcześniejszych projektów) jest obliczenie liczby wystąpień symboli spacji w literałach łańcuchowych używanych podczas logowania. Z mojego doświadczenia wynika, że zero spacji zasadniczo gwarantuje, że instrukcja rejestrowania jest bezsensowna, jedna spacja jest również dobrym wskaźnikiem potencjalnego problemu.
źródło
somethingSpecialHappenedCount
), a następnie przesyłane do rejestratora.Zaloguj wyjątek tylko raz!
Jednym z typowych problemów, które zauważyłem, jest rejestrowanie i ponowne zgłaszanie wyjątku. W rezultacie pliki dziennika zawierają kilka razy te same wyjątki na kilku poziomach stosu.
źródło
Oto anty-wzorzec: Utworzenie dwóch tuzinów „zmiennych ogólnych” w tabeli bazy danych w celu śledzenia wszystkiego, co możliwe, a następnie posiadanie 88 (i zliczanie) różnych wartości wyliczeniowych dla różnych typów dzienników.
źródło
Moje doświadczenie z logami jest tym większe, im lepsze, ale na tyle spójne, aby można je było filtrować według komputera i móc skonfigurować poziom ważności dla każdego komponentu aplikacji osobno.
Ponadto bardzo trudno jest przewidzieć, jakie logowanie będzie potrzebne do znalezienia przyszłego błędu. Większość oczywistych miejsc do rejestrowania błędów została naprawiona, zanim produkt wyjdzie za drzwi. Często zdarza się, że wynik zgłoszenia błędu polega na dodaniu rejestrowania w celu zdiagnozowania go, jeśli to się powtórzy.
źródło
Kilka notatek ze strony operacyjnej domu tutaj:
1) Upewnij się, że dzienniki są konfigurowalne lokalnie, najlepiej za pomocą narzędzia nie cięższego niż edytor tekstu. Przez większość czasu nie chcemy otrzymywać rejestrowania na poziomie TRACE, ale uwielbiamy móc go włączać.
2) Jeśli to możliwe, upewnij się, że dzienniki można odczytać za pomocą narzędzia nie cięższego niż edytor tekstu. Nie ma nic gorszego niż konieczność polowania na narzędzia w dziwnej godzinie, gdy system produkcyjny zawodzi.
źródło
Z własnego doświadczenia w pracy z aplikacjami internetowymi:
(i biorąc pod uwagę, że przechowywanie jest obecnie bardzo tanie)
Zachowaj spójność ze swoimi logami. Od zawsze używam tego rodzaju wzorca:
źródło
Oprócz stacktrace zaloguj bieżący stan aplikacji i dane wejściowe.
Oprogramowanie jest deterministyczne, te dwa są zwykle jedyną rzeczą, której potrzebujesz, aby odtworzyć błąd. Przechowywanie pełnego stanu może w niektórych przypadkach być kłopotliwe, więc sposoby na odtworzenie bieżącego stanu, na przykład przez poprzednie dane wejściowe, są również dobre.
Oczywiście więcej danych jest zawsze lepsze, ale przynajmniej te dwa są dobrym początkiem dla najłatwiejszych awarii.
źródło