Configurability

The most important reason is configurability and ease of use. We use logging to record information about the operation of code. This is not the core functionality of the application but is inevitable to have a program that can be operated. There are messages we print out to the log, which can be used by the operating personnel to identify environmental issues. For example, when an IOException is thrown and it gets logged, the operation may look at the logs and identify that the disk got full. They may delete files, or add a new disk and extend the partition. Without the logs, the only information would be that the program does not work.

The logs are also used many times to hunt down bugs. Some of the bugs do not manifest in the test environment and are very difficult to reproduce. In such a case, the logs that print out detailed information about the execution of the code are the only source of finding the root cause of some error.

Since logging needs CPU, IO bandwidth, and other resources, it should be carefully examined what and when to log. This examination and the decisions could be done during programming, and as a matter of fact, that is the only possibility if we used System.out.println for logging. If we need to find a bug, we should log a lot. If we log a lot, the performance of the system will go down. The conclusion is that we have to log only if it is needed. If there is a bug in the system that cannot be reproduced, the developers ask the operation to switch on debug logging for a short period. Switching on and off different parts of logging is not possible when System.out.println is used. When the debug level log is switched on, the performance may go down for a while, but at the same time, the logs become available for analysis. At the same time, the analysis is simpler when we have to find the log lines that are relevant (and you do not know beforehand which are relevant) if there is a small (a few hundred megabytes log file) rather than a lot of 2-GB compressed log files to find the lines in.

Using a log framework, you can define loggers that identify the source of the log messages and log levels. A string usually identifies the logger, and it is a common practice to use the name of the class from which the log message is created. This is such a common practice that the different log frameworks provide factory classes that get the class itself, instead of its name, to get a logger.

The possible logging levels may be slightly different in different logging frameworks, but the most important levels are as follows:

  • FATAL: This is used when the log message is about some error that prevents the program from continuing its execution.
  • ERROR: This is used when there is some severe error, but the program can still go on functioning although, probably, in some limited manner.
  • WARNING: This is used when there is some condition that is not a direct problem but may later lead to an error if not attended. For example, the program recognizes that a disk is near full, some database connections answer within limits but close to the timeout value, and similar situations.
  • INFO: This is used to create messages about normal operations that may be interesting to operate and are not an error or warning. These messages may help the operation to debug the operational environment settings.
  • DEBUG: This is used to log information about the program that is detailed enough (hopefully) to find a bug in the code. The trick is that when we put the log statement into the code, we do not know what bug it could be. If we knew, we better fixed it.
  • TRACE: This is even more detailed information about the execution of the code.

The log frameworks are usually configured using some configuration file. The configuration may limit the logging, switching off certain levels. In a normal operational environment, the first three levels are usually switched on, and INFO, DEBUG, and TRACE are switched on when really needed. It is also possible to switch on and off certain levels only for certain loggers. If we know that the error is certainly in the GameSessionSaver class, then we can switch on the DEBUG level only for that class.

Log files may also contain other information that we did not directly code and would be very cumbersome to print to the standard output. Usually, each log message contains the precise time when the message was created, the name of the logger, and, many times, the identifier of the thread. Imagine if you were forced to put all this to each and every println argument; you would probably soon write some extra class to do that. Don't! It has already been done professionally: it is the logger framework.

Loggers can also be configured to send the message to different locations. Logging to the console is only one possibility. Logging frameworks are prepared to send messages to files, database, Windows Event Recorder, syslog service, or to any other target. This flexibility, which message to print, what extra information to print, and where to print is reached by separating the different tasks that the logger framework does into several classes following the single responsibility principle.

The logger frameworks usually contain loggers that create the logs, formatters that format the message from the original log information, many times, adding information such as thread ID and time stamp, and appenders that append the formatted message to some destination. These classes implement interfaces defined in the logging framework and nothing but the size of the book stops us from creating our own formatters and appenders.

When a log is configured, the appenders and formatters are configured, given the class that implements them. Therefore, when you want to send some logs to some special destination, you are not limited to the appenders that are provided by the authors of the framework. There are a lot of independent open-source projects for different logging frameworks providing appenders for different targets.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.196.244