将ConsoleHandler与自己的PrintStream一起使用会抑制System.err

时间:2018-08-01 20:29:44

标签: java java.util.logging

我希望Java ConsoleHandler使用System.out而不是err,所以我实现了自己的处理程序,该处理程序调用父protected void setOutputStream(OutputStream)类的StreamHandler

public class ConsoleHandler extends java.util.logging.ConsoleHandler {

    public ConsoleHandler() {

        setOutputStream(System.out); // or System.err
        setLevel(Level.ALL);
    }
}

我从中删除默认的控制台记录器,并将自己的添加到根记录器:

Logger l = Logger.getLogger("");
for (Handler h : l.getHandlers())
    l.removeHandler(h);
l.addHandler(new ConsoleHandler());

System.out.println("OUT");
System.err.println("ERR");

问题:始终打印“ OUT”,而永远不会打印“ ERR”,与我在ConsoleHandler构造函数中设置的输出流无关。

1 个答案:

答案 0 :(得分:1)

  

不再打印stacktrace(打印到System.err),没有我的更改,它照常打印

这是因为setOutputStream closes the previously assigned System.err stream。这是JDK-4827381: Invoking ConsoleHandler.setOutputStream(...) closes System.err下的一个已知问题。该错误报告应该发生的是,StreamHandler.setOutputStream应该调用Handler.close而不是flushAndClose()

您需要使用不允许关闭流的代理包装现有的System.err流。或者只是扩展StreamHandler并使用采用OutputStream的构造函数。

public class OutConsoleHandler extends StreamHandler {

   public OutConsoleHandler() {
        super(System.out, new SimpleFormatter());
        //TODO: Read level,filter,encoding from LogManager.
   }

    @Override
    public void publish(LogRecord record) {
        super.publish(record);
        super.flush();
    }

    @Override
    public void close() {
        super.flush();
    }
}