I don't know if anyone else will find this interesting, but I wrote a
class which redirects System.Out to JDK1.4 Logging. It is Tomcat
aware and unrolls the stack in a way useful for Tomcat. This might be
useful if you are embedding Tomcat.
I changed catalina.sh to start my class, it then invokes Bootstrap.
Any comments?
Cheers,
-bob
? patch.txt
? catalina/src/share/org/apache/catalina/startup/Tomcat2Jdk14Log.java
Index: catalina/build.xml
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/build.xml,v
retrieving revision 1.124
diff -r1.124 build.xml
1073a1074
> <include name="org/apache/catalina/startup/Tomcat2Jdk14Log.class" />
Index: catalina/src/bin/catalina.sh
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/bin/catalina.sh,v
retrieving revision 1.31
diff -r1.31 catalina.sh
209c209
< org.apache.catalina.startup.Bootstrap "$@" start \
---
> org.apache.catalina.startup.Tomcat2Jdk14Log "$@" start \
package org.apache.catalina.startup;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.logging.Level;
import java.util.logging.Logger;
/* This class takes StandardOut and redirects it to the Jdk1.4 Logger.
* It attempts to walk the stack in a way that is meaningful for Tomcat
*/
public class Tomcat2Jdk14Log extends OutputStream {
public static void main(String args[]) {
PrintStream ps = ( new PrintStream( new Tomcat2Jdk14Log("SysOut", Level.INFO ) ) );
System.setOut( ps );
ps = (new PrintStream( new Tomcat2Jdk14Log("SysErr", Level.WARNING ) ) );
// Humm... this causes an exception to start to be printed..
// perhaps a re-entrant issue?
//System.setErr(ps);
// just passing through
Bootstrap.main(args);
}
private StringBuffer sb = new StringBuffer();
private Level level;
private Logger jlog;
// some platforms use 1 char for newline, others use 2
private int preNewlineChar = -1;
private int newlineChar;
private Tomcat2Jdk14Log( String logName, Level level ){
this.level = level;
jlog = Logger.getLogger(logName);
String newline = System.getProperty( "line.separator" );
if ( newline.length() == 2 ) {
preNewlineChar = newline.charAt(0);
newlineChar = newline.charAt(1);
} else {
newlineChar = newline.charAt(0);
}
}
// should this be syncronized?
public void write(int x) throws java.io.IOException {
if ( x != newlineChar ) {
sb.append( (char)x );
return;
}
// deal with Windows/Unix newline stuff
if ( preNewlineChar != -1
&& sb.length() > 1
&& sb.charAt( sb.length() -1 ) == preNewlineChar) {
sb.deleteCharAt( sb.length() -1 );
}
// get stack trace. This is quite slow. If method/classnames
// arent needed this should be turned off
StackTraceElement locations[] = new Throwable().getStackTrace();
String cname="unknown";
String method="unknown";
boolean foundLogger = false;
String myClassName = this.getClass().getName();
// Stratagy for finding an "Interesting" tomcat stackframe
for (int i=3;i< locations.length;i++ ) {
StackTraceElement caller=locations[i];
cname=caller.getClassName();
if ( !foundLogger ){
// PHASE I: find the tomcat logger (we assume different platforms might
// have different levels of stack... so we whirl through until we see
// something we recognize. )
if ( !cname.equals( "org.apache.tomcat.util.log.SystemLogHandler" ))
continue;
foundLogger = true;
continue;
}
method=caller.getMethodName();
// PHASE II: get rid of wrappers on top of the wrapper
if ( method.equals("log") || method.equals("internalLog") )
continue;
// add line # for fun.
method += ":"+caller.getLineNumber();
break;
}
jlog.logp( level, cname, method, sb.toString() );
sb = new StringBuffer(200);
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>