[logback-dev] [GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.29-33-gf0b1a77

added by portage for gitosis-gentoo git-noreply at pixie.qos.ch
Tue Sep 20 22:39:35 CEST 2011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".

The branch, master has been updated
       via  f0b1a778e9000cadf586790d670cb75ad36bdf3a (commit)
      from  7a2e02bca24d872d580694ab89a865542103e570 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=f0b1a778e9000cadf586790d670cb75ad36bdf3a
http://github.com/ceki/logback/commit/f0b1a778e9000cadf586790d670cb75ad36bdf3a

commit f0b1a778e9000cadf586790d670cb75ad36bdf3a
Author: Tomasz Nurkiewicz <nurkiewicz at gmail.com>
Date:   Mon Aug 16 01:31:43 2010 +0800

    [LBCLASSIC-217] Exception stack trace printing starting from root cause

diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java b/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
index 9cab8e7..ef32df3 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
@@ -35,6 +35,7 @@ import ch.qos.logback.classic.pattern.MessageConverter;
 import ch.qos.logback.classic.pattern.MethodOfCallerConverter;
 import ch.qos.logback.classic.pattern.NopThrowableInformationConverter;
 import ch.qos.logback.classic.pattern.RelativeTimeConverter;
+import ch.qos.logback.classic.pattern.RootCauseFirstThrowableProxyConverter;
 import ch.qos.logback.classic.pattern.ThreadConverter;
 import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
 import ch.qos.logback.classic.spi.ILoggingEvent;
@@ -100,6 +101,9 @@ public class PatternLayout extends PatternLayoutBase<ILoggingEvent> {
     defaultConverterMap.put("ex", ThrowableProxyConverter.class.getName());
     defaultConverterMap.put("exception", ThrowableProxyConverter.class
         .getName());
+    defaultConverterMap.put("rEx", RootCauseFirstThrowableProxyConverter.class.getName());
+    defaultConverterMap.put("rootException", RootCauseFirstThrowableProxyConverter.class
+        .getName());
     defaultConverterMap.put("throwable", ThrowableProxyConverter.class
         .getName());
 
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverter.java
new file mode 100644
index 0000000..3ed88e4
--- /dev/null
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverter.java
@@ -0,0 +1,54 @@
+package ch.qos.logback.classic.pattern;
+
+import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter;
+import ch.qos.logback.classic.spi.IThrowableProxy;
+import ch.qos.logback.classic.spi.StackTraceElementProxy;
+import ch.qos.logback.classic.spi.ThrowableProxyUtil;
+import ch.qos.logback.core.CoreConstants;
+
+/**
+ * @author Tomasz Nurkiewicz
+ * @since 2010-08-07, 14:07:10
+ */
+public class RootCauseFirstThrowableProxyConverter extends ExtendedThrowableProxyConverter {
+
+    @Override
+    protected String printThrowableToString(IThrowableProxy tp) {
+        StringBuilder buf = new StringBuilder(2048);
+        printRootCauseFirst(tp, buf);
+        return buf.toString();
+    }
+
+    private void printRootCauseFirst(IThrowableProxy tp, StringBuilder buf) {
+        if (tp.getCause() != null)
+            printRootCauseFirst(tp.getCause(), buf);
+        printRootCause(tp, buf);
+    }
+
+    private void printRootCause(IThrowableProxy tp, StringBuilder buf) {
+        ThrowableProxyUtil.printFirstLineRootCauseFirst(buf, tp);
+        buf.append(CoreConstants.LINE_SEPARATOR);
+        StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
+        int commonFrames = tp.getCommonFrames();
+
+        boolean unrestrictedPrinting = lengthOption > stepArray.length;
+        int length = (unrestrictedPrinting) ? stepArray.length : lengthOption;
+
+
+        int maxIndex = length;
+        if (commonFrames > 0 && unrestrictedPrinting) {
+            maxIndex -= commonFrames;
+        }
+
+        for (int i = 0; i < maxIndex; i++) {
+            String string = stepArray[i].toString();
+            buf.append(CoreConstants.TAB);
+            buf.append(string);
+            extraData(buf, stepArray[i]); // allow other data to be added
+            buf.append(CoreConstants.LINE_SEPARATOR);
+        }
+
+    }
+
+
+}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableProxyConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableProxyConverter.java
index 0a68cf8..3ddb1e5 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableProxyConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableProxyConverter.java
@@ -96,7 +96,6 @@ public class ThrowableProxyConverter extends ThrowableHandlingConverter {
   }
 
   public String convert(ILoggingEvent event) {
-    StringBuilder buf = new StringBuilder(32);
 
     IThrowableProxy tp = event.getThrowableProxy();
     if (tp == null) {
@@ -135,10 +134,16 @@ public class ThrowableProxyConverter extends ThrowableHandlingConverter {
       }
     }
 
-    while (tp != null) {
-      printThrowableProxy(buf, tp);
-      tp = tp.getCause();
+    return printThrowableToString(tp);
     }
+
+  protected String printThrowableToString(IThrowableProxy tp) {
+      StringBuilder buf = new StringBuilder(32);
+      IThrowableProxy currentThrowable = tp;
+      while (currentThrowable != null) {
+          printThrowableProxy(buf, currentThrowable);
+          currentThrowable = currentThrowable.getCause();
+      }
     return buf.toString();
   }
 
@@ -166,7 +171,7 @@ public class ThrowableProxyConverter extends ThrowableHandlingConverter {
     }
 
     if (commonFrames > 0 && unrestrictedPrinting) {
-      buf.append("\t... " + tp.getCommonFrames()).append(
+      buf.append("\t... ").append(tp.getCommonFrames()).append(
           " common frames omitted").append(CoreConstants.LINE_SEPARATOR);
     }
   }
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyUtil.java
index c02cadd..1283bce 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyUtil.java
@@ -117,7 +117,7 @@ public class ThrowableProxyUtil {
     }
     
     if (commonFrames > 0) {
-      sb.append("\t... " + commonFrames).append(" common frames omitted")
+      sb.append("\t... ").append(commonFrames).append(" common frames omitted")
           .append(CoreConstants.LINE_SEPARATOR);
     }
     
@@ -128,6 +128,17 @@ public class ThrowableProxyUtil {
     if (commonFrames > 0) {
       buf.append(CoreConstants.CAUSED_BY);
     }
+    printExceptionMessage(buf, tp);
+  }
+
+  static public void printFirstLineRootCauseFirst(StringBuilder buf, IThrowableProxy tp) {
+    if (tp.getCause() != null) {
+      buf.append(CoreConstants.WRAPPED_BY);
+    }
+    printExceptionMessage(buf, tp);
+  }
+
+  private static void printExceptionMessage(StringBuilder buf, IThrowableProxy tp) {
     buf.append(tp.getClassName()).append(": ").append(tp.getMessage());
   }
 }
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverterTest.java
new file mode 100644
index 0000000..ccd0873
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverterTest.java
@@ -0,0 +1,103 @@
+package ch.qos.logback.classic.pattern;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static ch.qos.logback.classic.util.TeztHelper.makeNestedException;
+import static ch.qos.logback.classic.util.TeztHelper.positionOf;
+import static org.fest.assertions.Assertions.assertThat;
+
+/**
+ * @author Tomasz Nurkiewicz
+ * @since 2010-08-15, 18:34:21
+ */
+public class RootCauseFirstThrowableProxyConverterTest {
+
+  private LoggerContext context = new LoggerContext();
+  private ThrowableProxyConverter converter = new RootCauseFirstThrowableProxyConverter();
+  private StringWriter stringWriter = new StringWriter();
+  private PrintWriter printWriter = new PrintWriter(stringWriter);
+
+  @Before
+  public void setUp() throws Exception {
+    converter.setContext(context);
+    converter.start();
+  }
+
+  private ILoggingEvent createLoggingEvent(Throwable t) {
+    return new LoggingEvent(this.getClass().getName(), context
+        .getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", t,
+        null);
+  }
+
+  @Test
+  public void integration() {
+    //given
+    PatternLayout pl = new PatternLayout();
+    pl.setContext(context);
+    pl.setPattern("%m%rEx%n");
+    pl.start();
+
+    //when
+    ILoggingEvent e = createLoggingEvent(new Exception("x"));
+    String result = pl.doLayout(e);
+
+    //then
+    // make sure that at least some package data was output
+    Pattern p = Pattern.compile(" \\[junit.*\\]");
+    Matcher m = p.matcher(result);
+    int i = 0;
+    while(m.find()) {
+      i++;
+    }
+    assertThat(i).isGreaterThan(5);
+  }
+
+  @Test
+  public void smoke() {
+    //given
+    Exception exception = new Exception("smoke");
+    exception.printStackTrace(printWriter);
+
+    //when
+    ILoggingEvent le = createLoggingEvent(exception);
+    String result = converter.convert(le);
+
+    //then
+    result = result.replace("common frames omitted", "more");
+    result = result.replaceAll(" ~?\\[.*\\]", "");
+    assertThat(result).isEqualTo(stringWriter.toString());
+  }
+
+  @Test
+  public void nested() {
+    //given
+    Throwable nestedException = makeNestedException(2);
+    nestedException.printStackTrace(printWriter);
+
+    //when
+    ILoggingEvent le = createLoggingEvent(nestedException);
+    String result = converter.convert(le);
+
+    //then
+    assertThat(result).startsWith("java.lang.Exception: nesting level=0");
+    assertThat(
+            positionOf("nesting level=0").in(result)).isLessThan(
+            positionOf("nesting level =1").in(result));
+    assertThat(
+            positionOf("nesting level =1").in(result)).isLessThan(
+            positionOf("nesting level =2").in(result));
+  }
+
+}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java
index f9f848d..badde04 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java
@@ -23,4 +23,35 @@ public class TeztHelper {
     Throwable cause = makeNestedException(level - 1);
     return new Exception("nesting level =" + level, cause);
   }
+
+  /**
+   * Usage:
+   * <pre>
+   * String s = "123";
+   * positionOf("1").in(s) < positionOf("3").in(s)
+   * </pre>
+   *
+   * @param pattern Plain text to be found
+   * @return StringPosition fluent interface
+   */
+  public static StringPosition positionOf(String pattern) {
+    return new StringPosition(pattern);
+  }
+
+  public static class StringPosition {
+    private final String pattern;
+
+    public StringPosition(String pattern) {
+      this.pattern = pattern;
+    }
+
+    public int in(String s) {
+      final int position = s.indexOf(pattern);
+      if(position < 0)
+        throw new IllegalArgumentException("String '" + pattern + "' not found in: '" + s + "'");
+      return position;
+    }
+
+  }
+
 }

-----------------------------------------------------------------------

Summary of changes:
 .../java/ch/qos/logback/classic/PatternLayout.java |    4 +
 .../RootCauseFirstThrowableProxyConverter.java     |   54 ++++++++++
 .../classic/pattern/ThrowableProxyConverter.java   |   15 ++-
 .../logback/classic/spi/ThrowableProxyUtil.java    |   13 +++-
 .../RootCauseFirstThrowableProxyConverterTest.java |  103 ++++++++++++++++++++
 .../ch/qos/logback/classic/util/TeztHelper.java    |   31 ++++++
 6 files changed, 214 insertions(+), 6 deletions(-)
 create mode 100644 logback-classic/src/main/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverter.java
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverterTest.java


hooks/post-receive
-- 
Logback: the generic, reliable, fast and flexible logging framework.


More information about the logback-dev mailing list