Java Logging

Java allows us to create and capture log messages and files through the process of logging.

In Java, logging requires frameworks and APIs. Java has a built-in logging framework in the java.util.logging package.

We can also use third-party frameworks like Log4j, Logback, and many more for logging purposes.


Java Logging Components

The figure below represents the core components and the flow of control of the Java Logging API (java.util.logging).

The flow of control of Java Logging API
Java Logging

1. Logger

The Logger class provides methods for logging. We can instantiate objects from the Logger class and call its methods for logging purposes.

Let's take an example.

Logger logger = Logger.getLogger("newLoggerName");

The getLogger() method of the Logger class is used to find or create a new Logger. The string argument defines the name of the logger.

Here, this creates a new Logger object or returns an existing Logger with the same name.

It is a convention to define a Logger after the current class using class.getName().

Logger logger = Logger.getLogger(MyClass.class.getName());

Note: This method will throw NullPointerException if the passed name is null.

Each Logger has a level that determines the importance of the log message. There are 7 basic log levels:

Log Level (in descending order) Use
SEVERE serious failure
WARNING warning message, a potential problem
INFO general runtime information
CONFIG configuration information
FINE general developer information (tracing messages)
FINER detailed developer information (tracing messages)
FINEST highly detailed developer information(tracing messages)
OFF turn off logging for all levels (capture nothing)
ALL turn on logging for all levels (capture everything)

Each log level has an integer value that determines their severity except for two special log levels OFF and ALL.


Logging the message

By default, the top three log levels are always logged. To set a different level, we can use the following code:

logger.setLevel(Level.LogLevel);

// example
logger.setLevel(Level.FINE);

In this example, only level FINE and levels above it are set to be logged. All other log messages are dropped.

Now to log a message, we use the log() method.

logger.log(Level.LogLevel, "log message");

// example
logger.log(Level.INFO, "This is INFO log level message");

There are shorthand methods for logging at desired levels.

logger.info( "This is INFO log level message");
logger.warning( "This is WARNING log level message");

All log requests that have passed the set log level are then forwarded to the LogRecord.

Note: If a logger's level is set to null, its level is inherited from its parent and so on up the tree.


2. Filters

A filter (if it is present) determines whether the LogRecord should be forwarded or not. As the name suggests, it filters the log messages according to specific criteria.

A LogRecord is only passed from the logger to the log handler and from the log handler to external systems if it passes the specified criteria.

// set a filter
logger.setFilter(filter);

// get a filter
Filter filter = logger.getFilter();

3. Handlers(Appenders)

The log handler or the appenders receive the LogRecord and exports it to various targets.

Java SE provides 5 built-in handlers:

Handlers Use
StreamHandler writes to an OutputStream
ConsoleHandler writes to console
FileHandler writes to file
SocketHandler writes to remote TCP ports
MemoryHandler writes to memory

A handler can pass the LogRecord to a filter to again determine whether it can be forwarded to external systems or not.

To add a new handler, we use the following code:

logger.addHandler(handler);

// example
Handler handler = new ConsoleHandler();
logger.addHandler(handler);

To remove a handler, we use the following code:

logger.removeHandler(handler);

// example
Handler handler = new ConsoleHandler();
logger.addHandler(handler);
logger.removeHandler(handler);

A logger can have multiple handlers. To get all the handlers, we use the following code:

Handler[] handlers = logger.getHandlers();

4. Formatters

A handler can also use a Formatter to format the LogRecord object into a string before exporting it to external systems.

Java SE has two built-in Formatters:

Formatters Use
SimpleFormatter formats LogRecord to string
XMLFormatter formats LogRecord to XML form

We can use the following code to format a handler:

// formats to string form
handler.setFormatter(new SimpleFormatter());

// formats to XML form
handler.setFormatter(new XMLFormatter());

LogManager

The LogManager object keeps track of the global logging information. It reads and maintains the logging configuration and the logger instances.

The log manager is a singleton, which means that only one instance of it is instantiated.

To obtain the log manager instance, we use the following code:

LogManager manager = new LogManager();

Advantages of Logging

Here are some of the advantages of logging in Java.

  • helps in monitoring the flow of the program
  • helps in capturing any errors that may occur
  • provides support for problem diagnosis and debugging
Did you find this article helpful?