The post covers a simple approach that can be used with a
FileAppender
by using a timestamp as part of the log file name injected from a system property.Two different samples are provided. One can be used when the Java program is launched directly from a shell (manually or via a scheduler) and the other when launching it as an Ant task.
The log4j configuration is the same for both scenarios and is shown right below:
# A sample Log4j configuration demonstrating how to create a new log file # at each program start. # Created: Apr 6, 2016 by Vitali Tchalov log4j.rootLogger=info, stdout, logfile log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout= org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern= %5p [%t] (%d) %c - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=logs/job_${log.timestamp}.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d [%t] %5p %c - %m%n
The configuration uses a custom system property
log.timestamp
to append a unique (with a second precision) suffix to the log file name.The way the property is set depends on how the Java program is launched.
Scenario 1 - when starting a plain regular Java program by directly invoking the java executable
1. Add a system property in a static block of the main class (i.e. the launching class with the
main(String[])
method) prior to referencing any Logger
.static { System.setProperty("log.timestamp", new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())); }
Below is a complete class source code:
package com.forms2docx; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.log4j.Logger; /** * A sample class to demonstrate a technique to configure Log4j to create a new log file at each program run. * * To compile the sample program, specify the absolute path to a log4j.jar file, for example: * javac -d bin -cp ".;./lib/log4j-1.2.17.jar;" ./com/forms2docx/*.java * * To run with the static block that programmatically adds the log.timestamp property: * java -cp ".;./bin;./lib/log4j-1.2.17.jar;" com.forms2docx.Log4jNewFile * * To run with the log.timestamp property passed from the command line: * java -cp ".;./bin;./lib/log4j-1.2.17.jar;" -Dlog.timestamp=$(date +"%Y%m%d_%H%M%S") com.forms2docx.Log4jNewFile * * @author Vitali Tchalov */ public class Log4jNewFile { static { System.setProperty("log.timestamp", new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())); } private static final Logger logger = Logger.getLogger(Log4jNewFile.class); public static void main(String[] args) { logger.info(String.format("Job has started at %s.", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))); logger.info("The sample demonstrates how to configure Log4j to create a new file on every program run."); } }
To execute this program, compile and run from a shell:
java -cp ".;./bin;./lib/log4j-1.2.17.jar;" com.forms2docx.Log4jNewFile
Of course, a log4j jar file must reside on the classpath.
If modifying the source is not possible or desirable for whatever reason, it is also possible to supply the system property on the command line, like this:
java -cp ".;./bin;./lib/log4j-1.2.17.jar;" -Dlog.timestamp=$(date +"%Y%m%d_%H%M%S") com.forms2docx.Log4jNewFile
The command line above is for a UNIX system (e.g. Linux, Mac). It might be possible to adapt it for Windows too but formatting a date and time to a short format would be very cumbersome in Windows.
Scenario 2 - starting a Java program (job) as an Ant task.
These steps are required for launching a Java program as an Ant task:
1. Include
<tstamp />
to the Ant build file2. Add the following to the java task:
<sysproperty key="log.timestamp" value="${DSTAMP}_${TSTAMP}" />
Note, the
DSTAMP
and TSTAMP
are standard variables defined by Ant.An example of an Ant build file to launch a Java program as an Ant task: (requires a log4j.jar file on the classpath as well as Ant in the PATH):
<project name="Launch Java Ant task sample" basedir="." default="info"> <echo message="Launching Java Ant task sample..." /> <tstamp/> <target name="info"> <echo message="The runJob Java task demonstrates creating a new log file at each run."/> </target> <target name="runJob" description="Demonstrates a new log file per each run."> <java classname="com.forms2docx.Log4jNewFile" fork="true" failonerror="true"> <jvmarg value='-Dlog4j.configuration=file:"${basedir}/log4j.properties"' /> <jvmarg value='-server' /> <sysproperty key="log.timestamp" value="${DSTAMP}_${TSTAMP}" /> <classpath> <pathelement location="${basedir}/bin"/> <fileset dir="${basedir}/lib"> <include name="*.jar" /> </fileset> </classpath> </java> <echo message="Task completed."/> </target> </project>Note that by default, the
TSTAMP
is in "HHmm" format. When this precision is not sufficient, then a custom property with a required format can be added.For example:
<tstamp> <format property="tstamp-sec" pattern="HHmmss"/> </tstamp>
Then the
sysproperty
in the java
task would look like this:<sysproperty key="log.timestamp" value="${DSTAMP}_${tstamp-sec}" />/* --- end --- */
No comments:
Post a Comment