users@glassfish.java.net

Re: Log Segregation

From: <glassfish_at_javadesktop.org>
Date: Fri, 05 Oct 2007 17:55:12 PDT

Actually, this isn't easy to do.

The problem is that the default implementation of java.util.logging is to use a global set of loggers across the entire JVM.

In theory, you could attach a different Handler or Formatter on the Loggers within each of your applications. But the problem is that they're in a global name space.

And no doubt all of your Loggers from each app share their Logger names (many people use the class name).

So, since they're a global, container wide, unified space, changing the properties of a Logger in one app, would change it for all apps using that same named Logger.

There are ways around this, but you have to jump through a bunch of hoops to mitigate it. A simple mechanism would be to prefix the application version to all of your Logger names, then they be unique across versions, and you could attach Handlers and Formatters to the root based on your version.

Assume you have a simple singleton:

public class AppVersion {
    public static String version = "v1";
}


The in your application:

Logger log = Logger.getLogger(AppVersion.version + "." + MyClass.class.getName());

In your new Application you would do:
public class AppVersion {
    public static String version = "v1-1"; //Note -- don't use "." here, instead use "-"
}

Now, at a minimum, your Logger name will be different for each application.

In App1 your logger would be:

v1.com.example.MyClass

And in App2 it would be:

v1-1.com.example.MyClass

You can use the Advanced Search function of the Log Viewer in the console, and filter your classes that way, specify either v1 or v1-1 in the "Custom Loggers" pane for your search.

The dark side, of course, is that for any class NOT directly under your control, you're pretty much out of luck, as this technique requires modifying the actual Logger names, and you can't readily do that for classes which you have no control.

Finally, in, say, an Init servlet, if you like, you can demarcate your application log messages to their own file if you like:

Logger log = Logger.getLogger(AppVersion.version);

Handler myHandler = new FileHandler("/some/path/mylog.log");

log.addHandler(myHandler);

That will route just your versions to its own file, but, again, you won't get the common loggers (or GFs for that matter).

I hope that they will put some work in to being able to get a little more control over your logging, like what you want, but I don't think it's a particularly trivial task -- kind of depends what kind of state they stick on a ThreadLocal of the runtime threads to help identify the application that's running -- then they can use that information to configure logging to different areas for different applications.

But I don't think this is even on the RADAR for v3.

We also need some protection since anyone can access any other applications logs in a hostile deployment scenario.

(So never log anything sensitive in an application that's being deployed in a container you don't "trust".)
[Message sent by forum member 'whartung' (whartung)]

http://forums.java.net/jive/thread.jspa?messageID=238752