Log4j

log4j – Additivity Property Example

In this post, we are going to discuss about log4j additivity 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 Loggers (Logger hierarchy)

The first and foremost advantage of any logging API over plain System.out.println statements resides in its ability to disable certain log statements while allowing others to print unhindered. Loggers are named entities. Logger names are case-sensitive and follow the Named Hierarchy Rule:

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 which is an immediate ancestor of a descendant is said to be a parent logger and the immediate descendant is said to be a child logger.

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

  • It always exists
  • Its level cannot be set to null
  • It cannot be retrieved by name

1.2 What are log4j appenders?

log4j allows logging requests to print to multiple destinations. In log4j speak an output destination is called an appender. Currently, appenders exist for the console, files, Swing components, remote socket servers, JMS, NT Event Loggers, and remote UNIX Syslog daemons. Log4j allows attaching multiple appenders to any logger. Appenders can be added to and removed from a logger at any time. A logger can make use of one and only one level.

1.3 Appender Additivity

Each enabled logging request for a given logger will be forwarded to all the appenders in that logger, as well as the appenders higher in the hierarchy. In other words, appenders are inherited additively from the logger hierarchy. For example, if a console appender is added to the root logger, then all enabled logging requests will at least print on the console. If in addition a file appender is added to a logger, say L, then enabled logging requests for L and L’s children will print on a file and on the console. It is possible to override this default behavior so that appender accumulation is no longer additive by setting the additivity flag to false.

The rule governing appender additivity is summarized below:

The output of a log statement of some logger L is forwarded to all the appenders in L and its ancestors. This is the meaning of the term appender additivity.

However, if an ancestor of logger L, say P, has its additivity flag set to false, then L’s output will be directed to all the appenders in L and it’s ancestors up to and including P but not the appenders in any of the ancestors of P.

Loggers have their additivity flag set to true by default.

1.4 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 appender additivity.

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.log4jadditivity.foo=INFO, stdout
log4j.additivity.com.javacodegeeks.examples.log4jadditivity.foo=false

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

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.log4jadditivity.foo" additivity="false">
		<level value="INFO" />
		<appender-ref ref="console" />
	</logger>
	
	<!-- Bar package -->
	<logger name="com.javacodegeeks.examples.log4jadditivity.bar" additivity="false">
		<level value="WARN" />
		<appender-ref ref="console" />
	</logger>
	
	<!-- Root logger option -->
	<root>
		<level value="DEBUG" />
		<appender-ref ref="console" />
	</root>
</log4j:configuration>

Notice how we set the additivity property to false for both loggers.

2. Executing some code

FooBean.java

package com.javacodegeeks.examples.log4jadditivity.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.log4jadditivity.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.log4additivity;

import org.apache.log4j.Logger;

import com.javacodegeeks.examples.log4jadditivity.bar.BarBean;
import com.javacodegeeks.examples.log4jadditivity.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.log4additivity.App should be similar to:

2014-09-01 18:12:01 DEBUG App:15 - Hello there from App class!
2014-09-01 18:12:01 INFO  FooBean:11 - Hello there from FooBean class!
2014-09-01 18:12:01 WARN  BarBean:11 - Hello there from BarBean class!

3. Download the Eclipse project of this tutorial:

This was an example of how to set the logger additivity for the log4j library.

Download
You can download the full source code of this example here : log4jadditivity.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