"O, tu jesteś! Pamiętasz, że mamy dzisiaj kolejną lekcję?"

– Nie, po prostu cię szukałem. Prawie…

„Wspaniale, więc zaczynajmy. Dzisiaj chcę ci opowiedzieć o wyrębie”.

„Dziennik to lista zdarzeń, które miały miejsce. Prawie jak dziennik statku lub pamiętnik. Albo Twitter – może lepiej się do tego odnosisz. Nic dziwnego, że rejestrator to obiekt, którego używasz do rejestrowania”.

„W programowaniu zwyczajowo rejestrujemy prawie wszystko. A w Javie rejestrujemy wszystko, a nawet trochę więcej”.

„Faktem jest, że programy Java są bardzo często dużymi aplikacjami serwerowymi bez interfejsu użytkownika, konsoli itp. Przetwarzają jednocześnie tysiące żądań użytkowników i często występują różne błędy. Zwłaszcza, gdy różne wątki zaczynają ze sobą kolidować”.

„W rzeczywistości jedynym sposobem wyszukiwania rzadko powtarzalnych błędów i awarii w takich okolicznościach jest rejestrowanie wszystkiego, co dzieje się w każdym wątku”.

„Najczęściej dziennik zawiera informacje o argumentach metod, wszelkich wyłapanych błędach i wiele informacji pośrednich”.

„Im pełniejszy dziennik, tym łatwiej odtworzyć sekwencję zdarzeń i śledzić przyczyny awarii lub błędów”.

„Czasami dzienniki osiągają kilka gigabajtów dziennie. To normalne”.

„Kilka gigabajtów? O_o”

„Tak. Najczęściej pliki dziennika są archiwizowane automatycznie, ze wskazaniem odpowiedniej daty”.

"Wow."

„Aha. Początkowo Java nie miała własnego rejestratora. W rezultacie napisano kilka niezależnych rejestratorów. Najpopularniejszym z nich był log4j”.

„Kilka lat później Java dostała własny rejestrator, ale jego funkcjonalność była znacznie gorsza i nie była powszechnie używana”.

„Faktem jest, że Java ma oficjalnego rejestratora, ale cała społeczność programistów Javy woli używać innych rejestratorów ” .

„Później napisano kilka innych rejestratorów opartych na log4j”.

„Następnie dla nich wszystkich napisano specjalny uniwersalny rejestrator slf4j, który jest obecnie powszechnie używany. Jest bardzo podobny do log4j, więc użyję go jako przykładu podczas wyjaśniania logowania”.

„Cały proces logowania składa się z trzech części”.

Najpierw zbierz informacje”.

Po drugie , przefiltruj zebrane informacje”.

Po trzecie , zapisz wybrane informacje”.

„Zacznijmy od kolekcji. Oto typowy przykład klasy, która rejestruje:”

Klasa z logowaniem
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.compleate();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

„Zwróć uwagę na słowa zaznaczone na czerwono”.

Linia 3  – Utwórz obiekt loggera . Taki statyczny obiekt jest tworzony prawie w każdej klasie! No, poza klasami, które nie robią nic poza przechowywaniem danych.”

" LoggerFactory to specjalna klasa do tworzenia loggerów, a getLogger to jedna z jej metod statycznych. Bieżący obiekt jest zwykle przekazywany, ale możliwe są różne opcje."

" Linia 7 – Informacja o wywołaniu metody jest zapisywana do loggera. Należy zauważyć, że jest to pierwsza linia metody. Gdy tylko metoda zostanie wywołana, natychmiast zapisujemy informację do logu."

„Nazywamy metodę debugowania, co oznacza, że ​​ważność informacji jest na poziomie DEBUG. Służy do filtrowania. Opowiem ci o tym za kilka minut”.

Linia 17 – Wyłapujemy wyjątek i… natychmiast zapisujemy go w dzienniku! To jest dokładnie to, co należy zrobić”.

„Tym razem wywołujemy metodę error, która od razu wskazuje, że informacja jest na poziomie ERROR”

Rejestrator - 1

- Na razie wszystko wydaje się jasne. Cóż, na tyle, na ile może być jasne w trakcie naszej rozmowy.

„Świetnie, w takim razie przejdźmy do filtrowania wiadomości”.

„Zwykle każdy komunikat dziennika ma swój własny poziom ważności, którego można użyć do odrzucenia niektórych komunikatów. Oto poziomy ważności, o których wspomniałem:”

Poziom ważności Opis
WSZYSTKO Wszystkie wiadomości
NAMIERZAĆ Drobne komunikaty debugowania
ODPLUSKWIĆ Ważne komunikaty debugowania
INFORMACJE Komunikaty informacyjne
OSTRZEGAĆ Ostrzeżenia
BŁĄD Błędy
FATALNY Fatalne błędy
WYŁĄCZONY Brak wiadomości

