[logback-dev] svn commit: r1792 - in logback/trunk: logback-classic/src/main/java/ch/qos/logback/classic/pattern logback-classic/src/test/java/ch/qos/logback/classic/pattern logback-classic/src/test/java/ch/qos/logback/classic/pattern/lru logback-core/src/main/java/ch/qos/logback/core/helpers logback-core/src/test/java/ch/qos/logback/core/helpers
noreply.ceki at qos.ch
noreply.ceki at qos.ch
Wed Sep 3 22:28:08 CEST 2008
Author: ceki
Date: Wed Sep 3 22:28:08 2008
New Revision: 1792
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/PackageInfo.java
- copied, changed from r1790, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/PackageInfo.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/StackTraceElementProxy.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableDataPoint.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToDataPointArray.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/helpers/
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/helpers/ThrowableToDataPointTest.java
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/PackageInfo.java
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LRUCache.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableInformationConverter.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/LRUCacheTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/Simulator.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/UtilTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/lru/T_LRUCache.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToStringArray.java
Log:
LBGENERAL-23
Reworking Throwable to string conversion. Instead of simply converting StackTraceElement
(STE) array into just strings, we convert them to a little more sophisticated objects,
namely ThrowableDataPoints which support PackageInformation.
This is ongoing work, unit test may not pass.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LRUCache.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LRUCache.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LRUCache.java Wed Sep 3 22:28:08 2008
@@ -40,6 +40,8 @@
}
List<K> keyList() {
- return new ArrayList<K>(keySet());
+ ArrayList<K> al = new ArrayList<K>();
+ al.addAll(keySet());
+ return al;
}
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableInformationConverter.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableInformationConverter.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableInformationConverter.java Wed Sep 3 22:28:08 2008
@@ -98,6 +98,7 @@
int length = (lengthOption > stringRep.length) ? stringRep.length
: lengthOption;
+ // an evaluator match will cause stack printing to be skipped
if (evaluatorList != null) {
boolean printStack = true;
for (int i = 0; i < evaluatorList.size(); i++) {
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java Wed Sep 3 22:28:08 2008
@@ -15,6 +15,8 @@
import org.slf4j.Marker;
+import ch.qos.logback.core.helpers.PackageInfo;
+
/**
*
* @author James Strachan
@@ -77,12 +79,14 @@
* Uses the context class path or the current global class loader to deduce
* the file that the given class name comes from
*/
- static String getJarNameOfClass(String className) {
+ static String getJarNameOfClass0(String className) {
try {
Class type = findClass(className);
if (type != null) {
URL resource = type.getClassLoader().getResource(
type.getName().replace('.', '/') + ".class");
+
+
// "jar:file:/C:/java/../repo/groupId/artifact/1.3/artifact-1.3.jar!/com/some/package/Some.class
if (resource != null) {
String text = resource.toString();
@@ -107,7 +111,41 @@
}
return "na";
}
-
+
+ static String getJarNameOfClass1(String className) {
+ try {
+ Class type = findClass(className);
+ if (type != null) {
+
+
+ // file:/C:/java/maven-2.0.8/repo/com/icegreen/greenmail/1.3/greenmail-1.3.jar
+ URL resource = type.getProtectionDomain().getCodeSource().getLocation();
+ if (resource != null) {
+ String text = resource.toString();
+ // now lets remove all but the file name
+ int idx = text.lastIndexOf('/');
+ if (idx > 0) {
+ text = text.substring(idx + 1);
+ }
+ idx = text.lastIndexOf('\\');
+ if (idx > 0) {
+ text = text.substring(idx + 1);
+ }
+ return text;
+ }
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ return "na";
+ }
+
+
+
+ static String getJarNameOfClass(String className) {
+ return getJarNameOfClass1(className);
+ }
+
static private Class findClass(String className) {
try {
return Thread.currentThread().getContextClassLoader()
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/LRUCacheTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/LRUCacheTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/LRUCacheTest.java Wed Sep 3 22:28:08 2008
@@ -5,8 +5,6 @@
import java.util.LinkedList;
import java.util.List;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -15,17 +13,9 @@
public class LRUCacheTest {
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
@Test
public void smoke() {
+
LRUCache<String, String> cache = new LRUCache<String, String>(2);
cache.put("a", "a");
cache.put("b", "b");
@@ -38,34 +28,84 @@
@Test
public void typicalScenarioTest() {
- int simulationLen = 1000 * 20;
- int cacheSize = 500;
- int worldSize = 10000;
+ int simulationLen = 1000 * 10;
+ int cacheSize = 100;
+ int worldSize = 1000;
doScenario(simulationLen, cacheSize, worldSize);
}
@Test
public void scenarioCoverageTest() {
- int simulationLen = 1000 * 20;
- int[] cacheSizes = new int[] {1,5,10,100,1000,5000,10000};
- int[] worldSizes = new int[] {1,10,100,1000,20000};
+ int simulationLen = 1000 * 10;
+
+ int[] cacheSizes = new int[] { 1, 10, 100};
+ // tests with large worldSizes are slow because with a large
+ // world size the probability of a cache miss is high.
+ int[] worldSizes = new int[] { 1, 10, 100 };
+
for (int i = 0; i < cacheSizes.length; i++) {
for (int j = 0; j < worldSizes.length; j++) {
- System.out.println("cacheSize="+cacheSizes[i]+", worldSize="+worldSizes[j]);
doScenario(simulationLen, cacheSizes[i], worldSizes[j]);
}
}
}
- void doScenario(int simulationLen, int chacheSize, int worldSize) {
- int cacheSize = 500;
+ void doScenario(int simulationLen, int cacheSize, int worldSize) {
int get2PutRatio = 10;
-
- Simulator simulator = new Simulator(worldSize, get2PutRatio);
+ Simulator simulator = new Simulator(worldSize, get2PutRatio, false);
List<Event> scenario = simulator.generateScenario(simulationLen);
LRUCache<String, String> lruCache = new LRUCache<String, String>(cacheSize);
T_LRUCache<String> tlruCache = new T_LRUCache<String>(cacheSize);
+ long start = System.nanoTime();
simulator.simulate(scenario, lruCache, tlruCache);
- assertEquals(tlruCache.ketList(), lruCache.keyList());
+ //assertEquals(tlruCache.keyList(), lruCache.keyList());
+ long end = System.nanoTime();
+ System.out.println("cacheSize=" + cacheSize + ", worldSize=" + worldSize
+ + ", elapsed time=" + ((end - start) / (1000 * 1000)) + " in millis");
+ }
+
+
+
+ @Test
+ @Ignore // slow test that is known to pass
+ public void multiThreadedScenario() throws InterruptedException {
+ int cacheSize = 100;
+ int worldSize = cacheSize*2;
+ LRUCache<String, String> lruCache = new LRUCache<String, String>(cacheSize);
+ T_LRUCache<String> tlruCache = new T_LRUCache<String>(cacheSize);
+ SimulatorRunnable[] simulatorArray = new SimulatorRunnable[5];
+ for(int i = 0; i < simulatorArray.length; i++) {
+ simulatorArray[i] = new SimulatorRunnable(lruCache, tlruCache, worldSize);
+ }
+ for(int i = 0; i < simulatorArray.length; i++) {
+ simulatorArray[i].start();
+ }
+ for(int i = 0; i < simulatorArray.length; i++) {
+ simulatorArray[i].join();
+ }
+ assertEquals(tlruCache.keyList(), lruCache.keyList());
+ }
+
+ private class SimulatorRunnable extends Thread {
+
+ LRUCache<String, String> lruCache;
+ T_LRUCache<String> tlruCache;
+ int worldSize;
+
+ SimulatorRunnable(LRUCache<String, String> lruCache, T_LRUCache<String> tlruCache, int worldSize) {
+ this.lruCache = lruCache;
+ this.tlruCache = tlruCache;
+ this.worldSize = worldSize;
+ }
+
+ public void run() {
+ int get2PutRatio = 10;
+ int simulationLen = 1000*50;
+ Simulator simulator = new Simulator(worldSize, get2PutRatio, true);
+ List<Event> scenario = simulator.generateScenario(simulationLen);
+ simulator.simulate(scenario, lruCache, tlruCache);
+ System.out.println("done");
+ }
}
+
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/Simulator.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/Simulator.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/Simulator.java Wed Sep 3 22:28:08 2008
@@ -11,28 +11,29 @@
public class Simulator {
-
Random random;
-
+
int worldSize;
int get2PutRatio;
-
- public Simulator(int worldSize, int get2PutRatio) {
+ boolean multiThreaded;
+
+ public Simulator(int worldSize, int get2PutRatio, boolean multiThreaded) {
this.worldSize = worldSize;
this.get2PutRatio = get2PutRatio;
long seed = System.nanoTime();
- System.out.println("seed is "+seed);
+ // System.out.println("seed is "+seed);
random = new Random(seed);
+ this.multiThreaded = multiThreaded;
}
-
+
public List<Event> generateScenario(int len) {
List<Event> scenario = new ArrayList<Event>();
-
- for(int i = 0; i < len; i++) {
-
+
+ for (int i = 0; i < len; i++) {
+
int r = random.nextInt(get2PutRatio);
boolean put = false;
- if(r == 0) {
+ if (r == 0) {
put = true;
}
r = random.nextInt(worldSize);
@@ -41,30 +42,40 @@
}
return scenario;
}
-
- public void simulate(List<Event> scenario, LRUCache<String, String> lruCache, T_LRUCache<String> tlruCache) {
- for(Event<String> e: scenario) {
- if(e.put) {
+
+ public void simulate(List<Event> scenario, LRUCache<String, String> lruCache,
+ T_LRUCache<String> tlruCache) {
+ for (Event<String> e : scenario) {
+ if (e.put) {
lruCache.put(e.k, e.k);
tlruCache.put(e.k);
} else {
+ @SuppressWarnings("unused")
String r0 = lruCache.get(e.k);
+ @SuppressWarnings("unused")
String r1 = tlruCache.get(e.k);
- if(r0 != null) {
- assertEquals(r0, e.k);
+ if (!multiThreaded) {
+ // if the simulation is used in a multi-threaded
+ // context, then the state of lruCache may be different than
+ // that of tlruCache. In single threaded mode, they should
+ // return the same values all the time
+ if (r0 != null) {
+ assertEquals(r0, e.k);
+ }
+ assertEquals(r0, r1);
}
- assertEquals(r0, r1);
}
}
}
-
-// void compareAndDumpIfDifferent(LRUCache<String, String> lruCache, T_LRUCache<String> tlruCache) {
-// lruCache.dump();
-// tlruCache.dump();
-// if(!lruCache.keyList().equals(tlruCache.ketList())) {
-// lruCache.dump();
-// tlruCache.dump();
-// throw new AssertionFailedError("s");
-// }
-// }
+
+ // void compareAndDumpIfDifferent(LRUCache<String, String> lruCache,
+ // T_LRUCache<String> tlruCache) {
+ // lruCache.dump();
+ // tlruCache.dump();
+ // if(!lruCache.keyList().equals(tlruCache.ketList())) {
+ // lruCache.dump();
+ // tlruCache.dump();
+ // throw new AssertionFailedError("s");
+ // }
+ // }
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/UtilTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/UtilTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/UtilTest.java Wed Sep 3 22:28:08 2008
@@ -4,9 +4,10 @@
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
+import ch.qos.logback.core.helpers.PackageInfo;
+
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetup;
@@ -37,7 +38,7 @@
PackageInfo pi = Util.getPackageInfo(className);
System.out.println(" at " + className + "." + ste.getMethodName()
+ "(" + ste.getFileName() + ":" + ste.getLineNumber() + ") ["
- + pi.jarName + ":" + pi.version + "]");
+ + pi.getJarName() + ":" + pi.getVersion() + "]");
}
}
}
@@ -68,17 +69,16 @@
}
@Test
- @Ignore
public void perfTest() {
int len = 1000;
loop(len, false);
double d0 = loop(len, false);
- System.out.println("false " + d0);
+ System.out.println("ve=false " + d0);
loop(len, true);
double d1 = loop(len, true);
- System.out.println("false " + d1);
+ System.out.println("ve=true " + d1);
}
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/lru/T_LRUCache.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/lru/T_LRUCache.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/pattern/lru/T_LRUCache.java Wed Sep 3 22:28:08 2008
@@ -31,7 +31,7 @@
}
@SuppressWarnings("unchecked")
- public void put(K k) {
+ synchronized public void put(K k) {
sequenceNumber++;
T_Entry<K> te = getEntry(k);
if (te != null) {
@@ -47,7 +47,7 @@
}
@SuppressWarnings("unchecked")
- public K get(K k) {
+ synchronized public K get(K k) {
T_Entry<K> te = getEntry(k);
if (te == null) {
return null;
@@ -58,7 +58,7 @@
}
}
- public List<K> ketList() {
+ synchronized public List<K> keyList() {
List<K> keyList = new ArrayList<K>();
for (T_Entry<K> e : cacheList) {
keyList.add(e.k);
@@ -86,3 +86,4 @@
}
}
+
Copied: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/PackageInfo.java (from r1790, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/PackageInfo.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/PackageInfo.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/PackageInfo.java Wed Sep 3 22:28:08 2008
@@ -1,13 +1,29 @@
-package ch.qos.logback.classic.pattern;
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.helpers;
public class PackageInfo {
-
String jarName;
String version;
- PackageInfo(String jarName, String version) {
+ public PackageInfo(String jarName, String version) {
this.jarName = jarName;
this.version = version;
}
+
+ public String getJarName() {
+ return jarName;
+ }
+
+ public String getVersion() {
+ return version;
+ }
}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/StackTraceElementProxy.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/StackTraceElementProxy.java Wed Sep 3 22:28:08 2008
@@ -0,0 +1,25 @@
+package ch.qos.logback.core.helpers;
+
+public class StackTraceElementProxy {
+
+ final StackTraceElement ste;
+ private String steAsString;
+ private PackageInfo pi;
+
+ StackTraceElementProxy(StackTraceElement ste) {
+ this.ste = ste;
+ }
+
+ public String getSTEAsString() {
+ if(steAsString == null) {
+ steAsString = "\tat "+ste.toString();
+ }
+ return steAsString;
+ }
+
+ public PackageInfo getPI() {
+ // compute pi from ste
+ return pi;
+ }
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableDataPoint.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableDataPoint.java Wed Sep 3 22:28:08 2008
@@ -0,0 +1,45 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.helpers;
+
+public class ThrowableDataPoint {
+
+ enum ThrowableDataPointType {
+ RAW, STEP;
+ }
+
+ String rawString;
+ StackTraceElementProxy step;
+ final ThrowableDataPointType type;
+
+ ThrowableDataPoint(String rawString) {
+ this.rawString = rawString;
+ this.type = ThrowableDataPointType.RAW;
+ }
+
+ ThrowableDataPoint(StackTraceElement ste) {
+ this.step = new StackTraceElementProxy(ste);
+ this.type = ThrowableDataPointType.STEP;
+ }
+
+ public ThrowableDataPointType getType() {
+ return type;
+ }
+
+ @Override
+ public String toString() {
+ switch(type) {
+ case RAW: return rawString;
+ case STEP: return step.getSTEAsString();
+ }
+ throw new IllegalStateException("Unreachable code");
+ }
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToDataPointArray.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToDataPointArray.java Wed Sep 3 22:28:08 2008
@@ -0,0 +1,87 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.helpers;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import ch.qos.logback.core.CoreGlobal;
+
+public class ThrowableToDataPointArray {
+
+ static final ThrowableDataPoint[] TEMPLATE_ARRAY = new ThrowableDataPoint[0];
+
+ public static ThrowableDataPoint[] convert(Throwable t) {
+ List<ThrowableDataPoint> tdpList = new LinkedList<ThrowableDataPoint>();
+ extract(tdpList, t, null);
+ return tdpList.toArray(TEMPLATE_ARRAY);
+ }
+
+ private static void extract(List<ThrowableDataPoint> tdpList, Throwable t,
+ StackTraceElement[] parentSTE) {
+ StackTraceElement[] ste = t.getStackTrace();
+ final int numberOfcommonFrames = findNumberOfCommonFrames(ste, parentSTE);
+
+ tdpList.add(firstLineToDataPoint(t, parentSTE));
+ for (int i = 0; i < (ste.length - numberOfcommonFrames); i++) {
+ tdpList.add(new ThrowableDataPoint(ste[i]));
+ }
+
+ // buf.append("\tat ");
+
+
+ if (numberOfcommonFrames != 0) {
+ tdpList.add(new ThrowableDataPoint("\t... "+numberOfcommonFrames
+ + " common frames omitted"));
+ }
+
+ Throwable cause = t.getCause();
+ if (cause != null) {
+ extract(tdpList, cause, ste);
+ }
+ }
+
+ private static ThrowableDataPoint firstLineToDataPoint(Throwable t,
+ StackTraceElement[] parentSTE) {
+ String prefix = "";
+ if (parentSTE != null) {
+ prefix = CoreGlobal.CAUSED_BY;
+ }
+
+ String result = prefix + t.getClass().getName();
+ if (t.getMessage() != null) {
+ result += ": " + t.getMessage();
+ }
+ return new ThrowableDataPoint(result);
+ }
+
+ private static int findNumberOfCommonFrames(StackTraceElement[] ste,
+ StackTraceElement[] parentSTE) {
+ if (parentSTE == null) {
+ return 0;
+ }
+
+ int steIndex = ste.length - 1;
+ int parentIndex = parentSTE.length - 1;
+ int count = 0;
+ while (steIndex >= 0 && parentIndex >= 0) {
+ if (ste[steIndex].equals(parentSTE[parentIndex])) {
+ count++;
+ } else {
+ break;
+ }
+ steIndex--;
+ parentIndex--;
+ }
+ return count;
+ }
+
+}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToStringArray.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToStringArray.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToStringArray.java Wed Sep 3 22:28:08 2008
@@ -18,31 +18,22 @@
String[] result;
StackTraceElement[] ste = t.getStackTrace();
- final int commonFrames = findCommonFrames(ste, parentSTE);
+ final int numberOfcommonFrames = findNumberOfCommonFrames(ste, parentSTE);
final String[] firstArray;
- if (commonFrames == 0) {
+ if (numberOfcommonFrames == 0) {
firstArray = new String[ste.length + 1];
} else {
- firstArray = new String[ste.length - commonFrames + 2];
+ firstArray = new String[ste.length - numberOfcommonFrames + 2];
}
- String prefix = "";
- if (parentSTE != null) {
- prefix = CoreGlobal.CAUSED_BY;
- }
-
- firstArray[0] = prefix + t.getClass().getName();
- if (t.getMessage() != null) {
- firstArray[0] += ": " + t.getMessage();
- }
-
- for (int i = 0; i < (ste.length - commonFrames); i++) {
+ firstArray[0] = formatFirstLine(t, parentSTE);
+ for (int i = 0; i < (ste.length - numberOfcommonFrames); i++) {
firstArray[i + 1] = ste[i].toString();
}
- if (commonFrames != 0) {
- firstArray[firstArray.length - 1] = commonFrames
+ if (numberOfcommonFrames != 0) {
+ firstArray[firstArray.length - 1] = numberOfcommonFrames
+ " common frames omitted";
}
@@ -60,7 +51,20 @@
return result;
}
- private static int findCommonFrames(StackTraceElement[] ste,
+ private static String formatFirstLine(Throwable t, StackTraceElement[] parentSTE) {
+ String prefix = "";
+ if (parentSTE != null) {
+ prefix = CoreGlobal.CAUSED_BY;
+ }
+
+ String result = prefix + t.getClass().getName();
+ if (t.getMessage() != null) {
+ result += ": " + t.getMessage();
+ }
+ return result;
+ }
+
+ private static int findNumberOfCommonFrames(StackTraceElement[] ste,
StackTraceElement[] parentSTE) {
if (parentSTE == null) {
return 0;
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/helpers/ThrowableToDataPointTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/helpers/ThrowableToDataPointTest.java Wed Sep 3 22:28:08 2008
@@ -0,0 +1,81 @@
+package ch.qos.logback.core.helpers;
+
+import static org.junit.Assert.*;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import ch.qos.logback.core.Layout;
+
+public class ThrowableToDataPointTest {
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ public void verify(Throwable t) {
+ t.printStackTrace(pw);
+
+ ThrowableDataPoint[] tdpArray = ThrowableToDataPointArray.convert(t);
+ StringBuilder sb = new StringBuilder();
+ for (ThrowableDataPoint tdp : tdpArray) {
+ sb.append(tdp.toString());
+ sb.append(Layout.LINE_SEP);
+ }
+ String expected = sw.toString();
+ String result = sb.toString().replace("common frames omitted", "more");
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void smoke() {
+ Exception e = new Exception("smoke");
+ verify(e);
+ }
+
+ @Test
+ public void nested() {
+ Exception w = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ w = new Exception("wrapping", e);
+ }
+ verify(w);
+ }
+
+ @Test
+ public void multiNested() {
+ Exception w = null;
+ try {
+ someOtherMethod();
+ } catch (Exception e) {
+ w = new Exception("wrapping", e);
+ }
+ verify(w);
+ }
+
+ void someMethod() throws Exception {
+ throw new Exception("someMethod");
+ }
+
+ void someOtherMethod() throws Exception {
+ try {
+ someMethod();
+ } catch (Exception e) {
+ throw new Exception("someOtherMethod", e);
+ }
+ }
+}
More information about the logback-dev
mailing list