Bug 42044

Summary: Multiple/composite logs for ant builds
Product: Ant Reporter: Ketan Padegaonkar <KetanPadegaonkar+apache-bugs>
Component: Core tasksAssignee: Ant Notifications List <notifications>
Status: NEW ---    
Severity: enhancement CC: KetanPadegaonkar+apache-bugs
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
Attachments: lsof output for various cases of logging

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?)