我的Java堆棧跟蹤有很多條我不關心,顯示方法調用通過代理和Spring反射方法以及類似的東西。它可以很難挑出實際來自我的代碼的堆棧跟蹤部分。 Ruby on Rails包含一個「堆棧跟蹤清理器」,您可以在其中指定堆棧跟蹤模式列表以從打印的堆棧跟蹤中忽略 - 對於Java來說,通用地做這種事情的最佳方式是什麼?從Java堆棧跟蹤中清除噪音
如果這種方法在任何地方都能正常工作,包括在Eclipse jUnit runner中,那最好。
我的Java堆棧跟蹤有很多條我不關心,顯示方法調用通過代理和Spring反射方法以及類似的東西。它可以很難挑出實際來自我的代碼的堆棧跟蹤部分。 Ruby on Rails包含一個「堆棧跟蹤清理器」,您可以在其中指定堆棧跟蹤模式列表以從打印的堆棧跟蹤中忽略 - 對於Java來說,通用地做這種事情的最佳方式是什麼?從Java堆棧跟蹤中清除噪音
如果這種方法在任何地方都能正常工作,包括在Eclipse jUnit runner中,那最好。
intellij-idea允許可定製的stack trace folding,特別適用於dynamic languages。
和Analyzing external stack traces工具。
我可以想象在日誌框架(如logback或log4j)級別上工作的一般工具/過濾器。我不認爲會有這方面的普遍支持,但我認爲這是一個好主意。我會看看,也許這不是那麼多工作。
更新:我實施filtering irrelevant stack trace lines in logs爲logback,也遵循LBCLASSIC-325。
不幸的是,intelliJ插件不再兼容。 (至少在03/17 Ubuntu的構建) – Blauhirn 2017-06-18 11:34:07
不是你正在尋找的東西(並且據我所知,沒有針對你的問題的通用解決方案,至少我從來沒有聽說過一個着名的工具來清理並從Java堆棧中提取信息) 。
無論如何,this post from July, 05, 2011 at Faux' Blog描述了一個早期階段的Java代理,其目的是豐富(而不是過濾)棧跟蹤。它提供了一個鏈接到git倉庫與mavenized項目。也許你可以從這裏走,調整他的代碼並推出自己的解決方案(誰知道,甚至可能啓動一個開源項目)。
我已經看到了,但希望我不會寫我自己的。似乎要走的路。 – bhollis 2012-03-07 21:17:47
對於log4j的:
ThrowableRendererSupport loggerRepository =
(ThrowableRendererSupport) LogManager.getLoggerRepository();
loggerRepository.setThrowableRenderer(new FilteringThrowableRenderer());
或log4j.properties:
package package1;
public class FilteringThrowableRenderer implements ThrowableRenderer {
private static final String PACKAGES_SEPARATOR = "\\s*,\\s*";
private final static String TRACE_PREFIX = "\tat ";
private static final String FILTERED_WARNING = " [Stacktrace is filtered]";
ThrowableRenderer defaultRenderer = new EnhancedThrowableRenderer();
List<String> skippedLinePrefixes;
public FilteringThrowableRenderer() {
String skippedPackagesString = "java,org"; // TODO: move it to config
String[] skippedPackages =
skippedPackagesString.trim().split(PACKAGES_SEPARATOR);
skippedLinePrefixes = new ArrayList<String>(skippedPackages.length);
for (String packageName : skippedPackages) {
skippedLinePrefixes.add(TRACE_PREFIX + packageName);
}
}
@Override
public String[] doRender(Throwable throwable) {
String[] initialTrace = defaultRenderer.doRender(throwable);
if (!skippedLinePrefixes.isEmpty()) {
List<String> result = new ArrayList<String>(initialTrace.length);
boolean filtered = false;
trace: for (String element : initialTrace) {
for (String skippedLinePrefix : skippedLinePrefixes) {
if (element.startsWith(skippedLinePrefix)) {
filtered = true;
continue trace;
}
}
result.add(element);
}
if (filtered && result.size() > 0) {
result.set(0, result.get(0) + FILTERED_WARNING);
}
return result.toArray(new String[result.size()]);
} else {
return initialTrace;
}
}
}
用代碼,使之
log4j.throwableRenderer=package1.FilteringThrowableRenderer
其實我寫了一個庫 (https://github.com/michaelgantman/Mgnt/releases/tag/1.01) 包含幾個實用程序。其中之一是我廣泛使用的通用堆棧跟蹤 過濾器,並發現它非常有用。這個類被稱爲 TextUtils,它有幾個覆蓋簽名的方法getStacktrace()。 它需要一個Throwable實例,並允許設置相關包 的包前綴。比方說,你的公司的代碼始終駐留在 與啓動包「com.plain。*」你設置這樣的前綴,併爲此
logger.info(TextUtils.getStacktrace(e, true, "com.plain."));
這會過濾掉非常巧妙所有跟蹤的無用部分離開 你用非常簡潔的stacktrace。此外,我發現它十分便利,以預先設定的 前綴,然後只需使用舒適方法
TextUtils.getStacktrace(e);
這也將這樣做。要預設前綴,只需使用方法
setRelevantPackage("com.plain.");
此外,如果你使用Spring的環境中,你可以將以下段添加到您的 Spring配置,然後你所有的設置:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="com.mgnt.utils.TextUtils"/>
<property name="targetMethod" value="setRelevantPackage"/>
<property name="arguments" value="com.plain."/>
</bean>
庫自帶寫得很好(我希望)Javadoc詳細解釋了一切。但這裏是一個小傳情:你將得到以下堆棧跟蹤:
at com.plain.BookService.listBooks()
at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke()
...
at com.plain.LoggingAspect.logging()
at sun.reflect.NativeMethodAccessorImpl.invoke0()
...
at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks()
at com.plain.web.BookController.listBooks()
,而不是
at com.plain.BookService.listBooks()
at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke()
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed()
at com.plain.LoggingAspect.logging()
at sun.reflect.NativeMethodAccessorImpl.invoke0()
at sun.reflect.NativeMethodAccessorImpl.invoke()
at sun.reflect.DelegatingMethodAccessorImpl.invoke()
at java.lang.reflect.Method.invoke()
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod()
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept()
at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks()
at com.plain.web.BookController.listBooks()
這個插件的相當不錯
https://marketplace.eclipse.org/content/grep-console
只是一個廣義的grep格式化爲Eclipse工具控制檯,所以沒有額外的依賴關係。我將所有不相關的噪音都格式化爲灰色文字。
啊是的,根據Cay Horstmann的「來自地獄的堆棧跟蹤」:https://plus.google.com/+CayHorstmann/posts/YAwGCVpLXgH – 2015-11-22 14:13:33