log4j2-为特定软件包配置stderr重定向/忽略

时间:2018-10-24 15:00:16

标签: java logging junit log4j2 stderr

我在测试中使用的是第三方库。 该库将stderr的异常打印出来,并显示在控制台中。

我想做的就是忽略它们。

我能够编写一个Java黑客代码来拦截stderr

System.setErr(new PrintStream(new OutputStream() { public void write(int b) { } }));

但是这将在运行junit时禁用所有stderr-我只想从特定软件包中禁用stderr。

我有一个log4j2-test.xml用于我的Junit,但找不到任何示例来说明如何在软件包级别上控制stderr。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

解决此问题的另一种欺骗方法是为错误流提供自己的实现。然后,此错误流在内部创建一个异常,并使用该异常查看原始异常的打印位置。当然,这是对异常的滥用。

“简单”的实现是:

    System.setErr(new PrintStream(new OutputStream() {
        @Override
        public void write(byte[] b, int off, int len) throws IOException {
            Exception e = new Exception();
            StackTraceElement[] elements = e.getStackTrace();
            boolean hasSeenPrintStackTrace = false;
            for (int i = 0; i < elements.length; i++) {
                if (
                    elements[i].getClassName().equals("java.lang.Throwable") &&
                    elements[i].getMethodName().equals("printStackTrace")
                ) {
                    hasSeenPrintStackTrace = true;
                } else {
                    if (hasSeenPrintStackTrace) {
                        if (
                            elements[i].getClassName().equals("me.ferrybig.testpackage.ExceptionTester") &&
                            elements[i].getMethodName().equals("log1")
                        ) {
                            return;
                        }
                    }
                }
            }
            System.out.write(b, off, len);
        }

        @Override
        public void write(byte[] b) throws IOException {
            // TODO copy above implementation to here, exceptions printing only seems to use the above method
            System.out.write(b);
        }
        public void write(int b) {
            // TODO copy above implementation to here, exceptions printing only seems to use the above method
            System.out.write(b);
        }
    }));

上面的代码基本上遵循所有堆栈跟踪元素,直到找到java.lang.Throwable类和printStackTrace方法为止。从这一点开始,它设置一个布尔标志,以便它可以检查紧随其后的 all 帧,并扫描它们是否包含特定的类和方法组合。然后将其用于过滤该写出,因此不会最终输出。

完整的演示类:http://tpcg.io/5xnlZ7