简体   繁体   中英

flush System.out with own logger

I created my own little logger to use instead of 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);

At the moment, the messages don't get flushed, so they only appear once the application gets terminated. Is there a way to flush a message after printing it out without creating a new class or adding many lines of code? I want to keep this code as short as possible...

The problem is that the StreamHandler.setOutputStream wraps the given stream in a OutputStreamWriter which according to the javadocs :

The resulting bytes are accumulated in a buffer before being written to the underlying output stream. The size of this buffer may be specified, but by default it is large enough for most purposes.

So there is no way around calling StreamHandler.flush to force those bytes to the console.

Since you don't want to create a new class you can use the ConsoleHandler which will flush to console but by default will write to error stream. You can get around that if you haven't started any other threads by doing the following:

//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);
}

A subclass really is your best bet because you can end up accidentally closing the System.out by calling Handler.close() through LogManager.getLogManager().reset() or by calling StreamHandler.setOutputStream which means you won't see any output at all.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM