Up until and including Oracle Coherence Incubator 8, all logging occurred
through the use of the CacheFactory.log
method. While this was somewhat
consistent with the internal implementation of Oracle Coherence, it prevented
certain flexibility provided by standard java.util.logging
framework.
Post Oracle Coherence Incubator 8 we changed our strategy and refactored
almost all of the logging to use the standard java.util.logging
framework,
thus allowing fine-grain control, filtering and ultimately replacement using
commonly requested and community-driven logging frameworks.
While Java logging gives a lot of flexibility, we additionally want to ensure that logging via the Coherence provided framework is still possible. To achieve this we have provided a
java.util.logging.Handler
implementation that redirects standardjava.util.logging
messages to the Coherence log facility.
One of the core reasons for keeping the Coherence Logging facility is that the
Coherence Logging is asynchronous internally. It uses a separate thread for actual
logging, thus preventing logging-based latency to accidentally impact performance
(unlike the java.util.logging
framework prior to Java SE 7).
The following links further information about logging frameworks and Java.
http://www.crazysquirrel.com/computing/java/logging.jspx http://www.vogella.de/articles/Logging/article.html
Logging is quite easy. Simply acquire a Logger
for your class and log use it
as follows:
package com.wombat;
import java.util.logging.*;
public class Nose
{
// obtain a suitable logger.
private static Logger logger = Logger.getLogger(Nose.class.getName());
public static void main(String args[])
{
// Log a FINE tracing message
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "doing stuff");
}
try
{
Wombat.sneeze();
}
catch (Exception e)
{
if (logger.isLoggable(Level.SEVERE))
{
logger.log(Level.SEVERE, "trouble sneezing", e);
}
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "doing stuff");
}
}
}
}
The logging level for an individual class logger can be configured by adding
an entry in the JRE/lib/logging.properties
file:
 com.oracle.coherence.patterns.pushreplication.CachePublisher.level=FINE

An Incubator class logger logging level is independent of the Coherence Logging
Level (i.e. tangosol.coherence.log.level
). This allows for detailed class
logging without impacting the entire Coherence/Incubator stack's logging.
An Incubator class logger LogRecord
's logging level is set to the lower of:
the Coherence Logging Level and the Incubator Class Logger Logging Level. This
allows the LogRecord
into the Coherence log stream.
As the construction of the strings and getting values for log messages can be expensive, we recommend that you always guard the generation of log messages like this:
if (logger.isLoggable(INFO))
{
logger.info(getExpensiveString());
}
One of the most important decisions to be made when logging is to choose the correct logging level. The following section outlines our recommendations for choosing the correct logging level when developing for the Oracle Coherence Incubator.
The Severe Level:
The Level.SEVERE
level should be used for logging errors, exceptions and
messages prior to a process terminating. The method logger.severe(...)
should
be used for logging at the severe level.
In general, there's never a requirement to use a guard when using this level, simply because you want the end-user to see as much logging as possible prior to process termination.
The Warning Level:
The Level.WARNING
level should be used for logging unhandled exceptions and
messages:
prior to a part of a system/service/feature going unexpectedly going offline, deteriorating or becoming unavailable (without a process terminating).
when using a deprecated feature.
for recommending a better use of a feature.
when experiencing unexpected unhandled / unknown exception conditions (that won't lead to system instability). This does not include exceptions due to user error. ie: file not found, but does include exceptions due to configuration/developer error.
The method logger.warning(...)
should be used for logging warnings.
The Information Level:
The Level.INFO
level should be used for logging:
High-level feature functional activity in a system. eg: life-cycles
Information about the dynamic configuration of a sub-system/component/service/feature
Dynamic information/dependencies/configuration changes that have a material effect on a sub-system/component/feature's future behaviour.
For example when a feature becomes available/starting/stopping with a certain configuration.
The method logger.info(...) should be used for logging at the info level
The Configuration Level:
The Level.CONFIG
level should be used for logging static configuration
information.
The method logger.config(...) should be used for logging at the config level.
The Fine Level:
The Level.FINE
level should be used for logging top-level implementation details,
but not lifecycles or entry-exit. Examples include:
The successful (or unsuccessful) creation of a messaging session.
A request for some action to be performed.
An exception has occurred (like file not found).
A message that has been published / consumed.
A task that has been created/submitted
A namespace handler that has been created

In most cases, Level.FINE
will be the most common level of logging seen.
The method logger.fine(...) should be used for logging at the fine level
The Finer Level
The Level.FINER
level should be used for logging method/feature implementation
entry-exit and exceptions.
The methods logger.entering(...)/exiting(...) and throwing(...) should be used for logging entry, exit and exceptions at the finer level.
The Finest Level
The Level.FINEST
should be used for logging the internal execution of algorithms.
This is by far the noisiest level of logging. You'd typically see this logging
within a loop or method showing the progress of execution.
Use this level for where you'd be tempted to uses a System.out.print to debug/trace an implementation.
The method logger.finest(...) should be used for logging at this level.