JavaRush /Java Blog /Random EN /Java Logging. Unwind a ball of stectrace

Java Logging. Unwind a ball of stectrace

Published in the Random EN group
"Good afternoon, today an incident was recorded at the industrial site, I ask the developer to join the analysis group." One of your days at work could start something like this, or it could be the morning – it doesn’t matter. But let's start from the beginning. By solving problems here in JavaRush, you learn to write code that works and does what is expected of it. If you look at the help section , it is clear that this does not always work out the first time. It will be the same at work. You won’t always solve a problem the first time: bugs are our eternal companions. It is important that you can restore the events of the bug. Logging.  Unwind a ball of stectrace - 1Let's start with an example. Let's imagine that you are a policeman. You were called to the scene of the incident (glass was broken in a store), you arrived, and they are waiting for answers from you about what happened. Where to begin? I don't know how the police work. Very conditionally - they start looking for witnesses, evidence and all that stuff. What if the place itself could tell you in detail what happened? For example, like this:
  • 21:59 owner turned on the alarm (5 minutes until fully activated)
  • 22:00 owner closed the door
  • 22:05 full alarm activation
  • 22:06 owner pulled the handle
  • 23:15 noise sensor turned on
  • 23:15 a pack of dogs ran past, barking loudly
  • 23:15 noise sensor switched off
  • 01:17 the shock sensor on the outer glass of the display case turned on
  • 01:17 a pigeon flew into the glass
  • 01:17 glass broke
  • 01:17 siren on
  • 01:17 the pigeon shook itself off and flew away
Well, you don’t have to delve into such details for long; it’s immediately clear what happened. The same is in development. It’s very cool when you can tell from the recordings what happened. Now you may be remembering debugging, because you can debug everything. But no. You went home, and at night everything broke, there is nothing to debug: you need to understand why it broke and fix it. This is where the logs come into play, the history of everything that happened overnight. During the course of the article, I suggest you think about what is one of the most famous loggers (not really a logger, more like monitoring), which everyone who listens (watches) the news has probably heard of? Thanks to him, some events are restored. Now let's get serious. Logging in Java is the process of recording any events that occur in the code. It is your responsibility as a programmer to write down what your code did, because then these logs will be given to you for analysis. If everything is done well, then any bug will be sorted out and fixed very quickly. Here, I probably won’t delve into what kind of loggers there are. In this article we will limit ourselves to the simple java.util.Logger: it is more than enough for getting to know each other. Each log entry contains date-time, event level, message. The date and time are entered automatically. The event level is chosen by the message author. There are several levels. The main ones are info, debug, error.
  • INFO - usually these are information messages about what is happening, something like a history by date: 1915 - something happened, 1916 - something else.
  • DEBUG - describes the events of a particular moment in more detail. For example, the details of a battle in history are at the debug level." Commander Takoytovich advanced with his army towards the village of Selovicha ."
  • ERROR - errors that occur are usually written here. You've probably noticed that when you wrap something in try-catch, the block catchis substituted with e.printStacktrace(). It only outputs the entry to the console. Using a logger, you can send this entry to the logger (haha), you get the idea.
  • WARN - warnings are written here. For example, an overheating light in a car. This is just a warning, and it is better to change something, but this is not a breakdown. When the machine breaks down, then we will log with the ERROR level.
We've sorted out the levels. But don't worry: the line between them is very thin - not everyone can explain it. Plus, it may differ from project to project. A senior developer will explain to you at what level and what to log. The main thing is that these records are enough for you for future analysis. And this is understood on the fly. Next are the settings. Loggers can be told where to write (to the console, file, jms or somewhere else), and specify the level (info, error, debug...). An example of settings for our simple logger looks like this:
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 this case, everything is configured so that the logger writes to a file and to the console at the same time. In that case? if something is erased in the console, plus it’s easier to search by file. INFO level for both. A name pattern is also specified for the file. This is a minimal config that allows you to write to both the console and a file at once. java.util.logging.FileHandler.appendset to true so that old entries in the file are not erased. An example of use is this (without comments, the logger comments on itself):
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);
        }
    }
}
This is not the best example, I took the one that was at hand. Example 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)
Here I want to focus on the notes:
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Размер equals 3
апр 19, 2019 1:10:14 AM generics.Main main
INFO: Получим первый элемент
This entry is quite useless and not informative. Like the error entry:
WARNING: что-то пошло не так
You shouldn’t write this: it’s a log for the sake of a log, it will only get in the way. Try to always write meaningful things. I think this is enough to stop using it System.out.printlnand move on to adult toys. It java.util.logginghas disadvantages. For example, the levels that I described above are not here, but they are in most used loggers. I chose it for this article java.util.loggingbecause it does not require additional manipulations with the connection. I will also note that it can be used LOGGER.infoinstead of LOGGER.log(Level.INFO... One of the disadvantages already appears here: LOGGER.log(Level.WARNING,"что-то пошло не так" , e);- it allows you to transmit a message and an object Exception, the logger itself will write it down beautifully. At the same time, LOGGER.warning("");it only receives a message, i.e. The exception cannot be passed, you have to translate it into a string yourself. I hope this example is enough to get acquainted with Java logging. Then you can connect other loggers (log4j, slf4j, Logback...) - there are many of them, but the essence is the same^ to record the history of actions. Official tutorial
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION