home

Log4j Tutorial: Additivity – what and why?

August 13, 2009 · 32 comments

Hi there! I have created a small eBook explaining about Log4j logger and appenders. Download the Log4j PDF (200 KB)

In my last post about how to send log messages to different log files,  I’d promised to write about additivity. And, here is a post for keeping my promise. I hope that after reading my previous article, now you know how to configure Log4j for logging into multiple files using file appenders. But, there is a catch in that technique. To explain this clearly, consider this scenario:

You’ve configured a total of three appenders in your application. One for the package com.demo.moduleone and one for com.demo.moduletwo and one root logger for com.demo. The log4j configuration will look something like this (showing only the appender configuration, excluding other details)

log4j.category.com.demo.moduleone = INFO, moduleOneFileAppender
log4j.category.com.demo.moduletwo = INFO, moduleTwoFileAppender
log4j.rootLogger = INFO, rootFileAppender

The Log4j loggers are following hierarchies. ie, A log4j 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 log4j logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger.

So, as per the hierarchy, our rootFileAppender is the parent appender for both moduleOneFileAppender and moduleTwoAppender. So, all the log messages that are coming to the child appenders will be propagated to the parent appenders too. So, in our scenario, the log messages from the package com.demo.moduleone will be sent to the moduleOneFileAppender plus the rootFileAppender. The same applies to the com.demo.moduletwo also. This leads to write the same log message in two different location.

How to avoid this redundancy?

In order to avoid this redundancy, we can use Log4j additivity. Just set the additivity property of an Log4j logger to false and then the log messages which are coming to that logger will not be propagated to it’s parent loggers. So, our new Log4j configuration file would be:

log4j.category.com.demo.moduleone = INFO, moduleOneFileAppender
log4j.additivity.com.demo.moduleone = false
log4j.category.com.demo.moduletwo = INFO, moduleTwoFileAppender
log4j.additivity.com.demo.moduletwo = false
log4j.rootLogger = INFO, rootFileAppender

With the above configuration, the log messages from the com.demo.moduleone will go to the moduleOneAppender only and the rest of the log messages will go to the rootFileAppender.

Previous: How to send log messages to different log files?

Related Posts

{ 30 comments… read them below or add one }

Tanzy September 10, 2009 at 10:53 AM

Thanks a lot Veera.

U made a quite difficult things to understand with simplicity.

Reply

Raminder Singh October 19, 2009 at 7:00 PM

Thanks for too simple yet power concept. !!

Reply

Veera October 19, 2009 at 9:10 PM

you are welcome!

Reply

Tanzy November 13, 2009 at 11:03 PM

Thanks a lot Veera.

U made a quite difficult things to understand with simplicity.

Reply

Veera February 4, 2010 at 10:05 AM

you are welcome.

Reply

Chenna January 22, 2010 at 2:37 AM

Simple and informative. Thanks

Reply

Mubarak February 6, 2010 at 1:52 PM

Thanks Veera, for the simple and yet clear info.

Reply

Jisha February 11, 2010 at 8:07 PM

Thanks Veera Your tutorial is too good and easy to digest!! You’re great!!!

Reply

Radhika May 26, 2010 at 4:56 PM

Hi Veera,

Can you please help me in setting up multiple log files in the following scenario. I would want a particular package which is a common package to be logged in all other logs.

Thanks,
Radhika

Reply

Veera May 26, 2010 at 5:10 PM

Hi Radhika,

Can you please elaborate a bit more on your requirement?

Reply

matt July 24, 2010 at 3:58 PM

You have no idea how much time I’ve spent looking for this. I’m really grateful to find it here. Very succinctly and clearly explained, too. Thanks.

Reply

Veera July 24, 2010 at 4:35 PM

Hi matt,

I’m glad that this article saved your time!

Reply

Vika November 22, 2010 at 10:09 PM

Hello!

Your article is very helpful for me!
But I’m not sure that I realy understand where is my bug in log4j.properties, because it doesn’t work:

log4j.appender.journalisation=org.apache.log4j.RollingFileAppender
log4j.appender.journalisation.layout=org.apache.log4j.PatternLayout
log4j.appender.journalisation.layout.ConversionPattern=%d %5p (%F:%L) – %m%n
log4j.appender.journalisation.File=/srv/webedi/files/logs/journalisation.log
log4j.appender.journalisation.Encoding=UTF-8
log4j.appender.journalisation.MaxFileSize=10000KB
log4j.appender.journalisation.MaxBackupIndex=5

log4j.category.src.business.purge=INFO, journalisation
log4j.additivity.src.business.purge=false

