The OSGi Log Service

Developers who are used to a logging tool, such as log4j, are compelled to use the same logging setup in an OSGi framework. After overcoming the initial first obstacles relating to codebase separation and resource visibility, the developers succeed in making it work. The result would typically look like the following diagram:

The OSGi Log Service

Such structures would work. However, they usually require a complex configuration to be set up and maintained. A better option is the use of a common logging service.

The OSGi Compendium specifications define a set of Log Service interfaces that are intended to provide a common logging service for an OSGi framework.

The Log Service applies separation of concerns by splitting functionality into the following two services:

  • The Log Service interface is used by bundles that need to send logs this is the service end
  • The Log Reader Service interface set is used by bundles that need to read logs— this is the service provider end

Let's take a closer look at those.

The Service end

The Log Service interface exposes a simple, but expandable, logging API for use by the bundles that need to send log events. Those bundles would all depend on a single logging interface.

The Service end

The Log Service interface method declarations are variations of log():

log(int level, String message)

For logging a message at a log level.

The log levels are declared as constants in the same interface:

  • LOG_DEBUG: An integer with the value 4 for debug level logs
  • LOG_INFO: With value 3 for info logs
  • LOG_WARNING: With value 2 for warning logs
  • LOG_ERROR: With value 1 for error logs

To also pass an exception with the log entry, the signature with the Throwable parameter is used:

log(int level, String message, Throwable exception)

The same methods are also provided with a ServiceReference as the first parameter:

log(ServiceReference sr, int level, String message)
log(ServiceReference sr, int level, String message,
Throwable exception)

In this case, the log message is registered as relating to the bundle with the provided service reference (instead of relating to the bundle invoking the log() method).

Usage of the Log Service

The Log Service is used just like any other service on an OSGi framework.

To get access to a Log Service instance using the service locator, the look-up is done with the class name:

LogService log = null;
ServiceReference ref = context.getServiceReference(
LogService.class.getName());
if (ref != null)
{
log = (LogService) context.getService(ref);
}

Using iPOJO, the LogService is declared as a field of the service:

LogService log;

Then the field is declared for injection in the service component declaration in the iPOJO configuration:

<requires field="log" />

We will go through this again in a bit, when adding logging to our services.

The service provider end

What was just mentioned is all that's required when developing the bundle. At runtime, a Log Service implementation is needed.

In this section, we'll look at the service provider side of the Log Service in OSGi. It is not strictly necessary to know how it works. However, it's interesting to go through it for completeness.

According to the OSGi compendium specifications, the Log Service provider is to abide to the following setup:

The service provider end

The Log Service implementation packs received logs as Log Events and posts them with the Log Server Reader implementation.

The Log Service Reader exposes a means to access held log events, as well as the ability to register Log Listeners.

Registered Log Listener implementations receive log events and process them as they see fit. Some listeners may write the log entries to a file, others may forward them to an external logging component.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset