JavaRush /Blog Java /Random-FR /Journalisation Java. Dérouler une boule de stectrace

Journalisation Java. Dérouler une boule de stectrace

Publié dans le groupe Random-FR
"Bon après-midi, aujourd'hui un incident a été enregistré sur le site industriel, je demande au promoteur de rejoindre le groupe d'analyse." Une de vos journées de travail pourrait commencer quelque chose comme ça, ou cela pourrait être le matin – cela n’a pas d’importance. Mais commençons par le début. En résolvant des problèmes ici dans JavaRush, vous apprenez à écrire du code qui fonctionne et fait ce que l'on attend de lui. Si vous regardez la section d'aide , il est clair que cela ne fonctionne pas toujours du premier coup. Ce sera pareil au travail. Vous ne résoudrez pas toujours un problème du premier coup : les bugs sont nos éternels compagnons. Il est important que vous puissiez restaurer les événements du bug. Enregistrement.  Dérouler une boule de stectrace - 1Commençons par un exemple. Imaginons que vous soyez un policier. Vous avez été appelé sur les lieux de l'incident (une vitre a été brisée dans un magasin), vous êtes arrivé et ils attendent des réponses de votre part sur ce qui s'est passé. Où commencer? Je ne sais pas comment fonctionne la police. Très conditionnellement - ils commencent à rechercher des témoins, des preuves et tout ça. Et si le lieu lui-même pouvait vous raconter en détail ce qui s’est passé ? Par exemple, comme ceci :
  • 21h59, le propriétaire a activé l'alarme (5 minutes jusqu'à ce qu'elle soit complètement activée)
  • 22h00 le propriétaire a fermé la porte
  • 22h05 activation complète de l'alarme
  • 22h06 le propriétaire a tiré la poignée
  • 23h15 capteur de bruit allumé
  • 23h15, une meute de chiens est passée en courant en aboyant bruyamment
  • 23h15 capteur de bruit éteint
  • 01:17 le capteur de choc sur la vitre extérieure de la vitrine est allumé
  • 01:17 un pigeon s'est envolé dans le verre
  • 01:17 le verre s'est cassé
  • 01:17 sirène allumée
  • 01:17 le pigeon s'est secoué et s'est envolé
Eh bien, vous n’avez pas besoin d’entrer longtemps dans de tels détails : ce qui s’est passé est immédiatement clair. La même chose est en cours de développement. C’est vraiment cool quand on peut voir à partir des enregistrements ce qui s’est passé. Maintenant, vous vous souvenez peut-être du débogage, car vous pouvez tout déboguer. Mais non. Vous êtes rentré chez vous, et la nuit tout s'est cassé, il n'y a rien à déboguer : il faut comprendre pourquoi c'est cassé et le réparer. C’est là qu’interviennent les journaux de bord, l’histoire de tout ce qui s’est passé du jour au lendemain. Au cours de l'article, je vous propose de réfléchir à ce qui est l'un des enregistreurs les plus célèbres (pas vraiment un enregistreur, plutôt une surveillance), dont tous ceux qui écoutent (regardent) l'actualité ont probablement entendu parler ? Grâce à lui, certains événements sont restaurés. Maintenant, soyons sérieux. La journalisation en Java est le processus d'enregistrement de tous les événements qui se produisent dans le code. Il est de votre responsabilité en tant que programmeur d'écrire ce que votre code a fait, car ces journaux vous seront alors remis pour analyse. Si tout est bien fait, tout bug sera résolu et corrigé très rapidement. Ici, je n’entrerai probablement pas dans les détails des types d’enregistreurs. Dans cet article nous nous limiterons au simple java.util.Logger: c’est largement suffisant pour faire connaissance. Chaque entrée de journal contient la date-heure, le niveau d'événement et le message. La date et l'heure sont saisies automatiquement. Le niveau de l'événement est choisi par l'auteur du message. Il existe plusieurs niveaux. Les principaux sont les informations, le débogage et les erreurs.
  • INFO - il s'agit généralement de messages d'information sur ce qui se passe, quelque chose comme un historique par date : 1915 - quelque chose s'est passé, 1916 - autre chose.
  • DEBUG - décrit plus en détail les événements d'un moment particulier. Par exemple, les détails d'une bataille dans l'histoire sont au niveau du débogage. " Le commandant Takoytovich a avancé avec son armée vers le village de Selovicha . "
  • ERREUR - les erreurs qui se produisent sont généralement écrites ici. Vous avez probablement remarqué que lorsque vous enveloppez quelque chose dans try-catch, le bloc catchest remplacé par e.printStacktrace(). Il affiche uniquement l'entrée sur la console. En utilisant un enregistreur, vous pouvez envoyer cette entrée à l'enregistreur (haha), vous voyez l'idée.
  • WARN - les avertissements sont écrits ici. Par exemple, un voyant de surchauffe dans une voiture. Ceci n'est qu'un avertissement, et il vaut mieux changer quelque chose, mais ce n'est pas une panne. Lorsque la machine tombe en panne, nous enregistrerons le niveau ERREUR.
Nous avons trié les niveaux. Mais ne vous inquiétez pas : la frontière entre eux est très mince – tout le monde ne peut pas l’expliquer. De plus, cela peut différer d’un projet à l’autre. Un développeur senior vous expliquera à quel niveau et quoi enregistrer. L'essentiel est que ces enregistrements vous suffisent pour une analyse future. Et cela se comprend à la volée. Viennent ensuite les paramètres. Les enregistreurs peuvent savoir où écrire (dans la console, dans un fichier, jms ou ailleurs) et spécifier le niveau (info, erreur, débogage...). Un exemple de paramètres pour notre simple enregistreur ressemble à ceci :
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
Dans ce cas, tout est configuré pour que le logger écrive en même temps dans un fichier et sur la console. Dans ce cas? si quelque chose est effacé dans la console, il est plus facile de rechercher par fichier. Niveau INFO pour les deux. Un modèle de nom est également spécifié pour le fichier. Il s'agit d'une configuration minimale qui vous permet d'écrire à la fois sur la console et dans un fichier. java.util.logging.FileHandler.appenddéfini sur true afin que les anciennes entrées du fichier ne soient pas effacées. Un exemple d'utilisation est le suivant (sans commentaires, l'enregistreur commente lui-même) :
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);
        }
    }
}
Ce n'est pas le meilleur exemple, j'ai pris celui qui était sous la main. Exemple de sortie :
апр 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)
Ici, je veux me concentrer sur les notes :
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер equals 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
Cette entrée est tout à fait inutile et non informative. Comme l'entrée d'erreur :
WARNING: что-то пошло не так
Vous ne devriez pas écrire ceci : c'est un journal pour le plaisir d'un journal, cela ne fera que gêner. Essayez de toujours écrire des choses significatives. Je pense que cela suffit pour arrêter de l'utiliser System.out.printlnet passer aux jouets pour adultes. Cela java.util.loggingprésente des inconvénients. Par exemple, les niveaux que j'ai décrits ci-dessus ne sont pas ici, mais ils se trouvent dans les enregistreurs les plus utilisés. Je l'ai choisi pour cet article java.util.loggingcar il ne nécessite pas de manipulations supplémentaires avec la connexion. Je noterai également qu'il peut être utilisé LOGGER.infoà la place d' LOGGER.log(Level.INFO... un des inconvénients qui apparaît déjà ici : LOGGER.log(Level.WARNING,"что-то пошло не так" , e);- il permet de transmettre un message et un objet Exception, le logger lui-même l'écrira magnifiquement. En même temps, LOGGER.warning("");il ne reçoit qu'un message, c'est-à-dire L'exception ne peut pas être transmise, vous devez la traduire vous-même en chaîne. J'espère que cet exemple sera suffisant pour vous familiariser avec la journalisation Java. Ensuite, vous pouvez connecter d'autres enregistreurs (log4j, slf4j, Logback...) - il y en a beaucoup, mais l'essence est la même^ pour enregistrer l'historique des actions. Tutoriel officiel
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION