在较大的程序中,我使用静态java.util.logging.Logger
实例,但重定向System.err
连续到几个不同的文件。这Logger
第二次尝试重定向时无法记录System.err
.
这是一个显示问题的测试程序:
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.logging.Logger;
class TestRedirect {
static final Logger logger = Logger.getLogger("test");
public static void main(String[] args) throws FileNotFoundException {
for (int i = 1; i <= 2; i++) {
TestRedirect ti = new TestRedirect();
ti.test(i);
}
}
void test(int i) throws FileNotFoundException {
PrintStream filePrintStream = new PrintStream("test" + i + ".log");
PrintStream stderr = System.err; // Save stderr stream.
System.setErr(filePrintStream); // Redirect stderr to file.
System.err.println("about to log " + i);
logger.info("at step " + i);
System.setErr(stderr); // Restore stderr stream.
filePrintStream.close();
}
}
这是输出:
测试1.log:
about to log 1
Jan 28, 2014 4:34:20 PM TestRedirect test
INFO: at step 1
测试2.日志:
about to log 2
我以为我会看到一个Logger
- 生成的消息测试2.log以及。为什么Logger
停止工作,我能做些什么呢?
默认情况下,JRE 配置为在根记录器上加载 ConsoleHandler。默认情况下,您的日志消息将传输到根记录器处理程序。根记录器处理程序是按需加载的。在您当前的程序中,根记录器 ConsoleHandler 的延迟加载正在捕获您的第一个重定向的 System.err。之后,根记录器处理程序永远不会重新加载,这就是为什么您永远不会在日志 2 中看到日志消息的原因。加上第一个重定向流已关闭,因此现在根 ConsoleHandler 正在写入关闭的流。
为了证明这一点,请将以下内容添加为测试用例主方法的第一行并运行该程序。
Logger.getLogger("").getHandlers(); //Force load root logger handlers.
Logger.getLogger("").removeHandler((Handler) null);
您会看到现在没有记录任何记录器消息。如果您好奇为什么会这样,您可以阅读java.util.logging.LogManager$RootLogger
源代码了解详细信息。
你需要做的是创建一个流处理器 http://docs.oracle.com/javase/7/docs/api/java/util/logging/StreamHandler.html使用重定向的 System.err 流,然后add http://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#addHandler%28java.util.logging.Handler%29 and remove http://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#removeHandler%28java.util.logging.Handler%29来自记录器的 StreamHandler。您还可以切换使用父处理程序 http://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#setUseParentHandlers%28boolean%29在您的记录器配置上以避免写入原始 System.err。
Another possible solution would be to find all ConsoleHandler instances. Remove and close all of them. Perform the remap System.err. Then create and attach new ConsoleHandlers.
JDK 方面,ConsoleHandler 和 ErrorManager 应该被设计为使用java.io.FileDescriptor http://docs.oracle.com/javase/7/docs/api/java/io/FileDescriptor.html永远不会被重定向。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)