log4j.appender.stdout=org.apache.log4j.RollingFileAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %5p (%F:%L) – %m%n
log4j.appender.stdout.File=/srv/webedi/files/logs/ft-webedi-2.log
log4j.appender.stdout.Encoding=UTF-8
log4j.appender.stdout.MaxFileSize=10000KB
log4j.appender.stdout.MaxBackupIndex=5

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %5p (%F:%L) – %m%n

log4j.rootLogger = INFO, stdout, console

I want to separate the logging for this directory: src.business.purge
The appender for this class: journalisation

Thank you for any responce, and forgive me my english, plz

Reply

Veera November 22, 2010 at 10:16 PM

//log4j.category.src.business.purge//

Is “src” a package? I guess it’s the source folder. Can you please remove the “src” and try with this one instead:

log4j.category.business.purge=INFO, journalisation
log4j.additivity.business.purge=false

Reply

Vika November 23, 2010 at 1:56 PM

Genius!

Now it’s passing well!!!

Thank you!!!

Reply

Nishant December 15, 2010 at 7:52 PM

Cool. Thanks. It helped.

Reply

Gayathri December 29, 2010 at 11:44 AM

Hi Veera,

How to exclude getting logs from particular file in the module ? Suppose say, com.demo.moduleone has file1, file2. I want to exclude file 1 logs. How it could be done. Please help me out in this.

Thanks.

Reply

Veera December 29, 2010 at 12:33 PM

Hi Gayatri,

I could think of two ways to achieve your requirement:

1. Simple way: Remove all log messages from the file in which you want to exclude log messages .
2. Write custom log appender class extending the FileAppender (example). In that appender, you may have to override the method “append” and write your logic to check the Class name from which log message is sent. If it matches your class name, then don’t write the log. Otherwise, write the log message.

After creating this appender, associate it with your package “com.demo.moduleone”.

NOTE: If you have this appender for your entire project, then it’ll impact the performance considerably.

Reply

koteswara December 30, 2010 at 1:11 PM

Hello!

Your article is very helpful for me!
But I’m not sure that I realy understand where is my bug in log4j.properties, because it doesn’t work:

## Root Level logger
log4j.rootLogger=INFO,A1

## Root level appender
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=C:\\opt\\logs\\app.log
log4j.appender.A1.Append=false
log4j.appender.A1.DatePattern=’.'yyyy-MM-dd-HH
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c.%m%n

log4j.category.org.hibernate.pretty.Printer=DEBUG,A1
log4j.category.org.hibernate.jdbc.ConnectionManager=INFO,A1
log4j.category.org.hibernate=INFO

# ADMIN cosnsole
log4j.appender.FIAdminFileAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FIAdminFileAppender.File=C:\\opt\\logs\\fiadmin.log
log4j.appender.FIAdminFileAppender.Append=false
log4j.appender.FIAdminFileAppender.DatePattern=’.'yyyy-MM-dd-HH
log4j.appender.FIAdminFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FIAdminFileAppender.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c.%m%n

log4j.category.com.ewp.services.fiadmin=DEBUG,FIAdminFileAppender
log4j.additivity.com.ewp.services.fiadmin=false
log4j.category.com.ewp.services.fiadmin.security=DEBUG,FIAdminFileAppender
log4j.additivity.com.ewp.services.fiadmin.security=false
log4j.category.com.ewp.core.service.util=DEBUG,FIAdminFileAppender
log4j.additivity.com.ewp.core.service.util=false
log4j.category.com.ewp.services.fiadmin.helper=DEBUG,FIAdminFileAppender
log4j.additivity.com.ewp.services.fiadmin.helper=false
log4j.category.com.ewp.core.service.ext.servicemethod.impl.aspects.impl=DEBUG,FIAdminFileAppender
log4j.additivity.com.ewp.core.service.ext.servicemethod.impl.aspects.impl=false
log4j.category.com.ewp.fiadmin=DEBUG,FIAdminFileAppender
log4j.additivity.com.ewp.fiadmin=false
log4j.category.com.ewp.data.access.manager.fiadmin=DEBUG,FIAdminFileAppender
log4j.additivity.com.ewp.data.access.manager.fiadmin=false

#WAP
log4j.appender.WAPINFileAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.WAPINFileAppender.File=C:\\opt\\logs\\wapin.log
log4j.appender.WAPINFileAppender.Append=false
log4j.appender.WAPINFileAppender.DatePattern=’.'yyyy-MM-dd-HH
log4j.appender.WAPINFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.WAPINFileAppender.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c.%m%n

