Logging in OSGi and eclipse RCP
I’m further along with logging in an OSGi environment especially eclipse RCP. I found these blogs that are very useful:
- http://ekkes-corner.blogspot.com/2008/10/index-blogseries-logging-in-osgi.html
- http://blog.kornr.net/index.php/2008/12/16/writing-an-osgi-logging-back-end
- http://ekkes-corner.blogspot.com/2008/10/logging-in-osgi-enterprise-applications_31.html
- http://www.dynamicjava.org/articles/osgi-matters/logging-osgi-the-simple-way/11-osgi-matters/110-logging-osgi-the-simple-way
The real issue is that OSGi is a much stricter environment in terms of how the classpath is built and hence, the standard logging and logging facades (like slf4j) do not work properly in a strict OSGi environment. Eclipse equinox provides some relief through equinox specific or eclipse specific mechanisms but we need a logging solution that can operate in a strict OSGi environment but integrate multiple logging and logging facade APIs because most likely, in any decent sized application, you will need to manage multiple logging ecosystems within subsystems such as hibernate or spring.
What does eclipse’s equinox do?
First, before equinox was used for plugins in eclipse, there was a logging mechanism already in place. Typically, in most applications, you would define a master logging method in the plugin class specific to your bundle to help with general logging using IStatus.
1: public static void log(String message) {
2: getDefault().getLog().log(
3: StatusUtil.newStatus(IStatus.ERROR, message, null));
4: }
or at least something like this. The actual interface obtained from the plugin was ILog which is an object created by the eclipse runtime for each bundle. Note that if you used this interface you are tied to the eclipse platform which for UI plugins is okay but for general subsystems that may have usefulness outside of eclipse would be bad. The class org.eclipse.core.internal.runtime.Log implements ILog and this Log class uses an internal eclipse platform logger: InternalPlatform.getDefault().log(status); and it also runs the logged message through and specific bundle-level listeners. The InternalPlatform object uses a RuntimeLog object which essentially broadcasts/multiplexes the log message to all listeners at the platform level. The javadoc suggests that this class is to be replaced at some point. Two primary listeners at the platform level are defined, a status manager listener StatusManager.StatusManagerLogListener which puts status messages into an eclipse view, and a LogWriterwhich is a bridge between the platform and OSGi (some day) framework logging. The LogWriter writes to another interface for OSGi called org.eclipse.osgi.framework.log.FrameworkLog. There are two implementations for this interface, one that is an anonymous class that acts as a default OSGi logger that merely prints to System.err and a second that is called EclipseLog that writes to a file or some other OS specific location. This logger is brought in through the framework adapter which adapts the framework to a specific OS. FrameworkAdapter is an interface that allows more extensions to a platform and this defines a method to obtain a framework log through FrameworkAdapter.createFrameworkLog(). Different framework log implementations exist (several in fact) but many do not define an additional logging mechanism.
Based on code inspection it does not appear that eclipse use the OSGi logging service yet or perhaps never. However look here: http://eclipsesource.com/blogs/2009/03/24/tip-osgi-log-service/ and you can see that equinox does implement logging and extended logging services. Here’s the equinox home page: http://www.eclipse.org/equinox/bundles/. The logging service code is deleted (!) because they just switched to a newer logging service implementation. Here is the bug report that shows the extended log service (compatible with basic OSGi I believe) and says that eclipse does not use OSGi logging yet: https://bugs.eclipse.org/bugs/show_bug.cgi?id=260672. If you want to use this implementation but still use slf4j API, you will need a bridge between the two.
There are different ways to create the bridge. One can load up on slf4j in your own modules and use bridges to the slf4j interfaces that came from the slf4j home page. Then you can use a slf4j to osgi bridge that shoves all messages into the OSGi logging service. Then you can have a bridge between the OSGi logging service and logback (for example). Or you can everything, including OSGi logging services, go to the logback logging engine directly. The biggest issue I see with throttling everything OSGi logging services is that there is less chance for optimization and logging will take up more CPU and memory cycles—which may or may not be a big problem for your application.
The slf4j website has a svn (and perhaps built plugin) that has OSGi logging over slf4j. If you use this plugin, you still need to provide a slf4j logging implementation.
Comments
Post a Comment