Java – Logger is used for logging under Android

Logger is used for logging under Android… here is a solution to the problem.

Logger is used for logging under Android

I noticed that the following works on PC, but not in Android emulator.

Logger logger = Logger.getLogger("foo");
logger.log(Level.INFO, "Number is: {0}", new Object[]{new Integer(42)});

It just prints

Number is: {0}

Why does this fail for Android?

Solution

I found a solution in a roundabout way. Eventually, I think there is a formatter somewhere in the default android logging implementation that only renders messages, ignoring parameters. You should be able to use the Logging API to install a formatter of your own design.

I have installed a new handler for completely different reasons. The sources I use are available here: http://4thline.org/projects/download/misc/

The handler is located in the teleal-common-1.0.14-source.tar.gz archive. Follow the path to src\main\java\org\fourthline\android\util\FixedAndroidHandler .java.

THIS

SITE ALSO PROVIDES CODE TO INSTALL THIS HANDLER, BUT IT IS IN A DIFFERENT ARCHIVE: SASH-1.0-SNAPSHOT.tar.gz. Find 1.0\src\main\java\org\teleal\common\logging\Logging\LoggingUtil.java.

You can install this handler by calling it somewhere in your app startup code:

LoggingUtil.resetRootHandler(new FixedAndroidHandler());

I found that the Formatter of this handler is embedded in the handler as an anonymous class. How convenient. I can see that Formatter is not processing the parameters passed in via LogRecord. I just added an “else-if” condition:

private static final Formatter THE_FORMATTER = new Formatter() {
    @Override
    public String format(LogRecord r) {
        String msg = r.getMessage();
        Object[] params = r.getParameters();
        Throwable thrown = r.getThrown();
        if (thrown != null) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            sw.write(r.getMessage());
            sw.write("\n");
            thrown.printStackTrace(pw);
            pw.flush();
            return sw.toString();
        } else if ((params != null) && (params.length > 0) && (msg.indexOf("{0") >= 0)) {
            return MessageFormat.format(msg, params);
        } else {
            return r.getMessage();
        }
    }
};

The if test is consistent with other log formatting code I’ve seen. In theory, you should be able to take a more straightforward approach and install a similar Formatter into an existing handler. Since the above solution worked for me, I haven’t tried it myself.

Related Problems and Solutions