Logging APIs

Logging APIs

Pax Logging project was designed to hide the OSGi specific details, so user code doesn’t have to deal with OSGi specifics at all. What developers are used to is this kind of code:

 

import org.slf4j.Logger; import org.slf4j.LoggerFactory; ... Logger log = LoggerFactory.getLogger("com.example.service"); log.info("Hello");

As mentioned in Pax Logging, there are several Logging APIs to use and here’s summary of all supported, canonical usages:

// 1. SLF4j org.slf4j.LoggerFactory.getLogger(name).info("INFO using SLF4J"); // 2. Commons Logging org.apache.commons.logging.LogFactory.getLog(name).info("INFO using Commons Logging"); // 3. JULI Logging org.apache.juli.logging.LogFactory.getLog(name).info("INFO using Juli Logging"); // 4. Avalon Logging org.ops4j.pax.logging.avalon.AvalonLogFactory.getLogger(name).info("INFO using Avalon Logging"); // 5. JBoss Logging org.jboss.logging.Logger.getLogger(name).info("INFO using JBoss Logging"); // 6. Knopflerfish - no special facade // 7. Log4J1 org.apache.log4j.Logger.getLogger(name).info("INFO using Log4Jv1"); // 8. Logback - only behind SLF4J // 9. Log4J2 org.apache.logging.log4j.LogManager.getLogger(name).info("INFO using Log4Jv2"); // 10. JUL - extra handling without a pax-logging specific facade and shadowing. Only handler redirection java.util.logging.Logger.getLogger(name).info("INFO using java.util.logging");

How does it work?

Each of the above facades are implemented by pax-logging-api bundle which (using API/framework/library specific techniques) contains code that effectively implement the facades to pass the invocation to underlying OSGi mechanism. This includes:

  • providing own versions of original classes (shadowing) with delegation to Pax Logging

  • using org.osgi.util.tracker.ServiceTracker to dynamically adjust what actual logging implementation should be used (including the situation where no implementation is available)

  • dynamically switching to available logging backend provided by one of backend Pax Logging bundles (namely: pax-logging-service, pax-logging-logback orpax-logging-log4j2)

Missing piece in R6 - category

OSGi R6 misses important concept - a category. It is well known from all the above mentioned facades that user’s code use loggers which have name. This name is often referred to as category - a concept introduced by Log4J1 library defining a hierarchical name that may be related to some other mechanisms like appenders, filters or layouts.

When using OSGi R6 org.osgi.service.log package directly, Pax Logging internally derives a category from bundle’s symbolic name. The bundle that’s identified to be the one invoking particular logging statement is discovered by stack trace traversing.

OSGi Logging R7 - category introduced

OSGi R7 adds a category concept and we can now use standard org.osgi.service.log.LoggerFactory service to obtain loggers by category name. That’s very similar to what we already have in supported logging frameworks (facades).