Bob, That would work. I forgot that Remy now puts out a JDK 1.4 build of Tomcat and using the build flags would allow it to be picked up by users of the JDK 1.4 builds.
Patrick Bob Herrmann wrote: > Humm... How about this instead (not that I am lazy)? > > $ cvs diff -u catalina/build.xml > Index: catalina/build.xml > =================================================================== > RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/build.xml,v > retrieving revision 1.124 > diff -u -r1.124 build.xml > --- catalina/build.xml 29 Jun 2002 01:00:04 -0000 1.124 > +++ catalina/build.xml 22 Jul 2002 16:31:07 -0000 > @@ -801,6 +801,8 @@ > unless="jdk.1.3.present"/> > <exclude name="org/apache/catalina/servlets/CGIServlet.java" > unless="jdk.1.3.present"/> > + <exclude name="org/apache/catalina/logger/JdkLogger.java" > + unless="jdk.1.4.present"/> > <exclude name="org/apache/naming/NamingService.java" > unless="compile.jmx"/> > <exclude > name="org/apache/naming/factory/DbcpDataSourceFactory.java" > > > On Mon, 2002-07-22 at 12:28, Patrick Luby wrote: > >>Bob, >> >>This is a useful piece of code. However, your patch can't go into Tomcat >>as it will only compile with JDK 1.4. The standard builds of Tomcat that >>are downloadable from the jakarta.apache.org are built using JDK 1.3 and >>should be run without crashing Tomcat on JDK 1.2. >> >>So, if you would like this in Tomcat (and I think it would be a nice >>optional logger implementation), I think that you need to do the following: >> >>1. Remove all of the following import statements and replace them with >> reflection calls so that the JDK 1.3 compiler can compile this class: >> >> import java.util.logging.Logger; >> import java.util.logging.Level; >> import java.util.logging.Formatter; >> import java.util.logging.Handler; >> import java.util.logging.LogRecord; >> >>2. Catch any ClassNotFound and MethodNotFound exceptions that will occur >> when the code is run on JDK 1.2 or 1.3. >> >>Patrick >> >> >> >> >>Bob Herrmann wrote: >> >>>Hi. I am trying to get Tomcat to log to JDK1.4's logging. >>> >>>I tried implementing a "o.a.c.logging.Logger" subclass that forwarded >>>calls to commons-logging Log. This was unsatisfying because the >>>commons-logger unrolls the stack and logs the "class.method" of my >>>logger, not my logger's caller. >>> >>>I was tempted to change the commons-logger to allow for specifying >>>a class and method on all its methods, but that would be a large >>>change the commons-logger (involving changes and decisions about >>>how this new information should be pushed down and handled with >>>the other loggers it supports.) There is also some issues mapping >>>tomcat verbosity levels, to common-logger log levels and then to JDK >>>Logger levels. >>> >>>So I punted and implemented the code below. It is a >>>"o.a.c.logging.Logger" which writes directly to JDK 1.4 Logging. >>>It allowed me to unroll the stack in a way that fits well with >>>tomcat (ignoring stack frames calling with method log() or method >>>internalLog() which are uninteresting.) And allowed me to map >>>verbosity to JDK Levels. >>> >>>Cheers, >>>-bob >>> >>> >>> >>> >>>------------------------------------------------------------------------ >>> >>>/* >>> * $Header: $ >>> * $Revision: $ >>> * $Date: $ >>> * >>> * ==================================================================== >>> * >>> * The Apache Software License, Version 1.1 >>> * >>> * Copyright (c) 1999 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", "Tomcat", 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/>. >>> * >>> * [Additional notices, if required by prior licensing conditions] >>> * >>> */ >>> >>> >>>package org.apache.catalina.logger; >>> >>>import java.sql.Timestamp; >>> >>>import org.apache.catalina.Lifecycle; >>>import org.apache.catalina.LifecycleEvent; >>>import org.apache.catalina.LifecycleException; >>>import org.apache.catalina.LifecycleListener; >>>import org.apache.catalina.util.LifecycleSupport; >>>import org.apache.catalina.util.StringManager; >>> >>>import java.util.logging.Logger; >>>import java.util.logging.Level; >>>import java.util.logging.Formatter; >>>import java.util.logging.Handler; >>>import java.util.logging.LogRecord; >>> >>> >>>/** >>> * Implementation of <b>Logger</b> that sends log messages to the >>> * Jdk logger >>> * >>> * @version $Revision: $ $Date: $ >>> */ >>> >>>public class JdkLogger >>> extends LoggerBase >>> implements Lifecycle { >>> >>> >>> // ----------------------------------------------------- Instance Variables >>> >>> >>> /** >>> * The descriptive information about this implementation. >>> */ >>> protected static final String info = >>> "org.apache.catalina.logger.JdkLogger/1.0"; >>> >>> /** >>> * The lifecycle event support for this component. >>> */ >>> protected LifecycleSupport lifecycle = new LifecycleSupport(this); >>> >>> /** >>> * The string manager for this package. >>> */ >>> private StringManager sm = >>> StringManager.getManager(Constants.Package); >>> >>> /** >>> * Has this component been started? >>> */ >>> private boolean started = false; >>> >>> >>> /** >>> * The default JDK logging domain that these messages are logged to >>> */ >>> private String domain = "tomcat"; >>> >>> >>> /** >>> * The we are using. We set it immediately incase we get calls >>> */ >>> private Logger jlog = Logger.getLogger(domain); >>> >>> >>> // ------------------------------------------------------------- Properties >>> >>> >>> >>> /** >>> * Return the logging domain in which we create log files. >>> */ >>> public String getDomain() { >>> >>> return (domain); >>> >>> } >>> >>> >>> /** >>> * Set the domain in which we send our log files >>> * >>> * @param domain The new domain >>> */ >>> public void setDomain(String domain) { >>> >>> String oldDomain = this.domain; >>> this.domain = domain; >>> support.firePropertyChange("domain", oldDomain, this.domain); >>> >>> // there doesnt seem to be any semantics for changing a Logger's name, so >>> // we just replace it. >>> jlog = Logger.getLogger(domain); >>> } >>> >>> >>> // --------------------------------------------------------- Public Methods >>> >>> /** >>> * Writes an explanatory message and a stack trace for a given >>> * <code>Throwable</code> exception to the logger. >>> * This message will be logged unconditionally. >>> * >>> * @param message A <code>String</code> that describes the error or >>> * exception >>> * @param exception The <code>Exception</code> error or exception >>> */ >>> public void log(Exception exception, String message){ >>> logCallerStack( Level.INFO, message, exception ); >>> } >>> >>> /** >>> * Writes an explanatory message and a stack trace for a given >>> * <code>Throwable</code> exception to the logger >>> * This message will be logged unconditionally. >>> * >>> * @param message A <code>String</code> that describes the error or >>> * exception >>> * @param throwable The <code>Throwable</code> error or exception >>> */ >>> public void log(String message, Throwable throwable){ >>> logCallerStack( Level.INFO, message, throwable ); >>> } >>> >>> /** >>> * Writes the specified message and exception to the logger, >>> * if the logger is set to a verbosity level equal >>> * to or higher than the specified value for this message. >>> * >>> * @param message A <code>String</code> the message to log >>> * @param verbosity Verbosity level of this message >>> */ >>> public void log(String message, int verbosity){ >>> if (this.verbosity < verbosity) >>> return; >>> >>> // Translate tomcat verbosity into JDK Levels >>> Level jlevel = Level.INFO; >>> if ( verbosity == FATAL ) jlevel = Level.SEVERE; >>> else if ( verbosity == ERROR ) jlevel = Level.SEVERE; >>> else if ( verbosity == WARNING ) jlevel = Level.WARNING; >>> else if ( verbosity == DEBUG ) jlevel = Level.FINE; >>> >>> logCallerStack( jlevel, message, null ); >>> } >>> >>> /** >>> * Writes the specified message and exception to the logger, >>> * if the logger is set to a verbosity level equal >>> * to or higher than the specified value for this message. >>> * >>> * @param message A <code>String</code> that describes the error or >>> * exception >>> * @param throwable The <code>Throwable</code> error or exception >>> * @param verbosity Verbosity level of this message >>> */ >>> public void log(String message, Throwable throwable, int verbosity){ >>> if (this.verbosity < verbosity) >>> return; >>> >>> // Translate tomcat verbosity into JDK Levels >>> Level jlevel = Level.INFO; >>> if ( verbosity == FATAL ) jlevel = Level.SEVERE; >>> else if ( verbosity == ERROR ) jlevel = Level.SEVERE; >>> else if ( verbosity == WARNING ) jlevel = Level.WARNING; >>> else if ( verbosity == DEBUG ) jlevel = Level.FINE; >>> >>> logCallerStack( jlevel, message, throwable ); >>> } >>> >>> >>> /** >>> * Writes the specified message to a the logger >>> * >>> * @param message A <code>String</code> specifying the message to be logged >>> */ >>> public void log(String message) { >>> logCallerStack( Level.INFO, message, null ); >>> } >>> >>> >>> // -------------------------------------------------------- Private Methods >>> >>> /** >>> * Writes the specified message to a the logger and attempts to unroll >>> * the stack to include the Class and method of the caller. Trys to be >>> * clever by detecting other wrappers around logging (ie. frames with >>> * methods name log() and internalLog() are skipped in determing the >>> * messages stack of origin) >>> * >>> * @param jLevel A <code>java.util.logging.Level</code> instance to indicate >the desired logging level >>> * @param message A <code>String</code> specifying the message to be logged >>> * @param throwable The <code>Throwable</code> error or exception >>> */ >>> private void logCallerStack( Level jlevel, String message, Throwable throwable >){ >>> // Hack (?) to get the stack trace. >>> Throwable dummyException=new Throwable(); >>> StackTraceElement locations[]=dummyException.getStackTrace(); >>> // Caller will be the third element >>> String cname="unknown"; >>> String method="unknown"; >>> >>> // tomcat has methods named log() and internalLog() that are sometimes on the >stack >>> if( locations!=null && locations.length >2 ) { >>> StackTraceElement caller=null; >>> for (int stackLevel=2;stackLevel<locations.length;stackLevel++){ >>> caller = locations[stackLevel]; >>> method=caller.getMethodName(); >>> if ( !method.equals("log") && !method.equals("internalLog") ){ >>> cname=caller.getClassName(); >>> // method += " [DEPTH "+stackLevel+"]"; uncomment this to see how >much stack walking is going on. >>> break; >>> } >>> } >>> } >>> if( throwable==null ) { >>> jlog.logp( jlevel, cname, method, message ); >>> } else { >>> jlog.logp( jlevel, cname, method, message, throwable ); >>> } >>> >>> } >>> >>> >>> // ------------------------------------------------------ Lifecycle Methods >>> >>> >>> /** >>> * Add a lifecycle event listener to this component. >>> * >>> * @param listener The listener to add >>> */ >>> public void addLifecycleListener(LifecycleListener listener) { >>> >>> lifecycle.addLifecycleListener(listener); >>> >>> } >>> >>> >>> /** >>> * Get the lifecycle listeners associated with this lifecycle. If this >>> * Lifecycle has no listeners registered, a zero-length array is returned. >>> */ >>> public LifecycleListener[] findLifecycleListeners() { >>> >>> return lifecycle.findLifecycleListeners(); >>> >>> } >>> >>> >>> /** >>> * Remove a lifecycle event listener from this component. >>> * >>> * @param listener The listener to add >>> */ >>> public void removeLifecycleListener(LifecycleListener listener) { >>> >>> lifecycle.removeLifecycleListener(listener); >>> >>> } >>> >>> >>> /** >>> * Prepare for the beginning of active use of the public methods of this >>> * component. This method should be called after <code>configure()</code>, >>> * and before any of the public methods of the component are utilized. >>> * >>> * @exception LifecycleException if this component detects a fatal error >>> * that prevents this component from being used >>> */ >>> public void start() throws LifecycleException { >>> >>> // Validate and update our current component state >>> if (started) >>> throw new LifecycleException( "alreadyStarted"); >>> lifecycle.fireLifecycleEvent(START_EVENT, null); >>> started = true; >>> >>> } >>> >>> >>> /** >>> * Gracefully terminate the active use of the public methods of this >>> * component. This method should be the last one called on a given >>> * instance of this component. >>> * >>> * @exception LifecycleException if this component detects a fatal error >>> * that needs to be reported >>> */ >>> public void stop() throws LifecycleException { >>> >>> // Validate and update our current component state >>> if (!started) >>> throw new LifecycleException("notStarted"); >>> lifecycle.fireLifecycleEvent(STOP_EVENT, null); >>> started = false; >>> >>> } >>> >>> >>>} >>> >>> >>> >>> >>> >>>------------------------------------------------------------------------ >>> >>>-- >>>To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> >>>For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> >> >> >>-- >>________________________________________________________________ >>Patrick Luby Email: [EMAIL PROTECTED] >>Sun Microsystems Phone: 408-276-7471 >>901 San Antonio Road, USCA14-303 >>Palo Alto, CA 94303-4900 >>________________________________________________________________ >> >> >>-- >>To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> >>For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > > > > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- ________________________________________________________________ Patrick Luby Email: [EMAIL PROTECTED] Sun Microsystems Phone: 408-276-7471 901 San Antonio Road, USCA14-303 Palo Alto, CA 94303-4900 ________________________________________________________________ -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>