Presents your JAVA E-NEWSLETTER for April 28, 2003 <-------------------------------------------> CREATE YOUR OWN LOGGING HANDLER The Java logging package is dynamic and lets you plug in your own logging functionality. For example, you may want to build a custom-logging handler, java.util.logging.Handler. A handle is the part of the logging system that actually does the work of logging a java.util.logging.LogRecord to a destination. This tip will create a sample handler that will give you a starting point for your own handler ideas. To create your handler, you extend java.util.logging.Handler, provide implementations for the abstract methods close, publish, and flush, and define the handle configuration: package tips; import java.util.logging.Logger; import java.util.logging.LogManager; import java.util.logging.Handler; import java.util.logging.LogRecord; import java.util.logging.SimpleFormatter; import java.util.logging.Level; public class SampleHandler extends Handler { private String prefix = "SampleHandler"; public SampleHandler() { LogManager manager = LogManager.getLogManager(); String className = SampleHandler.class.getName(); String value; // set the logging level setLevel(Level.INFO); try { value = manager.getProperty(className + ".level"); if ( value != null ) { setLevel(Level.parse(value)); } } catch (IllegalArgumentException e) { // unknown level name } // now get our custom property, prefix value = manager.getProperty(className +".prefix"); if ( value != null ) { this.prefix = value; } setFormatter(new SimpleFormatter()); } /** this method does all of the handling work */ public void publish(LogRecord record) { if ( isLoggable(record) ) { System.err.println(record.getLevel() + ": " + this.prefix + " " + record.getMessage()); } } /** * called to tell the handler * to flush any buffered output. */ public void flush() {} /** * gives the handler an opportunity to release any * resources. */ public void close() {} } The sample handler will output log records to standard error. Through the publish method, you could output the log records to a database or send them across the network. As implemented, this handler's publish method uses the superclass's isLoggable method to determine whether the LogRecord should be logged. If so, the record is sent to standard error; if not, the record is ignored. Also for simplicity's sake, the handler doesn't buffer output or use any outside resources, so the flush and close methods do nothing. The sample handler is responsible for configuring itself at runtime, which it does by using the log manager's getProperty method to retrieve properties from the logging properties file. The sample handler has only two properties that are configurable from the outside: prefix and level. These properties both have default values. In your handler, you can have as many properties as you need. To set them, you prefix the name of the handler class and add a period to the name of the property. The properties file is where you set port numbers, user names, driver names, etc. A properties file that used the sample handler would look like this: handlers=tips.SampleHandler .level=FINEST tips.SampleHandler.level=CONFIG tips.SampleHandler.prefix=CUSTOM PREFIX-> Assuming there's a class somewhere that contains these statements: ... log.finest("the finest message"); log.finer("finer message"); log.fine("a fine message"); log.config("some configuration message"); log.info("a little bit of information"); log.warning("a warning message"); log.severe("a severe message"); ... the output would look something like this: CONFIG: CUSTOM PREFIX-> some configuration message INFO: CUSTOM PREFIX-> a little bit of information WARNING: CUSTOM PREFIX-> a warning message SEVERE: CUSTOM PREFIX-> a severe message The dynamic design of the logging API makes implementing a logging handler a relatively simple task. The sky's the limit when creating your own handlers. Before you get started, though, take a look at the handlers in the logging package. Maybe you can use or extend these to get what you need. ----------------------------------------