Author: ceki Date: Tue Sep 9 13:57:55 2008 New Revision: 1806 Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicCPDCTest.java logback/trunk/logback-site/src/site/pages/manual/layouts.html
Log: LBGENERAL-23 Class packaging information is now automatically added to stack traces formatted by PatternLayout Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java Tue Sep 9 13:57:55 2008 @@ -16,6 +16,7 @@ import ch.qos.logback.classic.pattern.EnsureExceptionHandling; import ch.qos.logback.classic.pattern.ClassOfCallerConverter; import ch.qos.logback.classic.pattern.DateConverter; +import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter; import ch.qos.logback.classic.pattern.FileOfCallerConverter; import ch.qos.logback.classic.pattern.LevelConverter; import ch.qos.logback.classic.pattern.LineOfCallerConverter; @@ -89,20 +90,25 @@ defaultConverterMap.put("X", MDCConverter.class.getName()); defaultConverterMap.put("mdc", MDCConverter.class.getName()); - defaultConverterMap - .put("ex", ThrowableProxyConverter.class.getName()); + defaultConverterMap.put("ex", ThrowableProxyConverter.class.getName()); defaultConverterMap.put("exception", ThrowableProxyConverter.class .getName()); defaultConverterMap.put("throwable", ThrowableProxyConverter.class .getName()); - + + defaultConverterMap.put("xEx", ExtendedThrowableProxyConverter.class.getName()); + defaultConverterMap.put("xException", ExtendedThrowableProxyConverter.class + .getName()); + defaultConverterMap.put("xThrowable", ExtendedThrowableProxyConverter.class + .getName()); + defaultConverterMap.put("nopex", NopThrowableInformationConverter.class .getName()); defaultConverterMap.put("nopexception", NopThrowableInformationConverter.class.getName()); defaultConverterMap.put("caller", CallerDataConverter.class.getName()); - + defaultConverterMap.put("marker", MarkerConverter.class.getName()); defaultConverterMap.put("n", LineSeparatorConverter.class.getName()); @@ -111,11 +117,11 @@ public PatternLayout() { this.postCompileProcessor = new EnsureExceptionHandling(); } - + public Map<String, String> getDefaultConverterMap() { return defaultConverterMap; } - + public String doLayout(LoggingEvent event) { if (!isStarted()) { return CoreGlobal.EMPTY_STRING; Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java Tue Sep 9 13:57:55 2008 @@ -5,17 +5,18 @@ import ch.qos.logback.core.pattern.ConverterUtil; import ch.qos.logback.core.pattern.PostCompileProcessor; -public class EnsureExceptionHandling implements PostCompileProcessor<LoggingEvent> { +public class EnsureExceptionHandling implements + PostCompileProcessor<LoggingEvent> { + + // public void process(Converter head) { + // // TODO Auto-generated method stub + // + // } -// public void process(Converter head) { -// // TODO Auto-generated method stub -// -// } - /** * This implementation checks if any of the converters in the chain handles - * exceptions. If not, then this method adds a ThrowableInformationConverter - * instance to the end of the chain. + * exceptions. If not, then this method adds a + * [EMAIL PROTECTED] ExtendedThrowableProxyConverter} instance to the end of the chain. * <p> * This allows appenders using this layout to output exception information * event if the user forgets to add %ex to the pattern. Note that the @@ -30,7 +31,7 @@ public void process(Converter<LoggingEvent> head) { if (!chainHandlesThrowable(head)) { Converter<LoggingEvent> tail = ConverterUtil.findTail(head); - Converter<LoggingEvent> exConverter = new ThrowableProxyConverter(); + Converter<LoggingEvent> exConverter = new ExtendedThrowableProxyConverter(); if (tail == null) { head = exConverter; } else { @@ -44,7 +45,7 @@ * not. * * @param head - * The first element of the chain + * The first element of the chain * @return true if can handle throwables contained in logging events */ public boolean chainHandlesThrowable(Converter head) { Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicCPDCTest.java ============================================================================== --- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicCPDCTest.java (original) +++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicCPDCTest.java Tue Sep 9 13:57:55 2008 @@ -34,6 +34,24 @@ System.out.println(SystemInfo.getJavaVendor()); } +// @Test +// public void withGreenMail() { +// try { +// ServerSetup serverSetup = new ServerSetup(-1, "localhost", +// ServerSetup.PROTOCOL_SMTP); +// GreenMail greenMail = new GreenMail((ServerSetup) null); +// // greenMail.start(); +// } catch (Throwable e) { +// ThrowableProxy tp = new ThrowableProxy(e); +// ClassPackagingDataCalculator cpdc = tp.getClassPackagingDataCalculator(); +// ThrowableDataPoint[] tdpArray = tp.getThrowableDataPointArray(); +// cpdc.calculate(tdpArray); +// verify(tdpArray); +// tp.fullDump(); +// } +// } + + @Test public void smoke() throws Exception { Throwable t = new Throwable("x"); @@ -42,6 +60,7 @@ ThrowableDataPoint[] tdpArray = tp.getThrowableDataPointArray(); cpdc.calculate(tdpArray); verify(tdpArray); + tp.fullDump(); } @Test Modified: logback/trunk/logback-site/src/site/pages/manual/layouts.html ============================================================================== --- logback/trunk/logback-site/src/site/pages/manual/layouts.html (original) +++ logback/trunk/logback-site/src/site/pages/manual/layouts.html Tue Sep 9 13:57:55 2008 @@ -292,22 +292,19 @@ customized at will by tweaking the conversion pattern of <code>PatternLayout</code>. </p> - <p> - The conversion pattern of - <code>PatternLayout</code> - is closely related to the conversion pattern of the - <code>printf()</code> - function in the C programming language. A conversion pattern - is composed of literal text and format control expressions - called conversion specifiers. You are free to insert any - literal text within the conversion pattern. Each conversion - specifier starts with a percent sign (%) and is followed by - optional format modifiers, a conversion word and optional - parameters between braces. The - conversion word controls the type of data to use, e.g. - logger name, level, date, thread name. The format modifiers - control such things as field width, padding, and left or - right justification. The following is a simple example. + + <p>The conversion pattern of <code>PatternLayout</code> is closely + related to the conversion pattern of the <code>printf()</code> + function in the C programming language. A conversion pattern is + composed of literal text and format control expressions called + conversion specifiers. You are free to insert any literal text + within the conversion pattern. Each conversion specifier starts + with a percent sign (%) and is followed by optional format + modifiers, a conversion word and optional parameters between + braces. The conversion word controls the type of data to use, e.g. + logger name, level, date, thread name. The format modifiers + control such things as field width, padding, and left or right + justification. The following is a simple example. </p> <em> Example 5.1: Sample usage of a PatternLayout @@ -385,13 +382,13 @@ listed on the left column, they should be considered as aliases. </p> - <table class="bodyTable" border="0" CELLPADDING="8"> + <table class="bodyTable" border="0"> <tr> <th>Conversion Word</th> <th>Effect</th> </tr> - <tr class="b"> + <tr> <td align="center"> <b>c</b>{<em>length</em>} <br /> <b>lo</b>{<em>length</em>} <br /> @@ -399,17 +396,15 @@ </td> <td> - <p> - Used to output the name of the logger at the origin of the - logging event. + <p>Used to output the name of the logger at the origin of + the logging event. </p> - <p> - This conversion word can take an integer as first and only - option. The converter's abbreviation algorithm will - shorten the logger name, usually without significant loss - of meaning. The next table provides examples of the - abbreviation algorithm in action. + <p>This conversion word can take an integer as first and + only option. The converter's abbreviation algorithm will + shorten the logger name, usually without significant loss of + meaning. The next table provides examples of the + abbreviation algorithm in action. </p> <table class="bodyTable" border="0" cellpadding="8"> @@ -449,7 +444,8 @@ </table> </td> </tr> - <tr class="a"> + + <tr class="alt"> <td align="center"> <b>C</b>{<em>length</em>} <br /> <b>class</b>{<em>length</em>} <br /> @@ -474,12 +470,12 @@ </td> </tr> - <tr class="b"> - <td align="center"> - <b>d</b>{<em>pattern</em>} <br /> - <b>date</b>{<em>pattern</em>} <br /> - </td> - <td> + <tr> + <td align="center"> + <b>d</b>{<em>pattern</em>} <br /> + <b>date</b>{<em>pattern</em>} <br /> + </td> + <td> <p>Used to output the date of the logging event. The date conversion word may be followed by an option enclosed between braces.</p> @@ -521,7 +517,7 @@ </td> </tr> - <tr class="a"> + <tr class="alt"> <td align="center"> <b>F / file</b> </td> @@ -538,7 +534,7 @@ </td> </tr> - <tr class="b"> + <tr> <td align="center"> <b>caller{depth}</b> <b>caller{depth, evaluator-1, ... evaluator-n}</b> @@ -588,7 +584,7 @@ </td> </tr> - <tr class="a"> + <tr class="alt"> <td align="center"> <b>L / line</b> </td> @@ -607,7 +603,7 @@ </tr> - <tr class="b"> + <tr> <td align="center"> <b>m / msg / message</b> </td> @@ -617,7 +613,7 @@ </td> </tr> - <tr class="a"> + <tr class="alt"> <td align="center"> <b>M / method</b> </td> @@ -635,7 +631,7 @@ </td> </tr> - <tr class="b"> + <tr> <td align="center"> <b>n</b> </td> @@ -656,14 +652,14 @@ </tr> - <tr class="a"> + <tr class="alt"> <td align="center"> <b>p / le / level</b> </td> <td>Used to output the level of the logging event.</td> </tr> - <tr class="b"> + <tr> <td align="center"> <b>r / relative</b> @@ -677,7 +673,7 @@ </tr> - <tr class="a"> + <tr class="alt"> <td align="center"> <b>t / thread</b> </td> @@ -689,7 +685,7 @@ </tr> - <tr class="b"> + <tr> <td align="center"> <b>X</b>{<em>key</em>} <br /> <b>mdc</b>{<em>key</em>} <br /> @@ -718,7 +714,7 @@ </td> </tr> - <tr class="a"> + <tr class="alt"> <td align="center"> <b>ex</b>{<em>length</em>} <br /> <b>exception</b>{<em>length</em>} <br /> @@ -748,14 +744,14 @@ the following options: </p> <ul> - <p><em>short</em>: prints the first line of the stack trace</p> - <p><em>full</em>: prints the full stack trace</p> - <p>Any integer: prints the given number of lines of the stack trace</p> + <li><em>short</em>: prints the first line of the stack trace</li> + <li><em>full</em>: prints the full stack trace</li> + <li>Any integer: prints the given number of lines of the stack trace</li> </ul> <p>Here are some examples:</p> - <table class="bodyTable" CELLPADDING="8"> + <table class="bodyTable"> <tr class="a"> <th>Conversion Pattern</th> <th>Result</th> @@ -787,17 +783,75 @@ </tr> </table> - <p> - This conversion word can also use evaluators to test logging events - against a given criteria before creating the output. For example, - using <b>%ex{full, EX_DISPLAY_EVAL}</b> will display the full - stacktrace of the exception, only if the evaluator called <em>EX_DISPLAY_EVAL</em> - returns a <b>negative</b> answer. Evaluators are described - further down in this document. + <p>This conversion word can also use evaluators to test + logging events against a given criteria before creating the + output. For example, using <b>%ex{full, EX_DISPLAY_EVAL}</b> + will display the full stacktrace of the exception, only if + the evaluator called <em>EX_DISPLAY_EVAL</em> returns a + <b>negative</b> answer. Evaluators are described further + down in this document. </p> </td> </tr> + + <tr> + <td align="center"> + <b>xEx</b>{<em>length</em>} <br /> + <b>xException</b>{<em>length</em>} <br /> + <b>xThrowable</b>{<em>length</em>} <br /> + <br /> + <b>xEx</b>{length, evaluator-1, ..., evaluator-n} <br /> + <b>xException</b>{length, evaluator-1, ..., evaluator-n} <br /> + <b>xThrowable</b>{length, evaluator-1, ..., evaluator-n} + </td> + + <td> + <p>Same as the %exception conversion keyword with the + addition of class packaging information.</p> + + <p>At the end of each stack frame of the exception, a string + consisting of the jar file containing the relevant class + followed by the "Implementation-Version" as found in that + jar's manifest will be added. This innovative technique was + <a + href="http://macstrac.blogspot.com/2008/09/better-stack-traces-in-java-with-log4j.html">suggested + by James Strachan</a>. If the information is uncertain, then + the class packaging data will be preceded by a tilde, i.e. + the '~' character. + </p> + + <p>Here is an example:</p> + + <p class="source">java.lang.NullPointerException + at com.xyz.Wombat(Wombat.java:57) <b><span class="red">~</span>[wombat-1.3.jar:1.3]</b> + at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3] + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.5.0_06] + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.5.0_06] + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.5.0_06] + at java.lang.reflect.Method.invoke(Method.java:585) ~[na:1.5.0_06] + at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59) [junit-4.4.jar:na] + at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98) [junit-4.4.jar:na] + ...etc </p> + + <p>Logback goes to great lengths to ensure that the class + packaging information it displays is correct, even in + arbirarily complex class loader hierarchies. However, when + it is not able to guarantee the absolute correctness of the + information, then it will prefix the data with a tilde, i.e. + the '~' character. Thus, it is theoretically possible for + the printed class packaging information to differ from the + real class packaging information. So, in the above example, + given that packaging data for the Wombat class is preceded + by a tilde, it possible that the correct packaging data is + in reality [wombat.jar:1.7]. + </p> + + </td> + + + </tr> + <tr class="b"> <td align="center"> <b>nopex</b> <br /> _______________________________________________ logback-dev mailing list logback-dev@qos.ch http://qos.ch/mailman/listinfo/logback-dev