JavaRush /Blog Java /Random-PL /Rejestrowanie w Javie. Rozwiń kulkę stectrasu

Rejestrowanie w Javie. Rozwiń kulkę stectrasu

Opublikowano w grupie Random-PL
„Dzień dobry, dzisiaj na terenie zakładu przemysłowego zarejestrowano zdarzenie, proszę dewelopera o dołączenie do grupy analitycznej.” Jeden z Twoich dni w pracy może rozpocząć się mniej więcej w ten sposób lub może to być poranek – to nie ma znaczenia. Ale zacznijmy od początku. Rozwiązując problemy w JavaRush, uczysz się pisać kod, który działa i robi to, czego się od niego oczekuje. Jeśli spojrzysz na sekcję pomocy , jasne jest, że nie zawsze działa to za pierwszym razem. W pracy będzie tak samo. Nie zawsze rozwiążesz problem za pierwszym razem: robaki są naszymi wiecznymi towarzyszami. Ważne jest, aby można było przywrócić zdarzenia związane z błędem. Logowanie.  Rozwiń kulkę stectrace - 1Zacznijmy od przykładu. Wyobraźmy sobie, że jesteś policjantem. Wezwano Cię na miejsce zdarzenia (w sklepie rozbito szybę), przyjechałeś i czekają na Twoją odpowiedź w sprawie tego, co się stało. Gdzie zacząć? Nie wiem, jak pracuje policja. Bardzo warunkowo – zaczynają szukać świadków, dowodów i tak dalej. A co by było, gdyby samo miejsce mogło szczegółowo opowiedzieć Ci, co się wydarzyło? Na przykład tak:
  • 21:59 właściciel włączył alarm (5 minut do pełnego uruchomienia)
  • 22:00 właściciel zamknął drzwi
  • 22:05 pełna aktywacja alarmu
  • 22:06 właściciel pociągnął za klamkę
  • 23:15 Włączono czujnik hałasu
  • 23:15 obok przebiegła sfora psów, głośno szczekając
  • 23:15 czujnik hałasu wyłączony
  • 01:17 włączył się czujnik wstrząsów na zewnętrznej szybie gabloty
  • 01:17 gołąb wleciał do szklanki
  • 01:17 pękło szkło
  • 01:17 włączona syrena
  • 01:17 gołąb otrząsnął się i odleciał
Cóż, nie trzeba długo zagłębiać się w takie szczegóły, od razu wiadomo, co się stało. Podobnie jest w rozwoju. To bardzo fajne, kiedy na nagraniach można stwierdzić, co się wydarzyło. Być może teraz pamiętasz debugowanie, ponieważ możesz debugować wszystko. Ale nie. Wróciłeś do domu, a wieczorem wszystko się zepsuło, nie ma co debugować: musisz zrozumieć, dlaczego się zepsuło i naprawić. Tutaj w grę wchodzą kłody, historia wszystkiego, co wydarzyło się w ciągu jednej nocy. W trakcie artykułu proponuję zastanowić się, jaki jest jeden z najsłynniejszych rejestratorów (właściwie nie rejestrator, raczej monitoring), o którym zapewne słyszał każdy, kto słucha (ogląda) wiadomości? Dzięki niemu niektóre wydarzenia zostają przywrócone. Teraz bądźmy poważni. Logowanie w Javie to proces rejestrowania wszelkich zdarzeń zachodzących w kodzie. Twoim obowiązkiem jako programisty jest zapisanie tego, co zrobił Twój kod, ponieważ wtedy te logi zostaną Ci przekazane do analizy. Jeśli wszystko zostanie zrobione dobrze, każdy błąd zostanie bardzo szybko rozwiązany i naprawiony. Tutaj prawdopodobnie nie będę się zagłębiał w to, jakie są rodzaje rejestratorów. W tym artykule ograniczymy się do prostego java.util.Logger: to więcej niż wystarczy, aby się poznać. Każdy wpis dziennika zawiera datę i godzinę, poziom zdarzenia i komunikat. Data i godzina są wprowadzane automatycznie. Poziom zdarzenia wybierany jest przez autora wiadomości. Istnieje kilka poziomów. Najważniejsze z nich to informacja, debugowanie, błąd.
  • INFO - zazwyczaj są to komunikaty informacyjne o tym, co się dzieje, coś w rodzaju historii według dat: 1915 - coś się wydarzyło, 1916 - coś innego.
  • DEBUGOWANIE - bardziej szczegółowo opisuje wydarzenia w danym momencie. Na przykład szczegóły historycznej bitwy są na etapie debugowania.” Komendant Takojtowicz ruszył ze swoją armią w kierunku wsi Selovicha .
  • BŁĄD - w tym miejscu zazwyczaj zapisywane są występujące błędy. Prawdopodobnie zauważyłeś, że kiedy coś zawijasz w try-catch, blok catchjest zastępowany przez e.printStacktrace(). Wyświetla tylko wpis do konsoli. Używając rejestratora, możesz wysłać ten wpis do rejestratora (haha), masz pomysł.
  • OSTRZEŻENIE – tutaj zapisywane są ostrzeżenia. Na przykład przegrzanie światła w samochodzie. To tylko ostrzeżenie i lepiej coś zmienić, ale to jeszcze nie awaria. Gdy maszyna się zepsuje, wówczas będziemy logować się z poziomem BŁĄD.
Ustaliliśmy poziomy. Ale nie martw się: granica między nimi jest bardzo cienka – nie każdy potrafi to wyjaśnić. Poza tym może się różnić w zależności od projektu. Starszy programista wyjaśni Ci na jakim poziomie i co logować. Najważniejsze jest to, że te zapisy wystarczą Ci do przyszłej analizy. I to jest rozumiane na bieżąco. Dalej są ustawienia. Rejestratorom można powiedzieć, gdzie mają pisać (do konsoli, do pliku, jms lub gdzie indziej) i określić poziom (informacje, błędy, debugowanie...). Przykładowe ustawienia naszego prostego rejestratora wyglądają następująco:
handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler

