This would seem obvious, but it wasn’t to me, so I thought I’d write about it to help out anyone else attempting to accomplish the same. It’s pretty straight forward actually.
Let’s say you have a java.util.logging.Logger object that you’ve initialized, and you want to redirect all stderr (exceptions, System.err.print()’s) and stdout (System.out.print()) to it. You’ll want to use System.setErr and System.setOut to a custom java.io.PrintStream object which writes to your Logger object.
Let’s first define a class to do this for us, and then I’ll explain how it works:
class CustomOutputStream extends OutputStream
{
Logger logger;
Level level;
StringBuilder stringBuilder;
public CustomOutputStream(Logger logger, Level level)
{
this.logger = logger;
this.level = level;
stringBuilder = new StringBuilder();
}
@Override
public final void write(int i) throws IOException
{
char c = (char) i;
if(c == '\r' || c == '\n')
{
if(stringBuilder.length()>0)
{
logger.log(level,stringBuilder.toString());
stringBuilder = new StringBuilder();
}
}
else
stringBuilder.append(c);
}
}
The way this works is by extending OutputStream and overriding the write() method. But write() only takes one character at a time, so essentially you want to buffer each character into a String Builder, to build up the whole line, until you encounter a \r or \n (carriage return, new line), and then submit it to the logger.
To attach CustomOutputStream to your logger:
Logger logger = Logger.getLogger(...); //... System.setErr( new PrintStream( new CustomOutputStream(logger,Level.SEVERE) //Or whatever logger level you want ) ); System.setOut( new PrintStream( new CustomOutputStream(logger,Level.FINE) //Or whatever logger level you ) );
Note: if you’ve configured your logger to always include the class/method with the log message, a side effect of this is that the output will not include your original method that wrote the log message to stderr or stdout , but instead your.package.CustomOutputStream.write().
Happy logging!

Your blog looks nice on mobile phone