faster implementation of the log renderer

This commit is contained in:
Alex Huang 2011-06-22 15:25:27 -07:00
parent be5707b26e
commit 47f114ad96
1 changed files with 13 additions and 85 deletions

View File

@ -18,13 +18,9 @@
package com.cloud.utils.log;
import java.io.File;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.spi.ThrowableRenderer;
@ -70,22 +66,20 @@ public class CglibThrowableRenderer implements ThrowableRenderer {
@Override
public String[] doRender(final Throwable th) {
try {
Object[] noArgs = null;
ArrayList<String> lines = new ArrayList<String>();
Throwable throwable = th;
lines.add(throwable.toString());
Map classMap = new HashMap();
int start = 0;
do {
Object[] elements = (Object[])getStackTraceMethod.invoke(throwable, noArgs);
StackTraceElement[] elements = throwable.getStackTrace();
for (int i = 0; i < elements.length - start; i++) {
if (elements[i] instanceof StackTraceElement) {
StackTraceElement stack = (StackTraceElement)elements[i];
if (stack.getFileName().equals("<generated>") || stack.getFileName().equals("MethodProxy.java")) {
continue;
}
StackTraceElement element = elements[i];
String filename = element.getFileName();
String method = element.getMethodName();
if ((filename != null && filename.equals("<generated>")) || (method != null && method.equals("invokeSuper"))) {
continue;
}
lines.add(formatElement(elements[i], classMap));
lines.add("\tat " + element.toString());
}
if (start != 0) {
lines.add("\t... " + start + " more");
@ -98,81 +92,15 @@ public class CglibThrowableRenderer implements ThrowableRenderer {
} while (throwable != null);
return lines.toArray(new String[lines.size()]);
} catch (Exception ex) {
PrintWriter pw = new PrintWriter(System.err);
ex.printStackTrace(pw);
pw = new PrintWriter(System.out);
ex.printStackTrace(pw);
ex.printStackTrace();
return null;
}
}
/**
* Format one element from stack trace.
*
* @param element element, may not be null.
* @param classMap map of class name to location.
* @return string representation of element.
*/
private String formatElement(final Object element, final Map classMap) {
StringBuffer buf = new StringBuffer("\tat ");
buf.append(element);
try {
String className = getClassNameMethod.invoke(element, (Object[])null).toString();
Object classDetails = classMap.get(className);
if (classDetails != null) {
buf.append(classDetails);
} else {
Class cls = findClass(className);
int detailStart = buf.length();
buf.append('[');
try {
CodeSource source = cls.getProtectionDomain().getCodeSource();
if (source != null) {
URL locationURL = source.getLocation();
if (locationURL != null) {
//
// if a file: URL
//
if ("file".equals(locationURL.getProtocol())) {
String path = locationURL.getPath();
if (path != null) {
//
// find the last file separator character
//
int lastSlash = path.lastIndexOf('/');
int lastBack = path.lastIndexOf(File.separatorChar);
if (lastBack > lastSlash) {
lastSlash = lastBack;
}
//
// if no separator or ends with separator (a directory)
// then output the URL, otherwise just the file name.
//
if (lastSlash <= 0 || lastSlash == path.length() - 1) {
buf.append(locationURL);
} else {
buf.append(path.substring(lastSlash + 1));
}
}
} else {
buf.append(locationURL);
}
}
}
} catch (SecurityException ex) {
}
buf.append(':');
Package pkg = cls.getPackage();
if (pkg != null) {
String implVersion = pkg.getImplementationVersion();
if (implVersion != null) {
buf.append(implVersion);
}
}
buf.append(']');
classMap.put(className, buf.substring(detailStart));
}
} catch (Exception ex) {
}
return buf.toString();
}
/**
* Find class given class name.
*