Te poziomy są również używane podczas filtrowania wiadomości.

Załóżmy, że ustawiłeś poziom rejestrowania na WARN. Wtedy wszystkie komunikaty mniej ważne niż WARN zostaną odrzucone: TRACE, DEBUG, INFO.

Jeśli ustawisz poziom filtrowania na FATAL, nawet komunikaty o BŁĘDACH zostaną odrzucone.

„Podczas filtrowania używane są jeszcze dwa poziomy ważności: WYŁ., który odrzuca wszystkie wiadomości, oraz WSZYSTKO, który pokazuje wszystkie wiadomości (nic nie jest odrzucane).”

„Jak i gdzie skonfigurować filtrowanie?”

– Powiem ci bez zbędnych ceregieli.

„Zwykle ustawienia rejestratora log4j są określone w pliku log4j.properties”.

W tym pliku można określić wiele obiektów programu dołączającego. Dane są zapisywane w tych obiektach. Istnieją źródła danych i są dołączacze — obiekty, które mają przeciwne cele. Obiekty, do których dane wpływają jak woda.

„Oto kilka przykładów:”

Logowanie do konsoli
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

Linie 1 i 4 – To są komentarze

Linia 2 – Wskazujemy żądany poziom logowania. Wszystkie mniej ważne poziomy (DEBUG, TRACE) zostaną odrzucone.

W tym samym miejscu dodajemy przecinek, a następnie wskazujemy nazwę obiektu (który sami wymyślimy), do którego zapisywany będzie log. Linie 5-9 zawierają jego ustawienia.

Linia 5 – Określamy typ appendera ( ConsoleAppender ).

Linia 6 – Wskazujemy dokładnie, gdzie piszemy ( System.out. ).

Linia 7 – Ustawiamy klasę, która będzie zarządzać wzorcami konwersji (PatternLayout).

Linia 8 – Ustalamy wzór konwersji, który będzie używany do pisania. W powyższym przykładzie jest to data i godzina.

„A oto jak wygląda zapisywanie do pliku:”

Logowanie do pliku
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

„Linia 2 ustawia poziom filtrowania komunikatów i nazwę obiektu dołączającego (ujścia).”

„Linia 5 — określamy typ programu dołączającego plik ( RollingFileAppender ).”

„Linia 6 – Podajemy nazwę pliku, do którego zostanie zapisany dziennik.”

„Linia 7 – Określamy maksymalny rozmiar dziennika. Po przekroczeniu tego limitu rozmiaru tworzony jest nowy plik”.

„Linia 8 – Określamy liczbę przechowywanych starych plików dziennika”.

„Linie 9-10 – Ustaw wzór konwersji”.

„Nie wiem, co się tutaj dzieje, ale mogę się domyślić. To budujące”.

„To świetnie. Oto przykład, jak zapisać dziennik w pliku i konsoli:”

Logowanie do konsoli i pliku
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

„Ach, więc możesz to zrobić? To świetnie!”

„Tak. Możesz zadeklarować dowolną liczbę dołączaczy i dostosować każdego z nich”.

Ponadto każdy program dołączający może mieć bardzo elastyczne ustawienia filtrowania wiadomości. Nie tylko możemy przypisać indywidualny poziom filtrowania wiadomości do każdego appendera, ale możemy również filtrować wiadomości według pakietu! Dlatego podczas tworzenia loggera musisz określić klasę (mówię o LoggerFactory.getLogger ).

"Na przykład:"

Logowanie do konsoli i pliku
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

„Linie 6 i 15 – Ustawiliśmy własny poziom filtrowania dla każdego programu dołączającego”.

„Linie 20-23 – Określamy nazwę pakietu i poziom filtrowania jego wiadomości. Log4j.logger to prefiks: nazwa pakietu jest podświetlona na pomarańczowo”.

„Naprawdę? Możesz nawet to zrobić. Cóż, fajnie!”

„Nawiasem mówiąc, ani log4j, ani slf4j nie są zawarte w JDK. Musisz pobrać je osobno. Możesz to zrobić tutaj . Ale jest inny sposób:”

Krok 1. Dodaj importy do klasy:”

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Krok 2. Umieść kursor na tych liniach i naciśnij Alt+Enter w IntelliJ IDEA”

Krok 3. Wybierz pozycję menu „Plik jar w internecie”.

" Krok 4. Wybierz 'slf4j-log4j13.jar'"

Krok 5. Określ, gdzie pobrać bibliotekę (słoik)”

Krok 6. Skorzystaj z zajęć, których potrzebujesz”.

„Wow! Cóż to był za dzień. Tyle nowości i tyle fajnych!”

„Oto kolejny dobry artykuł na temat rejestrowania: https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSCOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC

"Dobrze, wystarczy. Idź się zrelaksować, programiście."