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?



{ 40 comments… read them below or add one }
Thanks a lot Veera.
U made a quite difficult things to understand with simplicity.
Thanks for too simple yet power concept. !!
you are welcome!
Thanks a lot Veera.
U made a quite difficult things to understand with simplicity.
you are welcome.
Simple and informative. Thanks
Thanks Veera, for the simple and yet clear info.
Thanks Veera Your tutorial is too good and easy to digest!! You’re great!!!
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
Hi Radhika,
Can you please elaborate a bit more on your requirement?
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.
Hi matt,
I’m glad that this article saved your time!
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
//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
Genius!
Now it’s passing well!!!
Thank you!!!
Cool. Thanks. It helped.
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.
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.
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
What’s the issue that you are facing? Can you elaborate more on that?
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.
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!
Good Work..Helped me !!
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
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
can you please share your log4j.properties file and let me know for what appenders the log messages are missing?
This is very helpful, and saves lot of time for newbees. Thank you for the effort
Hi there,
thank you very much for this article!
Best regards
Nick
These are some really great entries. keep the good work going
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!
Hello,
for anyone wondering what ‘category’ is used for because in his files only ‘logger’ is used:
http://hanuska.blogspot.com/2007/02/log4j-logger-vs-category.html
(In short: category is deprecated, logger is a subclass of category. Use logger.)
Great article, though!
Thanks – Mathias
Hi veera,
Excellent explanation… Understood the concept very easily….
Keep writing on more topics…
Thanks.
welcome.
Hi Veera,
I am struggling with the following issues:
1. There are two sars such that one depend upon other
2. There is common logger for appending logs to the log files of both of these sars say for : com.broadridge.logger.BRLogger
</category
3. Here MQM_SERVICE depend upon BPRIOR
4. The problem is : I am getting the log files of both of these sars exactly same.
Thanks, for your quick reply in advance!!
Am not able to understand the issue here with the information provided… Can you mail me more details and I’ll see what I can do..
Veera,
Actually i solved the issue and the problem was : two different log files populated with same content. The issue was compatibility problem with jboss 5.1.0ga such that the filter class used for logging was not compatible to the given version of jboss.Thus, once i changed the filter class the issue get resolved.
excellent work !!!
i have a requirement, hopefully someone will show me a way. i searched a lot, couldnt find a solution
in my application i have 200 packages. in one package , in some classes i have log stements in TRACE level. i need to have a file appender to log only these TRACE level statements coming from this one package. i dont want to log DEBUG, INFO, ERROR, FATAL messages in this log file. i want just TRACE. how can i do it ?
i tried like this. created a category and set the threshold to TRACE. then i tried to suppress the 199 packages to FATAL. But thats lot of work listing 199 package names. unfortunately there is no wild card support in package names in log4j
thanks
bala
Thanks a lot Veera ! I have been trying a lot to skip the console logging done in my parent log4j.xml class.. Your blog helped a lot…thanks again !!
Siby
HI,
veera ,
Good ,and well explained ,thanks for your valuable blog.Are you familiar with slf4j ,can the same be done for slf4j.
if yes please help me by explaining that.i’m working in spring mvc is there any way for logging in spring ,while checking the log we are getting lots and lots of spring log while using slf4j.what to avoid spring loggings.
thanks in advance
Excellent article, well written and easy to understand.
{ 2 trackbacks }