我创建了自己的小记录器而不是System.out.println
LogManager.getLogManager().reset();
logger = Logger.getLogger(this.toString());
logger.setLevel(loglevel);
Formatter formatter = new Formatter() {
public String format(LogRecord record) {
return new Date().toString().substring(11, 20) + record.getLevel()+" " + formatMessage(record) + System.getProperty("line.separator");
}
};
logger.addHandler(new StreamHandler(System.out, formatter));
LogManager.getLogManager().addLogger(logger);
此时,消息不会被刷新,因此只有在应用程序终止后才会显示。有没有办法在打印出来后刷新消息而不创建新类或添加多行代码?我想保持这段代码尽可能短......
答案 0 :(得分:2)
问题在于StreamHandler.setOutputStream根据OutputStreamWriter将javadocs中的给定流包裹起来:
在写入底层输出流之前,生成的字节在缓冲区中累积。可以指定此缓冲区的大小,但默认情况下,它足以满足大多数用途。
因此无法调用StreamHandler.flush
强制将这些字节强制到控制台。
由于您不想创建新类,因此可以使用将ConsoleHandler刷新到控制台,但默认情况下会写入错误流。如果你没有通过执行以下任何其他线程来解决这个问题:
//Global resource so ensure single thread.
final PrintStream err = System.err;
System.setErr(System.out);
try {
ConsoleHandler ch = new ConsoleHandler();
ch.setFormatter(formatter);
logger.addHandler(ch);
} finally {
System.setErr(err);
}
子类确实是您最好的选择,因为您可能会通过System.out
或Handler.close()
致电LogManager.getLogManager().reset()
来意外关闭StreamHandler.setOutputStream
,这意味着您不会看到任何输出。
public class OutConsoleHandler extends StreamHandler {
public OutConsoleHandler(OutputStream out, Formatter f) {
super(out, f);
}
@Override
public synchronized void publish(LogRecord record) {
super.publish(record);
flush();
}
@Override
public void close() throws SecurityException {
flush();
}
}