Log4J

18 Aug 2008
Posted by cgp

Everyone seems to use log4j. The configuration always seemed a bit cryptic to me.

For instance, when I had the following entry:


log4j.rootLogger=debug, stdout, daily

Nothing logged to the debug "logger"! It had to come after stdout in the list as such:


log4j.rootLogger=warn, stdout, daily, debug

The reason for this is simple! The first parameter in this list specifies the logging threshhold for each of the appenders attached to the rootLogger. If you specify a valid value ("debug", "info", "warn", "error", "fatal"), it uses that as a threshhold. If you do not specify a valid threshhold value, it assumes a default (I'm not sure what the default is)

So, specifying the names stdout/daily/debug for log4j.rootLogger creates appenders by that name under the rootLogger. Options are set for each appender as such:


log4j.appender.stdout=....
log4j.appender.daily=....
log4j.appender.debug=....
...

The root of those entry declares the class to be used (each has a different purpose):

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.daily=org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug=org.apache.log4j.RollingFileAppender

And then, specify settings of each of those is just a matter of knowing the options available to the class:

log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=%d{h:mm:ssa} %5p (%F:%L) - %m%n
log4j.appender.debug.threshold=debug
log4j.appender.debug.MaxFileSize=1024KB
log4j.appender.debug.MaxBackupIndex=1
log4j.appender.debug.File=/apps/decommerce_be/logs/decommerce_be_debug.log

Pretty nifty. You can use XML to setup these configs too, to make it clear which appender owns each setting.

One other thing, in addition to being able to specify a logger under log4j.rootLogger, you can specify a logger like so:


log4j.logger.EJB.Logger=info,EJB

This will set the default threshhold and also specify the name of the appender (the logger).

The advantage of this being, that you can configure it to take only a particular subset of log messages (such as for EJB)

Configuration remains the same.

log4j.appender.EJB=org.apache.log4j.DailyRollingFileAppender
log4j.appender.EJB.File=${LOCLOG}/logs.txt

Additivity sets whether logs which went to that particular log will appear in the root log:


log4j.additivity.EJB.Logger=false

So, the only thing that confuses me here is, being that this is not set against any particular class, doesn't this mean ALL logs will not be sent to the root logger?

This seems like it would work, and make more sense:
You can also set a logger for a particular class, simply by specifying the class after logger:

log4j.logger.com.cgpsoftware=debug,cgpLogs
log4j.additivity.com.cgpsoftware=false
log4j.appender.cgpLogs=org.apache.log4j.DailyRollingFileAppenderExt

Now logs from com.cgpsoftware should appear in the appender log from this entry, but not in the root log (according to what I understand.

References