Part 2 shows you how to catch all log events logged by OSGI Bundles using “classic” Log-Frameworks instead of OSGI Log Services.
In Enterprise Applications following log frameworks are often in use:
Java-internal Logging will be used from EasyBeans – Bundles. Java.util package needs no own bundle, but we have to handle how to catch those log events.
org.apache.commons.logging will be used by these bundles:
- org.mortbay.jetty (without version)
- org.apache.commons.httpclient (version 1.0.4 – 2.0.0)
- org.ow2.easybeans.core (without version)
- org.ow2.bundles.ow2-util-jmx-impl (without version)
- org.ow2.easybeans.component.carol (without version)
- org.ow2.easybeans.component.jotm (without version)
- org.ow2.easybeans.component.quartz (without version)
org.apache.log4j will be used from:
org.eclipse.riena.core (without version)
org.slf4j is in use from:
org.ow2.easybeans.core (>= version 1.5.0) from contained Hibernate 3.4
Similar situations will be found in many enterprise applications. I’m using the API from SLF4J to bring it all together.
As implementation I’ve choosen LOGBack – I’ll explain the reasons later – this blog will only talk about technical things how to get the right bundles working to integrate it all.
Lets start from bottom – the LOGBack implementation of SLF4J API. At first (as „good“ OSGI citizens) we’ll search for LOGBack bundles in repositories und we’ll find the actual version in SpringSource Enterprise Bundle Repository 🙂
com.springsource.ch.qos.logback.core (version 0.9.9)
➡ exports core packages (version 0.9.9)
com.springsource.ch.qos.logback.classic (version 0.9.9)
➡ imports core packages (version 0.9.9) and org.slf4j api packages (version 1.5.0 – 2.0.0)
➡ exports classic packages and org.slf4j.impl (version 1.5.0)
Remark: This blog only notes dependencies and exported packages important for logging requirements – If you look into the MANIFEST-MF, you’ll see all of them.
Now we need some SLF4J bundles – API and some bridges between SLF4J and „classic“ logging frameworks. Of course at first we’re looking into the repositories and will find SLF4J bundles at SpringSource – but only version 1.5.0. The actual version is 1.5.3 – so in this case we have to build the bundles by ourself and also enter a JIRA at SpringSource to ask for version 1.5.3.
Remark: its a good idea to look at the current 1.5.0 bundles at SpringSource to watch dependencies and exported packages to compare it later with your own solution.
After downloading SLF4J JARs (1.5.3) we unzip the archiv. Here’s an overview about all SLF4J JAR f we need from download:
- jcl-over-slf4j-1.5.3.jar (already with OSGI compatible MANIFEST.MF)
We build the bundles (Plug-Ins) this way:
New | Plug-In Development | Plug-In from existing JAR-archives:
Now select the external JAR file. We’ll start with the API: slf4j-api-1.5.3.jar
If you create bundles from „foreign“ JAR files its good practice to prefix the name with your own namespace. Also: please dont forget to set the version !
PDE opens then the MANIFEST.MF file. Please check / add:
- Dependencies: Version correct ? (1.5.0 – 1.5.3) Because bundle com.springsource.ch.qos.logback.classic exports package org.slf4j.impl in version 1.5.0 we have to use the range from 1.5.0 to 1.5.3 !
- Runtime | Exported Packages: Set the version property (1.5.3) and click Calculate Uses
- Overview | Execution Environment set the environment value
Then your MANIFEST.MF should look like:
Bundle-Name: SLF4J Api Plug-in
Now we can export our Plug-In project:
That’s easy – isn’t it ?
But please always follow the rule: “If there’s a bundle for your JAR already available in one of the repositiories then use this one“.
The we repeat our steps for
and we’ll get following MANIFEST.MF files:
Bundle-Name: JUL to Slf4j Plug-in
Bundle-Name: Log4J over Slf4j Plug-in
We can use the JAR File jcl-over-slf4j-1.5.3.jar directly as bundle (Plug-In) because the included MANIFEST.MF contains all relevant informations for use under OSGI:
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Bundle-Description: JCL 1.1.1 implementation over SLF4J
Export-Package: org.apache.commons.logging;version=1.1.1, org.apache.
Import-Package: org.slf4j;version=1.5.3, org.slf4j.spi;version=1.5.3
The last part we’re missing is the configuration file to configure LOGBack – the logback.xml. Also for test purposes we’ll use the logback-test.xml. LOGBack always at first is looking for logback-test.xml and only if there’s none, the logback.xml will will be used.
Its a good idea to use the logback.xml for normal use and while testing and developing to use the logback-test.xml. We’ll show later how to switch easy between them.
Now we create two Fragment-Plug-In projects.
New | Plug-In Development | Fragment Project:
As HOST we have to choose Plug-In com.springsource.ch.qos.logback.core :
The Plug-In Fragment contains only one single file directly in the src folder:
src/logback.xml or src/logback-test.xml
Later we’ll talk about the content of these files.
Now we’re ready 🙂
We have all bundles we need to catch all log events from commons-logging, Log4J, SLF4J or java.util.logging, to configure all of them in one configuration file and to log all using a single backend – the LOGBack Implementation.
An overview of the bundles:
To catch loggers from java.util.logging , one of your bundles has to contain this code:
All bundles you were using in the past which are exporting packages from org.apache.log4j or org.apache.commons.logging or slf4j.org cannot be used anymore. Please remove them from your target platform or from OSGI Launch Configurations.
This was the second part of my blog series “Logging in OSGI Enterprise Applications“:
- An overview
- How to catch all log events from “classic” logging – frameworks
- Part 3: … follows
Perhaps some of my older blogs about Logging und OSGI are also interesting:
the blog in german.