3.1 List of event levels

Logging is the process of recording any events that occur while the program is running. Your duty as a programmer is record everything importantbecause then, when productionthere are strange and / or serious errors, you will have nothing else besides these logs.

Any error will be eliminated many times faster if you have all the information about it and about all the history of the calls. But a simple conclusion follows from here - to log everything in general: calls of all methods, values ​​of all parameters.

This is also not an option - too much information is just as bad as too little. We need smart logging. Made by man for man. And here we come to the first fact about logging - all entries in the log are divided into categories even at the time of their creation.

The programmer, when writing an event to the log, must decide for himself how important this information is. The severity level of the event is chosen by the author of the message. There log4jare 5 levels of logged information importance:

  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL

Below we will tell about them in more detail.

3.2 DEBUG

The level DEBUGis considered the least important. Information that is written to the log with this level of importance is only needed during application debugging. In order to log information needed during debugging, the method is used debug().

Example:

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.complete();
            return true;
        } catch (Exception e) {
            logger.error("Unknown error", e);
            return false;
        }
    }
}

Pay attention, the method debugis at the very beginning of the method (the method has not had time to do anything yet) and writes the value of the variable passed to the method to the log. This is the most common use case for the method debug().

3.3 INFO and WARN

The next two levels are INFOand WARN. There are two methods for them - info()and warn().

The level INFOis used simply for informational messages: this and that happens. When you start parsing an error in the log, it can be very useful to read its background. The method is perfect for this info().

The level WARNis used to write warnings (from the word warning ). Usually, with this level of importance, information is written that something went wrong, but the program knows what to do in this situation.

For example, in the process of writing a file to disk, it turned out that such a file already exists. Here the program can log a warning (warning), but show the user a dialog box and offer to select a different file name.

Example:

class FileManager {
    private static final Logger logger = LoggerFactory.getLogger(FileManager.class);

    public boolean saveFile(FileData file) {
        logger.info(“save the file ” + file.getName());
        boolean resultOK = SaveUtils.save(file);
        if (resultOK) return true;

        logger.warn(“file writing problem ” + file.getName());
        String filename = Dialog.selectFile();
        boolean result = SaveUtils.save(file, filename);
        return result;
    }

3.4 ERROR and FATAL

Finally, the two most important logging levels are ERRORand FATAL. For them, there are also special methods with the same names: error()and fatal().

They also decided to divide errors into two categories - ordinary errors and fatal errors . A fatal error most often results in an application crash (for desktop applications) or a web service crash (for web applications).

Another good example is the Windows operating system. If your program just crashed, then from the point of view of the operating system, this is Error. And if the operating system itself has fallen and you see the Windows blue screen of death, then this is already Fatal error.

In Java applications, events Errorare most often Fatalassociated with raised exceptions. Example:

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.complete();
            return true;
        } catch (Exception e) {
            logger.error("Unknown error", e);
            return false;
        }
    }
}

3.5 What to log

Of course, it's not worth logging everything in a row. In most cases, this sharply worsens the readability of the log, and after all, the log is written in the first place in order to be read.

In addition, you can not write various personal and financial information to the log. Now with this strictly and easily you can run into fines or lawsuits. Sooner or later, such a log will leak to the side and then there will be no problems.

So what should be logged?

First, you need to log the start of the application . After the application has started, it is recommended to log its operation mode and various important settings - this will make it easier to read the log in the future.

Secondly, you need to log the status of all third-party services with which your application works: mailing systems, any external services. At a minimum, you need to secure the moment of connection to them to make sure that they work properly.

Thirdly, all exceptions need to be logged . If they are expected, then information on them can be written compactly. Complete information about exceptions gives 50%-80% of important information when searching for a bug.

You also need to log the application shutdown . The application must terminate normally and not throw dozens of errors into the log. Often in this place you can find stuck tasks, problems with the thread pool, or problems with deleting temporary files.

Be sure to log everything related to security and user authorization . If a user tries to login or reset their password 10 times in a row, this information should be reflected in the logs.

Log as much information as possible about asynchronous tasks - exceptions are often lost in such threads. For an asynchronous task, be sure to log its start and end. Successful completion should be logged in the same way as a problematic one.

What else? Launching timed tasks, launching stored tasks SQL-procedures, synchronizing data, everything related to distributed transactions. I think that's enough for a start. You will add to this list in the future.