programmatic jdk logging configuration

something so wrong with all this being so hard.. so lets try to document a few words

problem:how do you programmatically configure the JDK logging so you get two different log streams, one to standard output and another to a file? everything i tried was either outputting everything or nothing.

trying to search for a solution you come up with all sorts of weird stuff. some of these shortly.

logger.setUseParentHandlers(false);

well, the line above should stop the logging hierarchy from spouting stuff through the global loggers that are supposedly always there. not that this ever did anything for me, but the whole thing with the “” name for the root logger and default configurations is just weird. so I am still using the above line just to be sure but whatever.

another attempt

LogManager.getLogManager().reset();
for (Handler handler : java.util.logging.Logger.getLogger(“”).getHandlers()) {
handler.setLevel(Level.OFF);
}

so some claim this will remove any excess loggers that are in by default. did nothing for me. similarly tried to remove all handlers on startup. did nothing for me.

ok so use the consolehandler, which sort of works

logger = java.util.logging.Logger.getLogger(name);
logger.setUseParentHandlers(false);
logger.setLevel(Level.ALL);
Handler console = new ConsoleHandler();
//custom formatter
console.setFormatter(new LogFormatter());
console.setLevel(Level.INFO);
logger.addHandler(console);

So, first of all, the logger should have the level Level.ALL since it will block any messages below this level from reaching the handlers attached to it. So is is the first level of filtering. The second level are the attached handlers.

Now, with the above the loggers actually outputs the stuff and only the INFO level stuff and on the console. But on the stderr, the System.err stream. I want stdout, the System.out stream. And how do you fix that?

Lots of people suggest using

Handler console = new StreamHandler(System.out, new LogFormatter());

Which just prints some of the stuff and not others. Probably messes up the stream in some handy way. whooppee.

Finally, this works

/** This is where the log messages are written. */
private PrintStream out = System.out;
/** For formatting the log statements. */
private LogFormatter formatter = new LogFormatter();

@Override
public void publish(LogRecord record) {
if (record.getLevel().intValue() < getLevel().intValue()) {
return;
}
out.print(formatter.format(record));
}

@Override
public void flush() {
//system.out handles itself
}

@Override
public void close() throws SecurityException {
//system.out handles itself
}

That is, create your own handler with the code above and configure that to your logger. It’s magic.

As for the file stream, the FileLogHandler from the JDK works fine and you just add it similarly to the examples above.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s