<< Zurück zum Index.

Log4j for an OSGi System

Apart from somehow incorportating Log4j (->external link) via providing it at some general library place of the OSGi-Container, and likewise with the logging configuration, which is not very OSGi-stylish, you can also use clean bundles to use it. For a basic setup we need three bundles: a general host bundle containing the log4j framework classes, a bundle with the configuration, and optionally a bundle for custom appenders if you need one. We will be using Eclipse Mars as an IDE and Log4j 1.2.9, but in principle you can substitute everything with the newer Log4j 2.x versions.

Log4j main bundle

  1. Make a new Plugin Project inside Eclipse, say named log4jbundle.
  2. Download the Log4j distribution, e.g. version 1.2.9, fetch the library jar from inside, e.g. log4j-1.2.9.jar, and copy the latter to your ${project}/lib.
  3. Make a file ${project}/META-INF/MANIFEST.MF and let it read
    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: Log4j-1.2
    Bundle-SymbolicName: log4j12
    Bundle-Version: 1.2.9
    Export-Package: org.apache.log4j;version="1.2.9"
    Bundle-ClassPath: ., lib/log4j-1.2.9.jar
    
  4. Figure out a way to create a bundle JAR from that. The structure must read
      lib/
          log4j-1.2.9.jar
      META-INF/
          MANIFEST.MF
    
    (use ANT, or Maven, or Groovy-Antrunner).

This bundle can be used via importing its only package org.apache.log4j from any other bundle. This is not enough though, we still need a configuration, see next section.

Log4j configuration bundle

  1. Make a new Plugin Project inside Eclipse, say named log4conf.
  2. Inside ${project}/src place your cnfiguration file, e.g. log4j.properties, with contents
    log4j.rootLogger=DEBUG, Appender1, Appender2
    
    log4j.appender.Appender1=org.apache.log4j.ConsoleAppender
    log4j.appender.Appender2=org.apache.log4j.RollingFileAppender
    log4j.appender.Appender2.File=sample.log
    
    log4j.appender.Appender1.layout=org.apache.log4j.PatternLayout
    log4j.appender.Appender1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
    
    log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout
    log4j.appender.Appender2.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
    
  3. Of course instead you can use any other configuration file format, see the Log4j documentation.
  4. Make a file ${project}/META-INF/MANIFEST.MF and let it read
    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: Log4jConf
    Bundle-SymbolicName: log4j-conf
    Bundle-Version: 1.0.0
    Fragment-Host: log4j12;bundle-version=1.2.9
    Bundle-ClassPath: .
    
    The important part is the Fragment-Host statement. Only then Log4j will be able to see the configuration from inside the Log4j framework bundle!
  5. Figure out a way to create a bundle JAR from that. The structure must read
      log4j.properties
      META-INF/
          MANIFEST.MF
    
    (use ANT, or Maven, or Groovy-Antrunner).

Unless you need a custom appender, you're done. Install the two bundles and any other bundle can import the Log4j functionalities in its own MANIFEST.MF via:

Import-Package: ..., org.apache.log4j;version="[1.2.9,1.2.9]", ...

Log4j custom appender

If you need a custom appender, it must be designed as a fragment bundle again:
  1. Make a new Plugin Project inside Eclipse, say named log4myAppender.
  2. Inside ${project}/src place your appender code (look for the Log4j documentation on how to create a custom appender)
  3. Make a file ${project}/META-INF/MANIFEST.MF and let it read
    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: TestAppender
    Bundle-SymbolicName: test-appender
    Bundle-Version: 1.0.0
    Fragment-Host: log4j12;bundle-version=1.2.9
    Bundle-ClassPath: .
    
  4. Figure out a way to create a bundle JAR from that. The structure must read
      [The classes...]
      META-INF/
          MANIFEST.MF
    
    (use ANT, or Maven, or Groovy-Antrunner).

Install that bundle in the OSGi container, and the new appender can be used from inside the Log4j configuration file.