log4j.category.com.obopay.wap=DEBUG,WAPINFileAppender
log4j.additivity.com.obopay.wap=false
log4j.category.com.ewp.utility=DEBUG,WAPINFileAppender
log4j.additivity.com.ewp.utility=false

Reply

Veera December 30, 2010 at 2:16 PM

What’s the issue that you are facing? Can you elaborate more on that?

Reply

Sanmuk February 21, 2011 at 3:01 PM

Hi Veera,

I am stuck with one log4j requirement. Please help me you have time.

We have one appender
log4j.logger.com.sankar.mukherjee.example1=DEBUG, EX1
log4j.appender.EX1=org.apache.log4j.RollingFileAppender

now we want a subpackage logging to go to a separate appender and not to the former
like
log4j.logger.com.sankar.mukherjee.example1.subexmple2=DEBUG, SE2
log4j.appender.SE2=org.apache.log4j.RollingFileAppender

will additivity work here, like if i say
log4j.logger.com.sankar.mukherjee.example1.subexmple2=DEBUG, SE2
log4j.additivity.com.sankar.mukherjee.example1.subexmple2=false
log4j.appender.SE2=org.apache.log4j.RollingFileAppender

Please advice.

Reply

Veera February 21, 2011 at 3:08 PM

Yes. Additivity will work for you in this case. With your configuration, the sub package log messages will go only to the SE2 appender and *not* to EX1!

Reply

Narasimha February 22, 2011 at 4:44 PM

Good Work..Helped me !!

Reply

SWATHI April 13, 2011 at 5:32 PM

Log messages are dispalying some times for selected locations but sometimes not displaying at all.how to know whether log messages are there for those locations and what is the pb log messages are not dispalying

Reply

swathi April 15, 2011 at 3:16 PM

Hi veera,

My task has to be resolved immediately.can u please reply my query
Log messages are displaying some times for selected locations but sometimes not displaying at all.how to know whether log messages are there for those locations and what is the pb log messages are not displaying

Reply

Veera April 15, 2011 at 9:49 PM

can you please share your log4j.properties file and let me know for what appenders the log messages are missing?

Reply

Harpreet May 6, 2011 at 11:33 PM

This is very helpful, and saves lot of time for newbees. Thank you for the effort

Reply

Nick Weaver May 12, 2011 at 7:57 PM

Hi there,
thank you very much for this article!
Best regards
Nick

Reply

Robin May 25, 2011 at 5:59 PM

These are some really great entries. keep the good work going

Reply

Matthew Mahon November 30, 2011 at 12:55 AM

Hello, I cannot disable logging to my console. Here is my log4j.properties:

#set up the root logger ( all logging will use this unless specifically overriden elsewhere in this file
log4j.rootLogger=info, R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller’s file name and line number.
#this outputs the log level – date/time – class specification and message to the console
log4j.appender.stdout.layout.ConversionPattern=[%p] – %d – %c{2} – %m%n

#Use the rollingFileAppender – this keeps a number of backup logs and
#deletes the oldest one when the number of backups is reached

log4j.appender.R=org.apache.log4j.RollingFileAppender

#The name of the log file is WebReporting.log it defaults to the WebReporting directory
log4j.appender.R.File=C:/Sandbox.miro/GOLD_12_2_RELEASE/4.2.0cp09/jboss-as/server/default/log/WebReports.log

#this sets the max file size for the log before it gets rolled over
log4j.appender.R.MaxFileSize=32000KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1

#these calls set the pattern for the log file – it adds the thread that called the logger
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%p] – %d – %t %c{2} – %m%n

Still in my console I see the following (which does not appear to be coming from my properties file):

22516 [main] ERROR com.asg.safari.webreports.ControlServlet – Mail send error
22518 [main] INFO com.asg.safari.webreports.ControlServlet – Successfully loade
d application settings. Storing in global context…
22518 [main] INFO com.asg.safari.webreports.ControlServlet – ASG-Safari Web Rep
orts 8.4.5.0
22567 [main] INFO com.asg.safari.webreports.ControlServlet – Initializing Globa
l Dictionary…
22568 [main] INFO com.asg.safari.webreports.ControlServlet – Activating GlobalD
ictionary.
22568 [main] INFO com.asg.safari.webreports.ControlServlet – Initializing Globa
l Dictionary…DONE.
22568 [main] INFO com.asg.safari.webreports.ControlServlet – Initializing Audit
Trail Manager…
22576 [main] INFO com.asg.safari.webreports.ControlServlet – Initializing Audit
Trail Manager…DONE
Shutdown complete

Any help you could provide would be appreciated!

Reply

Leave a Comment

{ 2 trackbacks }

Previous post:

Next post: