At 11:17 AM 7/9/2004, you wrote:
Conor MacNeill wrote:
It you can decide not to issue messages, you can decide to change the behavior of your task in a more radical fashion. But nevermind this point.
Still if we want to have such functionality what we would need is an API
in project to check for current "logging level of interest" that
internally
will consult ALL BuildLogger2 instances and give the aggregated answer.
Such a system will work in the presence of <record/> loggers.
That would be BuildListener2. There's a difference. I still think there is value in being able to control the logger. Being able to control the threshold in the logger (without affecting events sent to other listeners) would be useful for script debugging. I've always found <record> to be somewhat cumbersome.
I'd like to do a good wrapper of commons logging around ant logger that took the aggregate log level and forwarded it. This would make it easier to run highly log-instrumented code under Ant efficiently and yet integrated with Ant's logging (e.g axis-wsdl2java)
Isn't Ant2 going to address the logging issue "holistically" by using an established logging framework like log4j or commons logging as the backbone for the default build logger implementations? If so, is it worth the effort to create new (patch) APIs that will introduce more architecture/implementation constraint pressure on Ant2? Just a question...
1. There isnt going to be a 'big rewrite Ant 2', just gradual evolution.
2. We are at the bottom of the food chain. We cannot introduce dependencies in the core on projects that need ant to build, or you cannot bootstrap the gump. (http://gump.apache.org).
3. What we can do is have an interface with a 1:1 mapping with
BTW, I have already wrapped Ant for Log4J/J2SE using the current 1.6x build listener mechanism. Like you said, it allows me to run (externally controlled) log-instrumented *script* under Ant efficiently while leaving the Ant logging mechanism as-is. However, it's still not possible to make "is this level enabled" from within task Java code.
yes. I've just attached something to do that for commons-logging. One problem I have here is forcing a particular instance of a logger into a program. How did you manage that?
Also, I think there may be performance benefits in core ant if we only issue debug and verbose logs when debug and verbose are enabled; instrumentation is never free & the overhead of toString() and string concatenate operations may be tangible. But we cannot test that, yet.
-steve
/* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */
package org.apache.tools.ant.listener; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogConfigurationException; import org.apache.commons.logging.LogFactory; /** * A factory that creates commons listeners bound to a project */ public class AntCommonsLogFactory extends LogFactory { /** * The configuration attributes for this [EMAIL PROTECTED] LogFactory}. */ private Hashtable attributes = new Hashtable(); /** * Return the configuration attribute with the specified name (if any), * or <code>null</code> if there is no such attribute. * * @param name Name of the attribute to return */ public Object getAttribute(String name) { return (attributes.get(name)); } /** * Return an array containing the names of all currently defined * configuration attributes. If there are no such attributes, a zero * length array is returned. */ public String[] getAttributeNames() { Vector names = new Vector(); Enumeration keys = attributes.keys(); while (keys.hasMoreElements()) { names.addElement(keys.nextElement()); } String results[] = new String[names.size()]; for (int i = 0; i < results.length; i++) { results[i] = (String) names.elementAt(i); } return (results); } /** * Convenience method to derive a name from the specified class and * call <code>getInstance(String)</code> with it. * * @param clazz Class for which a suitable Log name will be derived * * @exception LogConfigurationException if a suitable <code>Log</code> * instance cannot be returned */ public Log getInstance(Class clazz) throws LogConfigurationException { return getInstance(clazz.toString()); } public Log getInstance(String name) throws LogConfigurationException { return new AntCommonsLog(name,null,null); } /** * Release any internal references to previously created [EMAIL PROTECTED] Log} * instances returned by this factory. This is useful environments * like servlet containers, which implement application reloading by * throwing away a ClassLoader. Dangling references to objects in that * class loader would prevent garbage collection. */ public void release() { } /** * Remove any configuration attribute associated with the specified name. * If there is no such attribute, no action is taken. * * @param name Name of the attribute to remove */ public void removeAttribute(String name) { attributes.remove(name); } /** * Set the configuration attribute with the specified name. Calling * this with a <code>null</code> value is equivalent to calling * <code>removeAttribute(name)</code>. * * @param name Name of the attribute to set * @param value Value of the attribute to set, or <code>null</code> * to remove any setting for this attribute */ public void setAttribute(String name, Object value) { if (value == null) { attributes.remove(name); } else { attributes.put(name, value); } } }
/* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "Ant" and "Apache Software Foundation" * must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.tools.ant.listener; import org.apache.commons.logging.Log; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; /** * This is an implementation of commons logging that is bound to an ant * project, and optionally a task within * this log says 'yes' to all isXXXenabled tests, because it is up * to the listeners and loggers to deal with it. */ public class AntCommonsLog implements Log { /** * our project */ Project project; /** * task; may be null */ Task task; /** * name of this log to print out */ String logName; /** * construct a log bound to a project * @param logName name of the log; Set to null if not needed * @param project the current project * @param task optional task; set to null if not used */ public AntCommonsLog(String logName, Project project, Task task) { this.logName = logName; this.project = project; this.task = task; } /** * log to a project or a task * @param message object/text to log * @param level log level */ private void log(Object message,int level) { String text; if(logName!=null) { text=logName+" "+message.toString(); } else { text= message.toString(); } if(task!=null) { task.log(text,level); } else { project.log(text, level); } } /** * * log to a project or a task * @param message object/text to log * @param level log level * @param exception what just wend wrong */ private void log(Object message, Throwable exception, int level) { log(message.toString()+"\n"+exception.toString(),level); } /** * a log level query that is always true * @return true */ public boolean isDebugEnabled() { return true; } /** * a log level query that is always true * @return true */ public boolean isErrorEnabled() { return true; } /** * a log level query that is always true * @return true */ public boolean isFatalEnabled() { return true; } /** * a log level query that is always true * @return true */ public boolean isInfoEnabled() { return true; } /** * a log level query that is always true * @return true */ public boolean isTraceEnabled() { return true; } /** * a log level query that is always true * @return true */ public boolean isWarnEnabled() { return true; } /** * log at MSG_VERBOSE level * @param o object to log */ public void trace(Object o) { log(o, Project.MSG_VERBOSE); } /** * log at MSG_VERBOSE level * @param o object to log * @param throwable throwable to log */ public void trace(Object o, Throwable throwable) { log(o, throwable, Project.MSG_VERBOSE); } /** * log at MSG_DEBUG level * @param o object to log */ public void debug(Object o) { log(o,Project.MSG_DEBUG); } /** * log at MSG_DEBUG level * @param o object to log * @param throwable throwable to log */ public void debug(Object o, Throwable throwable) { log(o, throwable, Project.MSG_DEBUG); } /** * log at MSG_INFO level * @param o object to log */ public void info(Object o) { log(o, Project.MSG_INFO); } /** * log at MSG_INFO level * @param o object to log * @param throwable throwable to log */ public void info(Object o, Throwable throwable) { log(o, throwable, Project.MSG_INFO); } /** * log at MSG_WARN level * @param o object to log */ public void warn(Object o) { log(o, Project.MSG_WARN); } /** * log at MSG_WARN level * @param o object to log * @param throwable throwable to log */ public void warn(Object o, Throwable throwable) { log(o, throwable, Project.MSG_WARN); } /** * log at MSG_ERR level * @param o object to log */ public void error(Object o) { log(o, Project.MSG_ERR); } /** * log at MSG_ERR level * @param o object to log * @param throwable throwable to log */ public void error(Object o, Throwable throwable) { log(o, throwable, Project.MSG_ERR); } /** * log at MSG_ERR level * @param o object to log */ public void fatal(Object o) { log(o, Project.MSG_ERR); } /** * log at MSG_ERR level * @param o object to log * @param throwable throwable to log */ public void fatal(Object o, Throwable throwable) { log(o, throwable, Project.MSG_ERR); } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]