The Apache Ant build tool is a great aid in automating builds and deployments. When the build fails, however, diagnosing the problem can be painful - especially if it only occurs intermittently. Logging details of the Ant build can therefore be useful.

By default Ant writes informational messages to the console. While this is usually sufficient for a successful build, more detail is often useful in the case of failed builds. Relying on the console output for information about the build has limitations – there might be too much output to fix in the console's buffer, or you might clear or close the console. The solution is to write Ant's output to a log file. This can be done using the <record> task, which allows you to specify a log level of "verbose" or "debug" to provide more details than the standard "info" log level. This task should be the first one performed by the build for any target to ensure that a log is always produced. To accomplish this, I put the <record> task at the start of a target named "init" which I ensure is the first dependency of every other target. An example is given below:

<target name="init">
  <record name="build.log" loglevel="verbose" append="false"/>
</target>

Normally I prefer to use the "verbose" level for the log file, as the "debug" level provides so much additional detail that it is only really useful for debugging bad behavior within Ant code. Notice that I specified the option append="false" which ensures that at the start of the build any existing log file is deleted and a new one created. This makes it easier to see what happens for an individual execution of the build and avoids having the log become too large. This can be a problem, however, if you need to refer back to the log from a prior build to resolve problems or for auditing purposes. I have had situations where after a build fails I look at the build log for the problem, run some other ant target (such as clean) before I have finished resolving the problem, then realize that I have wiped the record of the problem.

One solution to this issue is to create a separate log file for each execution of the build. This can be done by using a build timestamp as part of the log file name, as shown in the below example:

<target name="init">
  <tstamp>
    <format property="timestamp" pattern="yyyy-MM-dd_HH-mm-ss"/>
  </tstamp>
  <property name="build.log.dir" location="${basedir}/buildlogs"/>
  <mkdir dir="${build.log.dir}"/>
  <property name="build.log.filename" value="build_${timestamp}.log"/>
  <record name="${build.log.dir}/${build.log.filename}"
    loglevel="verbose" append="false"/>
  <echo message="Build logged to ${build.log.filename}"/>
</target>

The log files are written to a buildlogs subdirectory to avoid cluttering the main directory. For some reason the <record> task requires an absolute path when specifying a directory, so the build.log.dir property is prefixed with ${basedir}. After setting up the logging, a message is written to the console displaying the log filename used to make it easier to look up the log file if a problem occurs. This approach will cause log files to accumulate within the log directory. If this becomes a problem, you could add some Ant logic to delete log files older than a certain date. I will leave the implementation of this as an exercise to the reader. Hint: use a <delete> task with a <fileset> that contains a <date> selector.

If you find this article helpful, please make a donation.

Share this article: Add 'How to Add Logging to Ant Builds' to reddit Add 'How to Add Logging to Ant Builds' to digg Add 'How to Add Logging to Ant Builds' to Del.icio.us Add 'How to Add Logging to Ant Builds' to FURL Add 'How to Add Logging to Ant Builds' to Technorati Add 'How to Add Logging to Ant Builds' to Yahoo My Web Add 'How to Add Logging to Ant Builds' to Newsvine