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.
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();
}
}