JavaRush /Java Blog /Random-IT /Registrazione Java. Svolgi una palla di stectrace

Registrazione Java. Svolgi una palla di stectrace

Pubblicato nel gruppo Random-IT
"Buon pomeriggio, oggi è stato registrato un incidente nel sito industriale, chiedo allo sviluppatore di unirsi al gruppo di analisi." Una delle tue giornate di lavoro potrebbe iniziare in questo modo, oppure potrebbe essere la mattina, non importa. Ma cominciamo dall'inizio. Risolvendo i problemi qui in JavaRush, impari a scrivere codice che funziona e fa ciò che ci si aspetta da esso. Se guardi la sezione di aiuto , è chiaro che non sempre funziona la prima volta. Sarà lo stesso al lavoro. Non sempre risolverai un problema la prima volta: gli insetti sono i nostri compagni eterni. È importante ripristinare gli eventi del bug. Registrazione.  Srotolare una palla di stectrace - 1Cominciamo con un esempio. Immaginiamo che tu sia un poliziotto. Sei stato chiamato sul luogo dell'incidente (il vetro era rotto in un negozio), sei arrivato e stanno aspettando da te risposte su quello che è successo. Da dove cominciare? Non so come lavora la polizia. In modo molto condizionale: iniziano a cercare testimoni, prove e tutta quella roba. E se il luogo stesso potesse raccontarti nel dettaglio cosa è successo? Ad esempio, in questo modo:
  • 21:59 il proprietario ha attivato l'allarme (5 minuti fino all'attivazione completa)
  • 22:00 il proprietario ha chiuso la porta
  • 22:05 attivazione allarme totale
  • 22:06 il proprietario ha tirato la maniglia
  • 23:15 sensore di rumore acceso
  • 23:15 un branco di cani passò correndo, abbaiando forte
  • 23:15 sensore di rumore spento
  • 01:17 il sensore d'urto sul vetro esterno della vetrina si è acceso
  • 01:17 un piccione è volato nel bicchiere
  • 01:17 il vetro si è rotto
  • 01:17 sirena accesa
  • 01:17 il piccione si scrollò di dosso e volò via
Bene, non devi approfondire questi dettagli a lungo, è immediatamente chiaro cosa è successo. Lo stesso è in fase di sviluppo. È molto bello quando puoi capire dalle registrazioni cosa è successo. Ora potresti ricordare il debug, perché puoi eseguire il debug di tutto. Ma no. Sei tornato a casa e di notte tutto si è rotto, non c'è niente da eseguire il debug: devi capire perché si è rotto e aggiustarlo. È qui che entrano in gioco i registri, la storia di tutto ciò che è accaduto da un giorno all'altro. Nel corso dell'articolo, ti suggerisco di pensare a cos'è uno dei logger più famosi (non propriamente un logger, più simile a un monitoraggio), di cui probabilmente tutti quelli che ascoltano (guardano) le notizie hanno sentito parlare? Grazie a lui alcuni eventi vengono ripristinati. Ora diventiamo seri. L'accesso in Java è il processo di registrazione di tutti gli eventi che si verificano nel codice. È tua responsabilità come programmatore annotare ciò che ha fatto il tuo codice, perché poi questi log ti verranno forniti per l'analisi. Se tutto è fatto bene, qualsiasi bug verrà risolto e corretto molto rapidamente. Qui probabilmente non approfondirò che tipo di logger esistono. In questo articolo ci limiteremo alle cose semplici java.util.Logger: è più che sufficiente per conoscerci. Ogni voce di registro contiene data-ora, livello evento, messaggio. La data e l'ora vengono inserite automaticamente. Il livello dell'evento viene scelto dall'autore del messaggio. Ci sono diversi livelli. I principali sono info, debug, errore.
  • INFO - di solito si tratta di messaggi informativi su ciò che sta accadendo, qualcosa come una cronologia per data: 1915 - è successo qualcosa, 1916 - qualcos'altro.
  • DEBUG: descrive gli eventi di un momento particolare in modo più dettagliato. Ad esempio, i dettagli di una battaglia nella storia sono al livello di debug." Il comandante Takoytovich avanzò con il suo esercito verso il villaggio di Selovicha ."
  • ERRORE: gli errori che si verificano vengono solitamente scritti qui. Probabilmente hai notato che quando avvolgi qualcosa in try-catch, il blocco catchviene sostituito con e.printStacktrace(). Invia solo la voce alla console. Usando un logger, puoi inviare questa voce al logger (haha), hai capito.
  • WARN: gli avvisi vengono scritti qui. Ad esempio, una spia di surriscaldamento in un'auto. Questo è solo un avvertimento ed è meglio cambiare qualcosa, ma questo non è un guasto. Quando la macchina si guasta, registreremo il livello ERRORE.
