Wednesday, October 04, 2006

Log4j: Tipps and Tricks

Rolling log files w/o overwriting

When using the normal file appender, the log files grows indeterminately. When using the rolling file appender, the existing log file (of the current day) is overwritten on application restart. It should be possible to
  • use a file for each day the app is running
  • either append to the day's file, create a new file, or rename the day's file
before overwriting if the app is restarted.

Don't overwrite rolling file on startup

JBoss rolling file appender uses Append=false - this can be sensibly changed to not overwrite existing log files on startup Note: replace (, ), /) with the right XML parentheses.
(appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender"\)
(errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/)
 (param name="File" value="${jboss.server.log.dir}/server.log"/)
 (param name="Append" value="true"/)

 (!-- Rollover at midnight each day --)
 (param name="DatePattern" value="'.'yyyy-MM-dd"/)
[...]
It also works with the properties-based file:
log4j.appender.file.Append=true

Rename files before startup

When starting an app/server always with the same script, the log file can be moved out of the way before startup.

Rename files on startup

In the following code, the last log file is renamed to a date based pattern. Yet the pattern is based on the current date (the restart timestamp), not the original log file creation or its last entry. To use this, the logger must not be statically initialized in the main class, but after moving the file.
try {
String date = new SimpleDateFormat("yyyy.MM.dd-HH.mm").format(new Date());
// if log file already open, moving no longer possible ...
File file = new File(LOG4J_FILE_NAME+".log");
if (file.exists())
  file.renameTo(new File("LOG4J_FILE_NAME-"+date+".log"));
mLogger = Logger.getLogger(CurrentClass.class);
}
catch (IOException e) {...}
It might be possible to configure the name of the file the logger should use in the code, instead of the configuration file. This allows to set a filename manually (date pattern based) *before* the first log statement is printed and the log file thus opened. This might also require an explicit call to the ...Configurator. It will probably not work in combination with RollingFileAppender. Maybe there is no way around writing an appender (derived from RollingFileAppender) of our own?

DatedFileAppender

DatedFileAppender works in the same manner as the Tomcat FileLogger. Contrary to DailyRollingFileAppender shipping with log4j, log file names generated by DatedFileAppender always contain today's date. While this distinction seems minor, it means you can reliably copy, compress, remove or manipulate a day's log file shortly after midnight. With the DailyRollingFileAppender, a day's log file is not renamed until the first message is logged some time after midnight. http://minaret.biz/tips/datedFileAppender.html

Different log levels for stdout and file

Is there a possibility of using different log levels in log4j when logging onto stdout, and when logging into a file? The PropertiesConfigurator obviously does *not* support this, yet the xml configurator does. JBoss does this in its log4j.xml. From the log4j.dtd, no reference to such possibilities can be found. JBoss does the following in its xml configuration file:
(appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender")
(errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/)
(param name="Target" value="System.out"/)
(param name="Threshold" value="INFO"/)
[...]
This also works with the properties configuration file:
log4j.appender.stdout.Threshold=INFO

No comments: