Architecture & DesignLearn the Basics of Java Logging

Learn the Basics of Java Logging

Java incorporated a logging API library as a part of its framework from JDK 1.4. Today, this is a built-in support from Java. However, this library is customizable and extensible in the sense that we can use one or more alternate logging solutions provided by third party libraries. Although these third-party solutions have a different approach to create log data, they ultimately share the same goal of logging messages from application runtime. This article explores the basics of logging and shows how it may be used in a Java program.

Java Logging

A log usually means maintenance of some sort of record. From the perspective of programming, it is a process of writing messages in a log file during program execution. Persisted message logs are referred, typically by the programmer, to collect certain runtime statistical information that, when analysed, can reveal unforeseen situations. In fact, there can be numerous distinct reasons why logging is used and this is just one of them. According to the Java API documentation, there four primary uses of logging:

  • For problem diagnosis by end users and system administrators.
  • It is convenient for field service engineers to diagnose the problem from logged messages and fix it quickly.
  • Development organization can trace the internal execution of a particular subsystem and analyse it.
  • Developers can debug the application under development by getting a quick insight on the underlying problem from logged messages.

Java API logging is designed in an inexpensive manner in the sense that it can be left as a residue even in a production application. This does not create much overhead to the efficiency of program execution. The API provides the mechanism to change the production of log messages dynamically so that the impact of logging can be minimized during operations that require maximum efficiency. The API consists of a number of classes and interfaces that can be customized by extending them. The entire logging API is packaged under java.util.logging. The classes and interfaces in this package provides the core logging facilities in Java.

Logging Levels

The urgency of logging in a Java program can be categorised into several levels. By leveling up and down, we can increase or decrease the cost of logging in a production application. This is how we control the efficiency of an application’s execution where it is necessary to log one or more of its events. This is achieved through a class called Level, which defines the importance of logging. The log level is ordered and specified by static integer constants, such as:

  • Level.ALL: All messages are logged, irrespective of importance
  • Level.OFF: Logging is turned off
  • Level.SEVERE: Indicates serious failure; must be logged
  • Level.WARNING: Indicates warning messages
  • Level.INFO: Runtime informational message
  • Level.CONFIG: Static configuration messages
  • Level.FINE: Tracing messages
  • Level.FINER: Detail tracing messages
  • Level.FINEST: Highly detailed tracing messages

Logging Components

We need a Logger instance to do any sort of logging in Java. This instance is responsible for logging data into a LogRecord. The LogRecord instances are used to pass logging requests between logging frameworks and individual log handlers. Java SE provides five type built-in handlers: StreamHandler, ConsoleHandler, FileHandler, SocketHandler, and MemoryHandler. One can, however, create a new handler or extend one of these as a customization. The handlers determine what to do with the log record; for example, it can be persisted in a local repository or pass it on to a server over a network. Java SE also includes two standard formatters: SimpleFormatter and XMLFormatter. These formatters are used to format a LogRecord into human readable format and standard XML format, respectively.

There is a LogManager class which keeps track of global logging information, such as a hierarchical namespace of named Loggers and a set of logging control properties from the configuration file. It is central to logging in Java and pretty much controls what to log, where to log, including other initialization details, and so forth.

A Simple Logging Example

Creating a Logger object is very simple. Here is a very simple code to illustrate that.

import java.util.logging.Logger;
public class App {
   private static Logger logger =
      Logger.getLogger(App.class.getName());
   public static void main(String[] args) {
      logger.info("This is a log message  !!!");
      logger.info("The name of the logger is " +
         logger.getName() + " nwhich is same as class name: "
            + App.class.getName());
   }
}

Logger objects are usually named using the String value of a hierarchical dot-separated namespace. In the preceding case, it is the same as the class name. The name, however, can be an arbitrary String value, but normally names are based upon the package name or the class name of the logged component. It also is possible to create an “anonymous” logger which will not be stored in the Logger namespace.

Logging to an External File Using XML Formatting

In the following code, the log messages are redirected to a file using FileHandler.

Note: The file will be created in the project directory.

The FileHandler can either write to a specified file, or it can write to a rotating set of files. The rotating set of files means that older files are named by adding 0,1,2 and so on into the base file name. The XMLFormatter is the default formatting used by FileHandler.

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class App {
   private static FileHandler fileHandler;
   private static Logger logger =
      Logger.getLogger(App.class.getName());
   public static void main(String[] args) throws
         IOException {
      fileHandler = new
         FileHandler(App.class.getName() + ".log");
      logger.setLevel(Level.ALL);
      logger.addHandler(fileHandler);
      logger.info("Log message redirected to a file");
      logger.info("The name of the logger is " +
         logger.getName() + 
            " nwhich is same as class name: "
            + App.class.getName());
   }
}

Logging to an External File Using Custom Formatting

We’ll tweak the following code a bit to customize the formatting of the message. This changes how the messages are written in the external file.

Note: Observe the log file contents about how the formatting has changed.
import java.io.IOException;
import java.util.logging.*;
public class App {
   private static FileHandler fileHandler;
   private static Logger logger =
      Logger.getLogger(App.class.getName());
   public static void main(String[] args) throws
         IOException {
      fileHandler = new
         FileHandler(App.class.getName() + ".log");
      logger.setLevel(Level.ALL);
      fileHandler.setFormatter(newCustomFormatter());
      logger.addHandler(fileHandler);
      logger.fine("Log message redirected to a file");
      logger.finer("The name of the logger is " +
         logger.getName());
      loggerfinest("This is same as class name: " +
         App.class.getName());
   }
   private static class CustomFormatter extends Formatter {
      private static final String format =
          "[%1$tF %1$tT] [%2$-4s] %3$s %n";
      public String format(LogRecord record) {
         returnString.format(format,
            record.getMillis(),
            record.getLevel().getLocalizedName(),
            record.getMessage());
      }
   }
}

That’s all. Do experiment with Java logging and try many other possibilities. Consult the Java API documents wherever necessary.

Other Logging Frameworks in Java

Sometimes, it is convenient to use a third-party logging framework, and there are quite a few popular ones to choose from. For example, the logging API provided by SLF4J uses a simple façade pattern is an abstraction layer that enables the application to be decoupled from its logging framework. Log4j is syntactically similar to built-in Java logging. It has a default configuration to output all log messages to the console. Logback is a successor of Log4j and is an extension of its predecessor. tinyLog is a lightweight logging framework that can be used with both Java and Android.

Conclusion

The logging process is designed to be simple and efficient in delivering what it is supposed to do. It is possible to quickly get started with Logging APIs in Java. The design is extensible and can be customised according to the developer’s end needs. This article is a glimpse into the basics of Java logging. Many intricate details are omitted for simplicity. Study the Java API Documentation and other appropriate documents for more details on this.

References

Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
This email address is invalid.
Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
This email address is invalid.

Latest Posts

Related Stories