This is a quick implementation of a %stacktrace pattern converter to create exceptions when a stack trace is logged.

I added documentation in PatternLayout right below %throwable.

It also supports the {short} operator for just the first line.

Anyway... The best documentation is the source.

Comments welcome!

Kevin

--

Use Rojo (RSS/Atom aggregator). Visit http://rojo.com. Ask me for an invite! Also see irc.freenode.net #rojo if you want to chat.

Rojo is Hiring! - http://www.rojonetworks.com/JobsAtRojo.html

If you're interested in RSS, Weblogs, Social Networking, etc... then you should work for Rojo! If you recommend someone and we hire them you'll get a free iPod!
Kevin A. Burton, Location - San Francisco, CA
AIM/YIM - sfburtonator, Web - http://peerfear.org/
GPG fingerprint: 5FB2 F3E2 760E 70A8 6174 D393 E84D 8D04 99F1 4412


? cvs.diff
? src/java/org/apache/log4j/pattern/StacktraceInformationPatternConverter.java
Index: src/java/org/apache/log4j/PatternLayout.java
===================================================================
RCS file: 
/home/cvspublic/logging-log4j/src/java/org/apache/log4j/PatternLayout.java,v
retrieving revision 1.33
diff -u -r1.33 PatternLayout.java
--- src/java/org/apache/log4j/PatternLayout.java        21 Dec 2004 04:19:46 
-0000      1.33
+++ src/java/org/apache/log4j/PatternLayout.java        24 Dec 2004 02:36:32 
-0000
@@ -285,6 +285,23 @@
    </tr>
 
    <tr>
+     <td align=center><b>stacktrace</b></td>
+
+     <td>
+
+     <p> Similar to %throwable but generates printStackTrace-like output from
+     the point of log generation.  This enables to you to debug log points
+     within your application without a recompile.
+     
+     The throwable conversion word can be followed by an option in the form
+     <b>%throwable{short}</b> which will only output the first line of the
+     ThrowableInformation.</p>
+
+     </td>
+   </tr>
+
+   
+   <tr>
 
      <td align=center><b>%</b></td>
 
Index: src/java/org/apache/log4j/pattern/PatternParser.java
===================================================================
RCS file: 
/home/cvspublic/logging-log4j/src/java/org/apache/log4j/pattern/PatternParser.java,v
retrieving revision 1.19
diff -u -r1.19 PatternParser.java
--- src/java/org/apache/log4j/pattern/PatternParser.java        22 Dec 2004 
21:17:45 -0000      1.19
+++ src/java/org/apache/log4j/pattern/PatternParser.java        24 Dec 2004 
02:36:32 -0000
@@ -102,6 +102,8 @@
     globalRulesRegistry.put("sequenceNumber", 
SequenceNumberPatternConverter.class.getName());
     
     globalRulesRegistry.put("throwable", 
ThrowableInformationPatternConverter.class.getName());
+
+    globalRulesRegistry.put("stacktrace", 
StacktraceInformationPatternConverter.class.getName());
     
   }
 
/*
 * Copyright 1999,2004 The Apache Software Foundation.
 *
 * 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 org.apache.log4j.pattern;

import java.util.List;

import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;

/**
 * Outputs the stacktrace of a log point excluding log4j internal classes.
 *
 * @author Paul Smith
 * @since 1.3
 *
 */
public class StacktraceInformationPatternConverter extends PatternConverter {
  
  String option;
  
  /* (non-Javadoc)
   * @see org.apache.log4j.pattern.PatternConverter#convert(org.apache.log4j.spi.LoggingEvent)
   */
  protected StringBuffer convert(LoggingEvent event) {
    StringBuffer buf = new StringBuffer(32);

    //NOTE: the only reason we need to try/catch here is because getStackTrace
    //is a new method on JDK 1.4 and might not even be present on other Java
    //platforms (GCJ or J2ME?).  Note that if we were to use a
    //ByteArrayOutputStream along with printStackTrace and then were to parse
    //the output into lines manually then this would be more portable.  Not sure
    //that the output is consistent across platforms so it might be better to
    //have this mechanism fallback when getStackTrace throws a
    //NoSuchMethodException

    try {

        Exception stack = new Exception();

        StackTraceElement[] ste = stack.getStackTrace();

        boolean isShort = false;
        
        if ( "short".equals( option ) ) {
            isShort = true;
        } 
    
        //NOTE: when option is an integer here we could just return this many
        //lines.  As an example you could have %stacktrace{5} and only return 5
        //lines of the stack.

        buf.append( "Internal debug log4j stacktrace follows: \n" );
        
        for (int i = 0; i < ste.length; i++) {

            StackTraceElement current = ste[i];

            if ( current.getClassName().startsWith( "org.apache.log4j" ) )
                continue; //ignore internal log4j classes
            
            String str = current.toString();

            //note: add a string prefix here so that existing IDE tools can parse
            //our the stacktrace that use regexp.
            buf.append( "        " )
               .append( str )
               .append("\n");

            if ( isShort )
                break; //we're done here when in short mode.

        }

    } catch ( Exception e ) {
        buf.append( "Exception trying to log %stacktrace. Running on JDK >1.4?: " + e.getMessage() );
    }

    return buf;
  }

  public void setOptions(List optionList) {
    if(optionList == null || optionList.size() == 0) {
      return;
    }
    option = (String) optionList.get(0);
  }
  
  public String getName() {
    return "Stacktrace";
  }

  public String getStyleClass(LoggingEvent e) {
    return "stacktrace";
  }
  
  /**
   * This converter obviosly handles throwables.
   */
  public boolean handlesThrowable() {
    return true;
  }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to