问题
I want the Java ConsoleHandler to use System.out instead of err, so I implemented my own handler that calls the protected void setOutputStream(OutputStream) of the parent StreamHandler class:
public class ConsoleHandler extends java.util.logging.ConsoleHandler {
public ConsoleHandler() {
setOutputStream(System.out); // or System.err
setLevel(Level.ALL);
}
}
I remove the default console logger from and add my own to the root logger:
Logger l = Logger.getLogger("");
for (Handler h : l.getHandlers())
l.removeHandler(h);
l.addHandler(new ConsoleHandler());
System.out.println("OUT");
System.err.println("ERR");
Problem: "OUT" is always printed, but "ERR" never, independent of the output stream I set in my ConsoleHandler constructor.
回答1:
The stacktrace (printed to System.err) is not printed any more, without my changes it is printed as usual
This is because setOutputStream closes the previously assigned System.err stream. This is a known issue filed under JDK-4827381: Invoking ConsoleHandler.setOutputStream(...) closes System.err. What should have happened with that bug report is that the StreamHandler.setOutputStream should call Handler.close instead of flushAndClose().
You need to wrap the existing System.err stream with a proxy that doesn't allow the stream to be closed. Or just extend StreamHandler and use the constructor that takes an 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();
}
}
来源:https://stackoverflow.com/questions/51641805/using-consolehandler-with-own-printstream-suppresses-system-err