Friday, June 27, 2008

Java Applet logging

The last couple of days I have been working on logging from our applet. Frustrating indeed, but finally it works, almost as planned.

Our first approach was to do the configuration programatically, something like:

//get the root logger
Logger logger = Logger.getLogger("");
//create a ConsoleHandler
Handler handler = new ConsoleHandler();
handler.setLevel(Level.FINE);
logger.addHandler(handler);
logger.setLevel(Level.FINE);

Now, this works very well in the Applet Viewer, but when you run your applet in a browser you'll get an exception, since the applet can not change the Handler configuration.

Well, there is the getAnonymusLogger() function, which is designed for use in applets. An anonymous logger would mean that we miss much of the benefits of the flexibel configuration, which is based on named loggers, but I guess it is better than nothing. But while using this method makes it possible to the the level on the Logger, you still can not configure the handler, so you will not get any logging output still.

So, we had to go for the configuration file. This is actually not so bad. You find the logging.properties file (it is under jre.lib) and configure your logging there. For console logging, you have to change the level of the ConsoleHandler (configured by default, but set to INFO level):

java.util.logging.ConsoleHandler.level = FINE


If you want logging to file, you can add the FileHandler instead:

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

And of course, you turn your logging on:

com.xx.package.level = FINE

Now on my Windows PC this works both in applet viewer and in browser. But when I try the ConsoleHandler on my Mac, there is another gotcha, Bug ID 6585429 LoggerTraceListener causes infinite loop under some circumstances. On my mac the console simply loops and writes the same message over and over again. Seems like this is a known bug, and there should be a fix available, but for now we are stuck with logging to file on the Mac.

5 comments:

matze said...

Hi,

thanks, that helped me a bit. Maybe, you can help me further. I have a singleton:

class Test {
private static Test instance = new Test();
private static final Logger logger = Logger.getAnonymousLogger();
private Test() {}
public getInstance() {
return instance;
}
public foobar() {
logger.info("some text");
}
}

so far so good. But how can I add a custom Formatter to this? Because of the applet-security-reasons, I cannot add a ConsoleHandler. I tried s.th. like this:

for(Handler h : logger.getHandlers()) {
h.setFormatter(new FoobarFormatter());
}

but this doesn't work. Do you have an idea?

Erik said...

Sorry, I don't think there is asolution. What I do is add my formatter in logging.properties. This works in the applet viewer, but not when testing the applet on a web page.

An option would be to use log4J instead, but I haven't tested this.

A said...

Eric, where does the lgger rwrite to. Is it writing on local computer as thats where applet resides? Can you please share little bit of background as to what was your need. I am trying to find a decent approach to log client stuff i.e applet. Your implementation looks nice but i am little confused as to where is it writing the logs.

Erik said...

Hi A,
Since I use the ConsoleHandler output will be in the Java Console window. There are other handlers available, like the FileHandler) but because of the security restrictions of applets, you will have problems using them.A possibility is to debug your applet in the Applet Viewer.

Iftikhar Khan J2EE Developer said...

Thanks Erik!!
your topic help me a lot.