views:

1216

answers:

3

Is there an easy way to have the Ant logger (default or other) add a timestamp to each message?

The only way I can think of is to use the Log4jListener and have its settings include the timestamp. Or write a custom logger that subclasses DefaultLogger and writes the timestamp. If there's a better or easier way (preferably without requiring that users install a new jar file into their Ant lib directory),

I'd be interested in hearing about it.

+1  A: 

You can define an Ant macrodef to set the current timestamp, then call the macrodef each time you need to reference it throughout your build.xml

The following macrodef will set the timestamp to a property (you can add an attribute to the macrodef if you want to customise the property it sets):

<macrodef  name="set.timestamp">
  <sequential>
    <tstamp>
      <format property="current.time" pattern="MM/dd/yyyy hh:mm"/>
    </tstamp>
  </sequential>
</macrodef>

Then to use it, just access the property set by the macrodef as you need:

<target name="doFoo" depends="dir.check" if="dir.exists">
  <set.timestamp/>
  <!--in this example, just echo the timestamp -->
  <echo message="${current.time}"/>
</target>

For more information on ant macrodefs, check out the documentation.

Rich Seller
A: 

Writing a custom logger is not hard.

could you please give me some hits? I was trying to make a custom logger in Ant using redirector tag.
Tiger
Actually write one, as in implementing the BuildLogger interface. Extending DefaultLogger would be a good starting place.
+1  A: 

Given properties are immutable in ant you need to do something a bit funky here otherwise you just end up logging the same timestamp again and again.

Using antcall gives you a fresh session which means you can reuse the property, although it is a little clumsy.

<macrodef name="timestamp.echo"> 
  <attribute name="message"/>    
  <sequential> 
    <antcall target="_timestamp.echo">
        <param name="message" value="@{message}" />
    </antcall>
  </sequential> 
</macrodef>  


<target name="_timestamp.echo"> 
   <tstamp> 
    <format property="current.time" pattern="dd/MM/yyyy hh:mm:ss"/> 
   </tstamp>          
   <echo message="${current.time} ${message}"/> 
</target>

If you are using Ant 1.8 then you can use local which is much cleaner

<macrodef name="timestamp.echo"> 
  <attribute name="message"/>    
  <sequential> 
   <local name="current.time" />
   <tstamp> 
    <format property="current.time" pattern="dd/MM/yyyy hh:mm:ss"/> 
   </tstamp>          
   <echo message="${current.time} @{message}" />
  </sequential> 
</macrodef>  

And here is how you can use it

<target name="testTsEcho" depends="init" description="blah">
    <timestamp.echo message="test" />
    <sleep seconds="10" />
    <timestamp.echo message="test2" />
</target>
Gavin Clarke