tags:

views:

853

answers:

2

I'm configuring the logging for a Java application. What I'm aiming for is two logs: one for all messages and one for just messages above a certain level.

The app uses the java.util.logging.* classes: I'm using it as is, so I'm limited to configuration through a logging.properties file.

I don't see a way to configure two FileHandlers differently: the docs and examples I've seen set properties like:

java.util.logging.FileHandler.level = INFO

While I want two different Handlers logging at different levels to different files.

Any suggestions?

A: 

I think you should be able to just subclass a handler and then override the methods to allow output to go to multiple files depending on the level of the message. This would be done by overriding the publish() method.

Alternatively, if you have to use the system-provided FileHandler, you could do a setFilter() on it to inject your own filter into the mix and, in that filter code, send ALL messages to your other file and return true if the LogRecord level if INFO or higher, causing the FileHandler.publish() to write it to the real file.

I'm not sure this is the way you should be using filters but I can't see why it won't work.

paxdiablo
I'm using the application as is - I don't want to write code here: just configure logging from a properties file.
Then it can't be done. What you're asking for is not a feature of the logging system you're using. If that's what you have to use, then you're out of luck, I'm afraid.
paxdiablo
+2  A: 

http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html is helpful. You can only set one Level for any individual logger (as you can tell from the setLevel() method on the logger). However, you can take the lowest of the two common levels, and then filter programmatically.

Unfortunately, you can't do this just with the configuration file. To switch with just the configuration file you would have to switch to something like log4j, which you've said isn't an option.

So I would suggest altering the logging in code, with Filters, with something like this:

class LevelFilter implements Filter {
    private Level Level;
    public LevelFilter(Level level) {
        this.level = level;
    }
    public boolean isLoggable(LogRecord record) {
        return level.intValue() < record.getLevel().intValue();
    }
}

And then on the second handler, do setFilter(new LevelFilter(Level.INFO)) or whatever. If you want it file configurable you could use a logging properties setting you've made up yourself, and use the normal Properties methods.

I think the configuration code for setting up the two file handlers ad the programmatic code is fairly simple once you have the design, but if you want more detail add a comment and I'll edit.

Nick Fortescue
Thanks for the answer. I just find it incomprehensible that you can't log messages of different severity to different places without writing code.
Yep, that's one reason lots of people use log4j instead
Nick Fortescue