Bug 42044 - Multiple/composite logs for ant builds
Summary: Multiple/composite logs for ant builds
Status: NEW
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: unspecified
Hardware: All All
: P2 enhancement (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-04-04 06:20 UTC by Ketan Padegaonkar
Modified: 2008-11-24 03:58 UTC (History)
1 user (show)



Attachments
lsof output for various cases of logging (44.50 KB, application/x-tar)
2008-04-25 05:30 UTC, Owen Boyle
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ketan Padegaonkar 2007-04-04 06:20:32 UTC
When doing long builds, ant build logs are generally logged using the XmlLogger.

In certain cases, say for example when the build is taking longer than usual,
and needs to be killed/stopped, the XmlLogger does not flush contents to disk.

It would be nice if there is some sort of a composite logger than can chain any
logger along with the XmlLogger.

This approach would facilitate using an XmlLogger cases and say a defaultLogger
in the special case I've mentioned above.
Comment 1 Ketan Padegaonkar 2007-04-04 06:23:11 UTC
This is the source code for a CompositeLogger that logs to a default logger, and
 the XmlLogger. This needs the environment variable ANT_LOG_PREFIX to be set
(there's no better way I can think of)


/*******************************************************************************
 * Copyright 2007 Ketan Padegaonkar http://ketan.padegaonkar.name
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package name.padegaonkar.ketan.ant.logger;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.XmlLogger;

/**
 * @author Ketan Padegaonkar
 */
public class CompositeAntLogger implements BuildLogger {

        private ArrayList       loggers;
        private String          logPrefix;
        private PrintStream     out;

        public CompositeAntLogger() {
                checkLogPrefix();
                createLoggers();
        }

        public void setEmacsMode(boolean emacsMode) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.setEmacsMode(emacsMode);
                }
        }

        public void buildFinished(BuildEvent event) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.buildFinished(event);
                }
        }

        public void buildStarted(BuildEvent event) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.buildStarted(event);
                }
        }

        public void messageLogged(BuildEvent event) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.messageLogged(event);
                }

        }

        public void targetFinished(BuildEvent event) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.targetFinished(event);
                }
        }

        public void targetStarted(BuildEvent event) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.targetStarted(event);
                }
        }

        public void taskFinished(BuildEvent event) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.taskFinished(event);
                }
        }

        public void taskStarted(BuildEvent event) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.taskStarted(event);
                }
        }

        public void setMessageOutputLevel(int level) {
                for (Iterator iterator = loggers.iterator(); iterator.hasNext();) {
                        BuildLogger logger = (BuildLogger) iterator.next();
                        logger.setMessageOutputLevel(level);
                }
        }

        public void setOutputPrintStream(PrintStream output) {
                // do nothing
        }

        public void setErrorPrintStream(PrintStream err) {
                // do nothing
        }

        private void createLoggers() {
                loggers = new ArrayList();
                try {
                        loggers.add(createDefaultLogger());
                        loggers.add(createXmlLogger());
                } catch (FileNotFoundException e) {
                        throw new BuildException("The loggers could not open the
file", e);
                }
        }

        private void checkLogPrefix() {
                logPrefix = System.getenv("ANT_LOG_PREFIX");
                if (logPrefix == null || logPrefix.trim().length() == 0)
                        throw new BuildException("You need to set the
environment variable ANT_LOG_PREFIX.");
        }

        private DefaultLogger createDefaultLogger() throws FileNotFoundException {
                DefaultLogger logger = new DefaultLogger();
                out = new PrintStream(new FileOutputStream(logPrefix + ".txt"));
                logger.setOutputPrintStream(out);
                logger.setErrorPrintStream(out);
                return logger;
        }

        private XmlLogger createXmlLogger() throws FileNotFoundException {
                XmlLogger logger = new XmlLogger();
                out = new PrintStream(new FileOutputStream(logPrefix + ".xml"));
                logger.setOutputPrintStream(out);
                logger.setErrorPrintStream(out);
                return logger;
        }
}
Comment 2 Owen Boyle 2008-04-25 05:30:19 UTC
Created attachment 21851 [details]
lsof output for various cases of logging 

lsof output indicating number of pipes used for each combination of: 3 apache versions (2.2.6, 2.2.8 unpatched, 2.2.8 patched) by 3 config cases (T+E logs in main config, T+E in 1 VH, t+E in 2 VHs).
Comment 3 Owen Boyle 2008-04-25 05:32:22 UTC
Please ignore recent attachment - it went to the wrong bug... sorry.

(why oh why does bugzilla go to a random bug after posting?)