Log4j

log4j – Log Levels Example

In this post, we are going to discuss about log4j levels and how you configure them using both log4j.properties and log4j.xml files.

1. What is log4j?

log4j is a tool to help the programmer output log statements to a variety of output targets.

In case of problems with an application, it is helpful to enable logging so that the problem can be located. With log4j it is possible to enable logging at runtime without modifying the application binary. The log4j package is designed so that log statements can remain in shipped code without incurring a high performance cost. It follows that the speed of logging (or rather not logging) is capital.

At the same time, log output can be so voluminous that it quickly becomes overwhelming. One of the distinctive features of log4j is the notion of hierarchical loggers. Using loggers it is possible to selectively control which log statements are output at arbitrary granularity.

log4j is designed with three goals in mind: reliability, speed and flexibility. There is a tight balance between these requirements. We believe that log4j strikes the right balance.

log4j has three main components: loggers, appenders and layouts. These three types of components work together to enable developers to log messages according to message type and level, and to control at runtime how these messages are formatted and where they are reported.

1.1 What are log4j loggers?

Loggers are named entities. Logger names are case-sensitive and they follow the hierarchical naming rule:

Named Hierarchy

A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger.
For example, the logger named “com.foo” is a parent of the logger named “com.foo.Bar”. Similarly, “java” is a parent of “java.util” and an ancestor of “java.util.Vector”. This naming scheme should be familiar to most developers.

The root logger resides at the top of the logger hierarchy. It is exceptional in two ways:

  • It always exists
  • It cannot be retrieved by name

Loggers may be assigned levels. The set of possible levels, that is:

  • FATAL – The FATAL level is rarely used and usually implies the impending crash of the application or the relevant sub-component.
  • ERROR – The ERROR level is encountered more frequently, usually following a Java exception. Error conditions do not necessarily cause the application to crash and the application may continue to service subsequent requests.
  • WARN – The WARN level is indicative of minor problems caused by factors external to the application such as missing or inconsistent input parameters supplied by the user.
  • INFO – The INFO level is associated with significant events in the normal life cycle of the application.
  • DEBUG – The DEBUG level is associated with minor and frequently occurring but otherwise normal events.
  • TRACE – The TRACE Level designates finer-grained informational events than the DEBUG.

Loggers may be assigned levels. Onene of the big advantages of the log4j framework is that most loggers do not need to be assigned a level. This greatly reduces the time spent managing logging.

1.2 log4j – Configuration scripts

The log4j environment is fully configurable programmatically. However, it is far more flexible to configure log4j using configuration files. Currently, configuration files can be written Java properties (key=value) format or in XML.

Let’s see an example of how easy is to define levels in the configuration script.

log4j.properties

# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Root logger option
log4j.rootLogger=DEBUG, stdout

# Print only messages of level WARN or above in the package com.javacodegeeks.examples.log4levels.foo
log4j.logger.com.javacodegeeks.examples.log4levels.foo=INFO, stdout

# Print only messages of level INFO or above in the package com.javacodegeeks.examples.log4levels.bar
log4j.logger.com.javacodegeeks.examples.log4levels.bar=WARN, stdout

Here, he have three loggers

  1. A root logger with level set to DEBUG
  2. A logger for package com.javacodegeeks.examples.log4jlevels.foo with level set to INFO
  3. A logger for package com.javacodegeeks.examples.log4jlevels.bar with level set to WARN

We can accomplish the same using a XML configuration script

log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">

	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
		</layout>
	</appender>
	
	<!-- Foo package -->
	<logger name="com.javacodegeeks.examples.log4jlevels.foo">
		<level value="INFO" />
		<appender-ref ref="console" />
	</logger>
	
	<!-- Bar package -->
	<logger name="com.javacodegeeks.examples.log4jlevels.bar">
		<level value="WARN" />
		<appender-ref ref="console" />
	</logger>

	<!-- Root logger option -->
	<root>
		<level value="DEBUG" />
		<appender-ref ref="console" />
	</root>
</log4j:configuration>

That’s it! Now we can execute some code.

2. Executing some code

FooBean.java

package com.javacodegeeks.examples.log4jlevels.foo;

import org.apache.log4j.Logger;

public class FooBean {
	private static final Logger logger = Logger.getLogger(FooBean.class);
	
	public void sayHello() {
		logger.debug("Hello there from FooBean class!");
		
		logger.info("Hello there from FooBean class!");
	}
}

BarBean.java

package com.javacodegeeks.examples.log4jlevels.bar;

import org.apache.log4j.Logger;

public class BarBean {
	private static final Logger logger = Logger.getLogger(BarBean.class);

	public void sayHello() {
		logger.info("Hello there from BarBean class!");

		logger.warn("Hello there from BarBean class!");
	}
}

App.java

package com.javacodegeeks.examples.log4jlevels;

import org.apache.log4j.Logger;

import com.javacodegeeks.examples.log4jlevels.bar.BarBean;
import com.javacodegeeks.examples.log4jlevels.foo.FooBean;

public class App {
	private static final Logger logger = Logger.getLogger(App.class);

	public static void main(String[] args) {
		FooBean fooBean = new FooBean();
		BarBean barBean = new BarBean();

		logger.debug("Hello there from App class!");

		fooBean.sayHello();
		barBean.sayHello();
	}
}

The output of the command java com.javacodegeeks.examples.log4jlevels.App should be similar to:

2014-08-16 19:25:48 DEBUG App:15 - Hello there from App class!
2014-08-16 19:25:48 INFO  FooBean:11 - Hello there from FooBean class!
2014-08-16 19:25:48 INFO  FooBean:11 - Hello there from FooBean class!
2014-08-16 19:25:48 WARN  BarBean:11 - Hello there from BarBean class!
2014-08-16 19:25:48 WARN  BarBean:11 - Hello there from BarBean class!

Let’s quickly examine what we get

  • App class uses the root logger which has a level set to DEBUG.
  • FooBean class uses a logger which has a level set to INFO. Because the INFO level is one level before the DEBUG level, only the logging statement at level INFO is displayed.
  • BarBean class uses a logger which has a level set to WARN. Because the WARN level is two levels before the INFO level, only the logging statement at level WARN is displayed.

3. Download the Eclipse project of this tutorial:

This was an example of how to set the logging levels for the log4j library.

Download
You can download the full source code of this example here : log4jlevels.zip

Armando Flores

Armando graduated from from Electronics Engineer in the The Public University Of Puebla (BUAP). He also has a Masters degree in Computer Sciences from CINVESTAV. He has been using the Java language for Web Development for over a decade. He has been involved in a large number of projects focused on "ad-hoc" Web Application based on Java EE and Spring Framework.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button