Frameworks used for logging and i18n

Log levels

A message can be logged using the following levels (provided by SLF4J API and LocalizedLogger class):

Log levels and i18n:

Logger and category and message ID

Each logged message has a category. The category is given by the classname  where the message is logged. 

This allows to define a single logger per class, with the classname.

However, in order to have a higher kind of grouping, some pre-defined categories with simple names are also used (eg, CORESYNC, ...)

There is a mapping between packages (information which is included in classnames) and these simple categories. If a class does not map to a pre-defined package, then its category is its fully qualified class name. 

For example, all classes in the org.forgerock.opendj.server.core package or a sub-package are mapped to the CORE category.

Note that for debug logging in the server (messages logged by DebugLogger class), the pre-defined categories are NOT used.

I18N messages identification

For i18n messages, there is a way to uniquely identify the messages with two properties:

Ordinal is extracted from the message name suffix, while resource name corresponds to the resource file containing the messages. 

ERR_ADMIN_CANNOT_GET_LISTENER_BASE_1=some message
ERR_ADMIN_CANNOT_GET_MANAGED_OBJECT_2=another message
...
 

Code examples

Loggers

Each class should declare its own logger using the following code. This is valid for server classes as well as client tools classes.

private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 

Should you exceptionally need to log to a specific category that does not correspond to the class, you can create another logger to log this specific category:

private static final LocalizedLogger extensionLogger = LocalizedLogger.getLocalizedLogger("org.opends.server.extensions"); // will log to category EXTENSION according to pre-defined mapping

Non-debug (I18N) messages

The logging methods accept a localizable message descriptor and its arguments. It is the preferred way of logging: 

logger.error(ERR_ADMIN_CANNOT_GET_LISTENER_BASE, 123, "some string"); // message with a numeric argument and a string argument

Any exception is passed as the last argument:

logger.error(ERR_ADMIN_CANNOT_GET_LISTENER_BASE, 123, "some string", anException);

Debug messages

The LocalizedLogger#trace method accepts non localized arguments as an alternative to localizable argument:

logger.trace("a debug message with arg1: %s and arg2: %s", arg1, arg2)

There is also a specific method to trace an exception in addition to the message:

logger.traceException(anException, "a debug message with arg1: %s and arg2: %s", arg1, arg2)