Localization support
A discussion on the slf4j-dev mailing list spawned an open-source project called CAL10N or Compiler Assisted Localization. As its name indicates, CAL10N focuses on the issue of localization/internationalization in Java applications.
The org.slf4j.cal10n
package which ships with
slf4j-ext-${project.version}.jar adds an extremely thin
layer on top of CALI0N to offer localized logging.
Once you have a handle on an IMessageConveyor instance, you can create a LocLoggerFactory, which in turn can create LocLogger instances capable of doing localized logging.
Let us assume that you have defined localized message in your
application. In accordance with the CAL10N's philosophy, you have
the declared the keys for those messages in the enum type
Production
.
import ch.qos.cal10n.LocaleData; import ch.qos.cal10n.Locale; import ch.qos.cal10n.BaseName; @BaseName("production") @LocaleData( { @Locale("en_UK"), @Locale("ja_JP") }) public enum Production { APPLICATION_STARTED, APPLICATION_STOPPED, ... DB_CONNECTION, DB_CONNECTION_FAILURE; }
It is assumed that you have created appropriate bundle file for the various locales "en_UK" and "ja_JP" as appropriate. Here is a sample bundle for the "en_UK" locale.
APPLICATION_STARTED=Application {0} has started. APPLICATION_STOPPED=Application {0} has stopped. ...
Then, you
can instantiate a IMessageConveyor
, inject it into a
LogLoggerFactory
, retrieve multiple
LogLogger
instances by name and log away, as the next
sample code illustrates.
import java.util.Locale; import org.slf4j.cal10n.LocLogger; import org.slf4j.cal10n.LocLoggerFactory; import ch.qos.cal10n.IMessageConveyor; import ch.qos.cal10n.MessageConveyor; public class MyApplication { // create a message conveyor for a given locale IMessageConveyor messageConveyor = new MessageConveyor(Locale.UK); // create the LogLoggerFactory LocLoggerFactory llFactory_uk = new LocLoggerFactory(messageConveyor); // create a locLogger LocLogger locLogger = llFactory_uk.getLocLogger(this.getClass()); public void applicationStart() { locLogger.info(Production.APPLICATION_STARTED, "fooApp"); // .. } public void applicationStop() { locLogger.info(Production.APPLICATION_STOPPED, "fooApp"); // ... } }
Assuming the resource bundle production_en_UK.properties exists, and the underlying logging framework is enabled for the info level, log messages will be output in UK English.
Note that a LogLogger
is a regular SLF4J logger
with additional methods supporting localization. For those
additional methods which take an enum as first parameter,
LogLogger
follows the standard Java convention for
parameter substitution as defined by the java.text.MessageFormat
class. For non-localized logs, which take a String as first
parameter, LogLogger
follows the {} convention, as
customary for all org.slf4j.Logger
implementations.
Here is an example illustrating the difference.
import ...; public class MyApplication { IMessageConveyor messageConveyor = new MessageConveyor(Locale.UK); LocLoggerFactory llFactory_uk = new LocLoggerFactory(messageConveyor); LocLogger locLogger = llFactory_uk.getLocLogger(this.getClass()); public void someMethod() { // follows the MessageFormat convention locLogger.info(Production.APPLICATION_STARTED, "fooApp"); // follows the {} convention logLogger.info("Hello {}", name); ... } }