java.util.logging.FileHandler.level     = INFO
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append    = true
java.util.logging.FileHandler.pattern   = log.%u.%g.txt

java.util.logging.ConsoleHandler.level     = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
W tym przypadku wszystko jest skonfigurowane tak, aby logger zapisywał jednocześnie do pliku i do konsoli. W tym wypadku? jeśli coś zostanie usunięte w konsoli, a ponadto łatwiej jest wyszukiwać według plików. Poziom INFO dla obu. Dla pliku określony jest także wzorzec nazwy. Jest to minimalna konfiguracja, która pozwala na jednoczesne zapisywanie zarówno w konsoli, jak i w pliku. java.util.logging.FileHandler.appendustaw na true , aby stare wpisy w pliku nie zostały usunięte. Oto przykład użycia (bez komentarzy, rejestrator komentuje sam siebie):
public class Main {
    static Logger LOGGER;
    static {
        try(FileInputStream ins = new FileInputStream("C:\\log.config")){ \\полный путь до plik с конфигами
            LogManager.getLogManager().readConfiguration(ins);
            LOGGER = Logger.getLogger(Main.class.getName());
        }catch (Exception ignore){
            ignore.printStackTrace();
        }
    }
    public static void main(String[] args) {
        try {
            LOGGER.log(Level.INFO,"Начало main, создаем лист с типизацией Integers");
            List<Integer> ints = new ArrayList<Integer>();
            LOGGER.log(Level.INFO,"присваиваем лист Integers листу без типипзации");
            List empty = ints;
            LOGGER.log(Level.INFO,"присваиваем лист без типипзации листу строк");
            List<String> string = empty;
            LOGGER.log(Level.WARNING,"добавляем строку \"бла бла\" в наш переприсвоенный лист, возможна ошибка");
            string.add("бла бла");
            LOGGER.log(Level.WARNING,"добавляем строку \"бла 23\" в наш переприсвоенный лист, возможна ошибка");
            string.add("бла 23");
            LOGGER.log(Level.WARNING,"добавляем строку \"бла 34\" в наш переприсвоенный лист, возможна ошибка");
            string.add("бла 34");


            LOGGER.log(Level.INFO,"выводим все элементы листа с типизацией Integers в консоль");
            for (Object anInt : ints) {
                System.out.println(anInt);
            }

            LOGGER.log(Level.INFO,"Размер równa się " + ints.size());
            LOGGER.log(Level.INFO,"Получим первый элемент");
            Integer integer = ints.get(0);
            LOGGER.log(Level.INFO,"выведем его в консоль");
            System.out.println(integer);

        }catch (Exception e){
            LOGGER.log(Level.WARNING,"что-то пошло не так" , e);
        }
    }
}
To nie jest najlepszy przykład, wziąłem ten, który był pod ręką. Przykładowe wyjście:
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Начало main, создаем лист с типизацией Integers
апр 19, 2019 1:10:14 AM generics.Main main
INFO: присваиваем лист Integers листу без типипзации
апр 19, 2019 1:10:14 AM generics.Main main
INFO: присваиваем лист без типипзации листу строк
апр 19, 2019 1:10:14 AM generics.Main main
WARNING: добавляем строку "бла бла" в наш переприсвоенный лист, возможна ошибка
апр 19, 2019 1:10:14 AM generics.Main main
WARNING: добавляем строку "бла 23" в наш переприсвоенный лист, возможна ошибка
апр 19, 2019 1:10:14 AM generics.Main main
WARNING: добавляем строку "бла 34" в наш переприсвоенный лист, возможна ошибка
апр 19, 2019 1:10:14 AM generics.Main main
INFO: выводим все элементы листа с типизацией Integers в консоль
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер równa się 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
апр 19, 2019 1:10:14 AM generics.Main main
WARNING: что-то пошло не так
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
	at generics.Main.main(Main.java:45)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Tutaj chcę się skupić na notatkach:
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер równa się 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
Ten wpis jest zupełnie bezużyteczny i nie zawiera informacji. Podobnie jak wpis o błędzie:
WARNING: что-то пошло не так
Nie powinieneś tego pisać: to dziennik dla samego dziennika, tylko będzie przeszkadzał. Staraj się zawsze pisać sensowne rzeczy. Myślę, że to wystarczy, aby przestać go używać System.out.printlni przejść do zabawek dla dorosłych. Ma java.util.loggingwady. Przykładowo poziomów, które opisałem powyżej nie ma tutaj, ale są w większości używanych logerów. Wybrałem go do tego artykułu, java.util.loggingponieważ nie wymaga dodatkowych manipulacji przy połączeniu. Zwrócę też uwagę, że można go zastosować LOGGER.infozamiast. LOGGER.log(Level.INFO... Jedna z wad już się tu pojawia: LOGGER.log(Level.WARNING,"что-то пошло не так" , e);- pozwala na przesłanie wiadomości i obiektu Exception, sam rejestrator pięknie to zapisze. Jednocześnie LOGGER.warning("");odbiera jedynie komunikat, tj. Wyjątku nie można przekazać, musisz samodzielnie przetłumaczyć go na ciąg znaków. Mam nadzieję, że ten przykład wystarczy, aby zapoznać się z logowaniem w Javie. Następnie możesz podłączyć inne rejestratory (log4j, slf4j, Logback...) - jest ich wiele, ale istota jest ta sama^, aby rejestrować historię działań. Oficjalny poradnik
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION