Using pax logging

This page gives a recipe for adding pax-logging to an OSGi project built with Apache Maven. I did this using Apache Maven 3.2.5.

Pax logging is a facility that maps from several popular Java logging APIs to the OSGi logging service, and then maps from the OSGi logging service to log4j. Thus, if you have bundles that import any of the the usual logging API packages (SLF4J, LOG4J, java.util.logging), you can use pax-logging to collect all the messages from all of them and manage them together. If you use pax-logging, you don't need to include any of the bundles for any of these logging APIs – pax-logging exports them all.

I found this a bit hard to grasp at first, so I let me be really detailed.

Say that you like to write code to use the SLF4J API to log. So, you've got Java classes with imports like:

A bit of slf4j
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


class Whatever {
  private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
}

When you build this into a bundle, you will import the package org.slf4j. If you don't use pax-logging, you will have to provide slf4j. You would do this by provisioning two bundles in your OSGi container: slf4j-api and slf4j-SOMETHING. And then you'd have to arrange to configure SOMETHING (log4j, jcl, etc).

With pax-logging, you don't have to provision any slf4j bundle at all. Pax-logging's bundles export the org.slf4j package. Now, since pax-logging also exports the API packages for common logging packages, you have the option of provisioning the two SLF4J bundles and letting pax-logging grab the log messages as they come out 'of the bottom' of the particular logging back-end.

If you don't use SLF4J, but rather one of the other logging packages that pax-logging supports, the same principles apply. Pax-logging exports the API package so that you don't need to provide it.

Since the pax-logging service eventually disposes of the log messages via log4j, you do need to provision the log4j bundle.

This guide assumes that you are using Maven dependencies to manage your bundles; if you are managing your bundles manually (as in, with dependency:copy), then you'll have to adapt.

Step-by-step guide

You need three OSGi bundles added to your environment. Here they are as Maven POM dependencies. pax-logging-api is the bundle that provides the various logging APIs, while pax-logging-service provides the implementation of the logging service that delivers the log messages via log4j. pax-logging uses Configuration Admin to get log4j configuration, so you need that, too.

  1. Dependencies you need:

    Dependencies
     <dependency>
        <groupId>org.ops4j.pax.logging</groupId>
        <artifactId>pax-logging-api</artifactId>
        <version>1.8.3</version>
     </dependency>
     <dependency>
        <groupId>org.ops4j.pax.logging</groupId>
        <artifactId>pax-logging-service</artifactId>
        <version>1.8.3</version>
        <!-- Note that this bundle declares a dependency on log4j -->
     </dependency>
     <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.configadmin</artifactId>
        <version>1.8.8</version>
     </dependency>
  2. You need to configure the disposition of the log messages. Pax-logging has a default log4j configuration, and you can configure the top-level severity with a system property. You can configure the details with the OSGi Configuration Admin service.  See  Configuration (previous) for details. If you need to use appender classes (or formatter classes) that are not part of the standard Log4J bundle, you need to use a fragment bundle to make them available to pax-logging-service. Several blog posts (e.g. This one from Achim Nierbeck) have this information.