The OSGi Service Compendium specification defines a general purpose Log Service for the OSGi Platform.
It is a very simple specification that doesn't provide all the functionalities commonly available in enterprise-level logging tools, but its extensible service model can be used to build fairly sophisticated logging solutions.
The Log Service specification defines four main entities:
If the OSGi platform provides a Log Service, getting a reference to it is as simple as doing a normal OSGi service lookup:
public class Activator implements BundleActivator
{
public void start(BundleContext context) throws Exception
{
ServiceReference ref = context.getServiceReference(LogService.class.getName());
if (ref!=null)
{
LogService log = (LogService) context.getService(ref);
//use the log
}
}
//..
|
(Of course it's possible, and advisable, to use more sophisticated service acquisition mechanisms like a Service Tracker, Dynamic Services or iPOJO)
The Log Service provides four methods to define logs:
public interface LogService
{
//..
// log a message specifying a log level
public log(int level, java.lang.String message)
//log an exception
public log(int level, java.lang.String message, java.lang.Throwable exception)
//log a message specifying the ServiceReference that generates it
public log(ServiceReference sr, int level, java.lang.String message)
public log(ServiceReference sr, int level, java.lang.String message, java.lang.Throwable exception)
}
|
Log levels are defined in the same interface:
The LogReaderService provides a getLog() method to retrieve an Enumeration of the latest log entries.
ServiceReference ref = context.getServiceReference(LogReaderService.class.getName());
if (ref!=null)
{
LogReaderService reader = (LogReaderService) context.getService(ref);
Enumeration<LogEntry> latestLogs = reader.getLog();
}
|
The Log Service specification doesn't define any particular entity to store, display or write log entries; it's up to the developer to implement this functionality, or to choose an already available bundle capable of doing that.
To create such a bundle, the first step is to create an implementation of the LogListener interface:
public class LogWriter implements LogListener
{
public void logged(LogEntry entry)
{
//invoked by the OSGi platform every time a log entry is created
System.out.println(entry.getMessage());
}
}
|
The only method to implement is public void logged(LogEntry entry); this method will be called every time an installed bundle submits a log entry.
The second and final step is to register the newly created LogListener so it can start receving log entries:
ServiceReference ref = context.getServiceReference(LogReaderService.class.getName());
if (ref!=null)
{
LogReaderService reader = (LogReaderService) context.getService(ref);
reader.addLogListener(new LogWriter());
}
|
The Apache Felix Log Service bundle doesn't have any specific dependency on Felix, so it can run on any OSGi container. For its configuration, it will use the following optional system properties:
Property |
Default |
Description |
|---|---|---|
|
100 |
The maximum size of the log used to maintain historic log information. A value of -1 means the log has no maximum size; a value of 0 means that no historic log information will be maintained |
|
false |
Determines whether or not debug messages will be stored as part of the historic log information |