[osgi logging] part 6 – how to start the logging framework

This is part 6 of my blogseries about ‘Logging in OSGI Enterprise Applications‘ – you’ll find all parts here.

Normaly you put your needed bundles into the Dropins folder from your IDE (if there’s no update site) or add them to your Target Platform definition and you’re done.

Integrating a Logging Framework there are some requirements:

  • you want to get all logged messages from the beginning, so logging bundles have to start early
  • you want to control that your bundles are used and not others providing the same packages

You should always carefully think about using Start-Levels, but in this case it makes sense.

If you followed my blog series about Target Platform, then you know that its important to distinguish between IDE and Runtime (Target Platform).

Starting Logging Framework from OSGI Runtime

In most cases you’re interested into the Runtime only, because you want to know what your running product is logging.

Since Galileo you can define the Start-Level in the Product Configuration file:

product.configuration.plug-ins

– same way as from an OSGI Launch Configuration:

osgi.launch.configuration.bundles

or from an Eclipse Application Configuration:

eclipse.app.plugins.config

Youl’ll find the setting of Start-Level and Auto-Start under different Tabs and named Plug-Ins or Bundles, but its always the same 😉

Hint: The Auto-Start “default” depends from your setting of “Default Auto-Start” as false or true. If you want to be sure that the right value was choosen you should explicit set to true or false at each bundle.

Here are the settings to autostart the Logging Framework early from your Runtime Product / OSGI Launch / Application Launch:

per ex. Default Auto-Start Level 3

  • org.eclipse.osgi: Start-Level -1, Auto-Start true
  • org.eclipse.equinox.common: Start-Level 2, Auto-Start true
  • org.eclipse.equinox.ds: Start-Level default, Auto-Start true
  • all logging framework bundles: Start-Level 2, Auto-Start true
  • org.ekkescorner.logging bundles: Start-Level 2, Auto-Start true
  • all other bundles: Start-Level default, Auto-Start default

what happens:

logging start level

  1. Start-Level -1: Equinox OSGI Runtime starts at first
  2. Start-Level 2: equinox.common and all logging bundles are started
    1. org.ekkescorner.logging.starter.runtime (Bundle-ActivationPolicy: lazy)
      1. Avtivator start() calls SLF4JBridgeHandler.install() – this causes bundle ‘jul.to.slf4j’ to catch all java.util Logging
      2. logs a message: logger.debug(Activator.bundleMarker, “SLF4JBridgeHandler started”) – this causes slf4j and logback to begin initialization, read the config and perhaps log something
  3. Start-Level default: all bundles with Auto-Start true are started
    1. org.eclipse.equinox.ds is auto-started
      1. analyzes the DS Component from org.ekkescorner.logging.starter.runtime
      2. if LogReaderServices or ExtendedLogReaderServices become available, our LogListeners will get the LogEntries
    2. other bundles are started if needed and because SLF4J / Logback is initialized all dependencies to logging packages are resolved from SLF4J / Logback and all log messages are catched

Starting Logging Framework from IDE

In some cases you may have the need to log from your running IDE and it should work simply adding some bundles.

Adding bundles to Dropins folder or updating from Update Sites there’s no easy way to set Start-Level or Auto-Start.

Above you have seen how we solve this with the org.ekkescorner.logging.starter.runtime bundle at Runtime

– for the IDE we use another Bundle: org.ekkescorner.logging.starter.ide (Bundle-ActivationPolicy: lazy)

the important part – we have to use the Extension Point org.eclipse.ui.startup to get the bundle early started:

autostart.ide.plugin.xml

the Class AutoStartLogging has to implement org.eclipse.ui.IStartup

import org.eclipse.ui.IStartup;
import org.ekkescorner.logging.starter.ide.Activator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;

public class AutoStartLogging implements IStartup {

	// logger name = class name
	private static final Logger logger = LoggerFactory.getLogger(AutoStartLogging.class);

	public void earlyStartup() {

		logger.info(Activator.bundleMarker, "earlyStartup slf4j SLF4JBridgeHandler..."); //$NON-NLS-1$	

		// route java.util.logging to slf4j
		SLF4JBridgeHandler.install();

		logger.debug(Activator.bundleMarker, "SLF4JBridgeHandler started"); //$NON-NLS-1$

	}
}

You need this bundle only if you really have to receive log messages from the bundles of your running IDE.

One of my use-cases is the development and test of the redView WYSIWYG Designer – Editor where it’s great to get logging messages from the redView Designer bundles.
you’ll find the overview of this blog series here. stay tuned… part7 follows…

7 responses

  1. Hello ekke!

    I got a package uses conflict(Import-package:org.slf4j; version”1.5.10″) when I follow your “Starting Logging Framework from IDE” section.

    It is all ok on a simple target platform for testing the logging bundles.
    The conflict arise when I try to integrate these logging bundles into my RCP application.

    org.ekkescorner.logging.starter.ide bundle in conflict while org.ekkescorner.logging.starter.runtime is ok.

    So I guess that starter.ide’s Require-Bundle: org.eclipse.core.runtime ,org.eclipse.ui;bundle-version=”3.5.1″ causes the conflict.
    I could not find anything suspicious in their manifest.

    The Target Platform State view cant tell me which bundle lead to conflict.

    Please give me some suggestions.

    I am new to OSGi.Your blog helped me a lot!
    Thank you!

    • hao,
      this week I’ll publish actual versions of my bundles – then you can compare with your solution and hopefully get it run.
      a package uses conflict means that there’s a bundle exporting some packages with wrong use-clause.
      you can re-calculate usage from PDE MANIFEST editor – runtime tab – calculate uses.
      a workaround – but this does not fixe your problem – is to start the app with
      -Dosgi.resolver.usesMode=ignore
      ekke

      • ekke,
        ‘packages’ console directive show me that only bundle com.springsource.slf4j.api[1.5.10] supply package ‘org.slf4j’ and
        package ‘org.slf4j.bridge’ supply by bundle com.springsource.slf4j.bridge[1.5.10].

        I think there are no dependent constraint mismatches.
        May be it is a resolution order issue or something eles.

        So I use ‘-Dosgi.resolver.usesMode=ignore’ argument until you publish these bundles.
        Finally, I will find a reason for the strange conflict:)

        Thank you! Best regards!

  2. Hello ekke!

    After a long walk outside…
    I’ve got the solution.

    I used Eclipse new project wizard created a plug-in targeted to run with Eclipse version 3.5.
    The project template requires ‘org.eclipse.core.runtime’ bundle which caused conflict.

    After I remove the required ‘org.eclipse.core.runtime’ it all works well!

    Thank you! Best regards!

  3. Hi Hao,

    I am experiencing the same problem with the package use conflict on my headless PDE build.
    What is your explanation why the removal of the dependency to ‘org.eclipse.core.runtime’ helped to solve the problem? Unfortunately, this is no viable option for me as I have >100 bundles using it…

    @Ekke: Did you meanwhile succeed setting up the logging with the latest versions (logback 0.9.18 + SLF4J 1.5.10)?

    Cheers, Kai.

Leave a comment