【问题标题】:Cleaning noise out of Java stack traces从 Java 堆栈跟踪中清除噪音
【发布时间】:2012-03-07 17:51:59
【问题描述】:

我的 Java 堆栈跟踪有很多我不关心的条目,显示通过代理和 Spring 反射方法的方法调用和类似的东西。很难从我的代码中挑选出堆栈跟踪的部分。 Ruby on Rails 包含一个“堆栈跟踪清理器”,您可以在其中指定要从打印的堆栈跟踪中省略的堆栈跟踪模式列表 - 对于 Java,普遍而言,执行此类操作的最佳方法是什么?

如果这在任何地方都有效,包括在 Eclipse jUnit 运行器中,那将是最好的。

【问题讨论】:

标签: java exception stack-trace


【解决方案1】:

允许自定义stack trace folding,特别适用于dynamic languages


(来源:jetbrains.com

还有一个Analyzing external stack traces 工具。

我可以想象在日志框架(如)级别上工作的通用工具/过滤器。我认为对此没有任何普遍支持,但我认为实现这一点是个好主意。我去看看,可能工作量不大。

更新:我为 实现了filtering irrelevant stack trace lines in logs,也关注LBCLASSIC-325

【讨论】:

  • 很遗憾,intelliJ 插件不再兼容。 (至少在 03/17 ubuntu 版本中)
【解决方案2】:

有一个偏好堆栈跟踪过滤模式(查看 java > junit 或在偏好中搜索stacktrace) .您可以忽略包(也可以使用通配符)、类或方法。是否适用于直接测试调用(通过Test 运行),不适用于antmaven 等命令行运行。

【讨论】:

  • 谢谢!这绝对解决了我的 jUnit 插件问题。
【解决方案3】:

我实际上编写了一个开源库 MgntUtils(可在 Githubmaven central 获得) 包含几个实用程序。这是关于图书馆文章的链接:MgntUtils Open Source Java library。其中一个实用程序是通用堆栈跟踪 我广泛使用并发现它非常有用的过滤器。该类被称为 TextUtils,它有方法 getStacktrace() 和几个被覆盖的签名。 它需要一个 Throwable 实例并允许设置包的包前缀 相关的。假设您公司的代码始终驻留在以下包中 以“com.plain.*”开头,所以你设置了这样的前缀并执行此操作

logger.info(TextUtils.getStacktrace(e, true, "com.plain."));

这将非常巧妙地过滤掉痕迹中所有无用的部分 你有非常简洁的堆栈跟踪。我还发现预设 前缀,然后只需使用方便的方法

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()

【讨论】:

  • 很棒的图书馆! log4j2 中有一个类似的功能可以从堆栈跟踪中排除包。
  • @gaurav - 首先感谢。另外,如果您对此有什么要说的,我会对有关该库的更详细的反馈非常感兴趣。请在 LinkedIn (linkedin.com/in/michael-gantman-9661521) 上查找我,如果您可以给我写更多信息,请
【解决方案4】:

对于 log4j:

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;
        }
    }
}

使用代码启用它:

ThrowableRendererSupport loggerRepository =
    (ThrowableRendererSupport) LogManager.getLoggerRepository();
loggerRepository.setThrowableRenderer(new FilteringThrowableRenderer());

或使用 log4j.properties:

log4j.throwableRenderer=package1.FilteringThrowableRenderer

【讨论】:

    【解决方案5】:

    这个插件不错

    https://marketplace.eclipse.org/content/grep-console
    

    只是一个用于 Eclipse 控制台的通用 grep 格式化实用程序,因此没有额外的依赖项。我将所有不相关的噪音都格式化为灰色文本。

    【讨论】:

      【解决方案6】:

      不完全是您正在寻找的东西(而且,据我所知,没有针对您的问题的通用解决方案,至少我从未听说过有名的工具可以从 Java 堆栈跟踪中清理和提取信息)。

      无论如何,this post from July, 05, 2011 at Faux' Blog 描述了一个早期阶段的 Java 代理,其目的是丰富(而不是过滤)堆栈跟踪。它甚至提供了一个带有 mavenized 项目的 git 存储库的链接。也许你可以从这里开始,调整他的代码并推出你自己的解决方案(谁知道呢,甚至可能开始一个开源项目)。

      【讨论】:

      • 我已经看到了,但希望我不必自己写。似乎是要走的路。
      猜你喜欢
      • 1970-01-01
      • 2021-12-06
      • 2016-03-07
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-25
      相关资源
      最近更新 更多