【问题标题】:Retrieve contents of all stack traces being printed to the console?检索正在打印到控制台的所有堆栈跟踪的内容?
【发布时间】:2016-12-23 19:10:17
【问题描述】:

我想单独记录我遇到的每个唯一错误,因为搜索十几个日志文件,每行长度为 +10k 行,既浪费时间又乏味。

我可能会捕获所有异常,但通常其他线程或库会自行处理错误,而无法自己处理它们。

有什么解决方法吗?

(例如,当调用 printStackTrace() 时的事件。)

【问题讨论】:

  • 如果您使用 log4j,您可以为您不感兴趣的包指定不同的日志级别。这样行吗?
  • 不,我需要能够获取所有抛出的异常的内容。

标签: java logging exception-handling


【解决方案1】:

有什么解决方法吗? (例如,调用 printStackTrace() 时的事件。)

Remap System.err 拦截投掷物。如果您查看Throwable.printStackTrace() 的源代码,您会发现它间接调用了System.err.println(this);

例如:

import java.io.PrintStream;

public class SpyPrintStream extends PrintStream {

    public static void main(String[] args) {
        System.setErr(new SpyPrintStream(System.err));
        System.setOut(new SpyPrintStream(System.out));
        new Exception().printStackTrace();
    }

    public SpyPrintStream(PrintStream src) {
        super(src);
    }

    @Override
    public void println(Object x) {
        if (x instanceof Throwable) {
           super.println("Our spies detected "+ x.getClass().getName());
        }
        super.println(x);
    }
}

请记住,使用此代码存在各种问题,并且在使用非标准流调用 printStackTrace 的情况下它不起作用。

如果您真的想捕获所有异常,您可以随时深入了解java.lang.instrument

我可能会捕获所有异常,但通常其他线程或库会自行处理错误,而无法自己处理它们。

大多数库要么向调用者抛出异常,要么使用日志框架。捕获异常或配置日志框架。

我想单独记录我遇到的每一个唯一错误,因为搜索十几个日志文件,每个 +10k 行的长度既浪费时间又乏味。

日志框架包含处理此问题的选项。 DuplicateMessageFilter 就是一个例子。

【讨论】:

    【解决方案2】:

    深思:

    public class DemoClass {
    
        private Map<String, Exception> myExceptions = new HashMap<>();
    
        public void demoMethod() {
            try {
                // throwing an exception for illustration
                throw new IOException("some message");
            } catch (IOException e) {
                myExceptions.putIfAbsent(e.getLocalizedMessage(), e);
    
                // actually handle the exception
                ...
            }
        }
    
        public void finished() {
            for (Exception e : myExceptions.values()) {
                e.printStackTrace();
            }
        }
    }
    

    您可以存储您尚未看到的任何异常。如果您的特定场景允许更好的方法来确保您只保存一个异常,那么您应该更喜欢 Exception.getLocalizedMessage() 的映射而不是映射

    【讨论】:

      猜你喜欢
      • 2015-06-07
      • 2010-09-18
      • 1970-01-01
      • 2013-09-21
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多