Abbiamo sistemato i livelli. Ma non preoccuparti: il confine tra loro è molto sottile e non tutti possono spiegarlo. Inoltre, potrebbe differire da progetto a progetto. Uno sviluppatore senior ti spiegherà a quale livello e cosa registrare. La cosa principale è che questi record sono sufficienti per te per analisi future. E questo lo si capisce al volo. Poi ci sono le impostazioni. Ai logger può essere detto dove scrivere (sulla console, file, jms o da qualche altra parte) e specificare il livello (informazioni, errore, debug...). Un esempio di impostazioni per il nostro semplice logger è simile al seguente:
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
In questo caso tutto è configurato in modo che il logger scriva su un file e sulla console contemporaneamente. In quel caso? se qualcosa viene cancellato nella console, inoltre è più semplice effettuare la ricerca per file. Livello INFO per entrambi. Viene inoltre specificato un modello di nome per il file. Questa è una configurazione minima che ti consente di scrivere sia sulla console che su un file contemporaneamente. java.util.logging.FileHandler.appendimpostato su true in modo che le vecchie voci nel file non vengano cancellate. Un esempio di utilizzo è questo (senza commenti, il logger commenta se stesso):
public class Main {
    static Logger LOGGER;
    static {
        try(FileInputStream ins = new FileInputStream("C:\\log.config")){ \\полный путь до file с конфигами
            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,"Размер equals " + 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);
        }
    }
}
Questo non è l'esempio migliore, ho preso quello che era a portata di mano. Esempio di output:
апр 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: Размер equals 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)
Qui voglio concentrarmi sulle note:
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер equals 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
Questa voce è abbastanza inutile e non informativa. Come la voce di errore:
WARNING: что-то пошло не так
Non dovresti scrivere questo: è un registro fine a se stesso, sarà solo d'intralcio. Cerca di scrivere sempre cose significative. Penso che questo sia sufficiente per smettere di usarlo System.out.printlne passare ai giocattoli per adulti. Ha java.util.loggingdegli svantaggi. Ad esempio, i livelli che ho descritto sopra non sono qui, ma sono nei logger più utilizzati. L'ho scelto per questo articolo java.util.loggingperché non richiede ulteriori manipolazioni con la connessione. Noterò anche che può essere usato LOGGER.infoal posto di LOGGER.log(Level.INFO... Uno degli svantaggi già appare qui: LOGGER.log(Level.WARNING,"что-то пошло не так" , e);- ti permette di trasmettere un messaggio e un oggetto Exception, il logger stesso lo scriverà magnificamente. Allo stesso tempo LOGGER.warning("");riceve solo un messaggio, ad es. L'eccezione non può essere passata, devi tradurla tu stesso in una stringa. Spero che questo esempio sia sufficiente per familiarizzare con la registrazione Java. Quindi puoi connettere altri logger (log4j, slf4j, Logback...): ce ne sono molti, ma l'essenza è la stessa^ per registrare la cronologia delle azioni. Tutorial ufficiale
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION