Saturday, February 16, 2008

The Java Logging API in brief (part I)

In my previous post I've suggested a very primitive way to log error. Of course the right way to log your error, but also other information, is to use a really logger.
The most famous logger for the java environment is sure log4j but also the core jdk provides a logging api. The vantage of using the embedded java logging api is that you need no external jar.
If you already know the the log4j levels, this comparison table can help you:
log4J Java Logging
log4j.fatal("msg"); -
log4j.error("msg"); logger.severe("msg");
log4j.warn("msg"); logger.warning("msg");
log4j.info("msg"); logger.info("msg");
log4j.debug("msg"); logger.config("msg");
- logger.fine("msg");
- logger.finer("msg");
- logger.finest("msg");

To create a logger with the Java Logging API:
private static final Logger log =
Logger.getLogger(MyClass.class.getPackage().getName());

Note that I've called this logger as the package because this be my very practical in case of refactoring. Of couse, you are free to use the name that best fits your needings, for example the module name.
You can configure log level and everything else programmatically but the best and less intrusive way to do this is the logging.properties file.

A standard configuration is already in every java distribution in the folder $JAVA_HOME/jre/lib/ but you can use a different file by specifying a filename with the java.util.logging.config.file system property (for example java -Djava.util.logging.config.file=/path/to/log.properties).
This is the standard configuration as for jdk 6
############################################################
# Default Logging Configuration File
############################################################

############################################################
# Global properties
############################################################

# "handlers" specifies a comma separated list of log Handler
# classes. These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.
handlers= java.util.logging.ConsoleHandler

# To also add the FileHandler, use the following line instead.
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers. For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= INFO

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter


############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
com.xyz.foo.level = SEVERE

This configuration is pretty self-explanatory, note as you can set different log level for different logger.
You can write your own log formatter by subclassing the abstract class java.util.logging.Formatter and overriding the method format(LogRecord).

No comments: