У меня есть два возможных решения:
- написать собственную задачу antcall, которая по-разному обрабатывает ведение журнала
- забыть о консоли и использовать запись для управления записью в файл
Я собираюсь перейти ко второму, потому что его проще всего реализовать, и потому что я, вероятно, перейду на gradle позже, где я решу это по-другому (но, вероятно, следуя аналогичной схеме)
Основная задача муравья будет использовать запись для включения и выключения регистрации в build.log.До параллели он отключит ведение журнала, пусть суб-муравей регистрирует файлы.После завершения муравей загрузит и отобразит вывод.Вывод на консоль продолжает смешиваться, а build.log сериализуется.
Это немного клунко, но не так уж плохо.
<project name="antExperiments" default="para" basedir=".">
<!-- Logging Control -->
<property name="build.log.dir" location="${basedir}/logs"/>
<!-- - - - - - - - - - - - - - - - - -
macro: activate logging (defaults to ${build.log.dir}/build.log)
- - - - - - - - - - - - - - - - - -->
<macrodef name="start.log">
<attribute name="name" default="build"/>
<attribute name="dir" default="${build.log.dir}"/>
<attribute name="append" default="false"/>
<sequential>
<record action="start" append="@{append}" name="@{dir}/@{name}.log"/>
</sequential>
</macrodef>
<!-- - - - - - - - - - - - - - - - - -
macro: deactivate logging (defaults to ${build.log.dir}/build.log)
- - - - - - - - - - - - - - - - - -->
<macrodef name="stop.log">
<attribute name="name" default="build"/>
<attribute name="dir" default="${build.log.dir}"/>
<attribute name="append" default="false"/>
<sequential>
<record action="stop" append="@{append}" name="@{dir}/@{name}.log"/>
</sequential>
</macrodef>
<target name="clean">
<delete dir="${build.log.dir}"/>
<mkdir dir="${build.log.dir}"/>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: main.init
Initialization for Top Level build - not used by subants
- - - - - - - - - - - - - - - - - -->
<target name="main.init">
<start.log/>
</target>
<!-- =================================
target: para
top level build runs 2 jobs in parallel producing interleaved hard to read
on to standard output and non interleaved more easily understood logging
to build.log
================================= -->
<target name="para" depends="main.init,clean">
<stop.log/> <!-- disable top level logging -->
<parallel threadcount="4" pollinterval="50">
<ant output="${build.log.dir}/proc1.log" target="proc1">
<property name="proc" value="proc1"/>
</ant>
<ant output="${build.log.dir}/proc2.log" target="proc2">
<property name="proc" value="proc2"/>
</ant>
</parallel>
<start.log/> <!-- enable top level logging -->
<!-- Non interleaved output -->
<loadfile property="p1" srcfile="${build.log.dir}/proc1.log"/>
<loadfile property="p2" srcfile="${build.log.dir}/proc2.log"/>
<echo>
--------------------------
BuildJob: proc1
OUTPUT: ******************
${p1}
**************************
--------------------------
BuildJob: proc2
OUTPUT: ******************
${p2}
**************************
BUILD LOG: ${build.log.dir}/build.log
</echo>
</target>
<target name="init">
<echo>Init called by ${proc}</echo>
</target>
<target name="proc1" depends="init">
<echo>PROC1.......................
</echo>
<exec dir="${basedir}" executable="cmd">
<arg line="/c dir \"/>
</exec>
</target>
<target name="proc2" depends="init">
<echo>PROC2..........2222222.......
</echo>
<exec dir="${basedir}" executable="cmd">
<arg line="/c dir \sandbox"/>
</exec>
</target>
</project>