OSGi Log Service
The OSGi specification defines a log service (Section 101.1) in the Service Compendium. Like most logging facilities, the log service allows you to specify a message, exception, log level and service reference to be logged. The log service can be acquired using typical OSGi service acquisition mechanisms like a ServiceTracker (see snippet below). However, I highly recommend that you look at using Declarative Services (see Section 112) if you’re working with OSGi services.
public class Activator implements BundleActivator {
private ServiceTracker logServiceTracker; private LogService logService; public void start(BundleContext context) throws Exception { // create a tracker and track the log service logServiceTracker = new ServiceTracker(context, LogService.class.getName(), null); logServiceTracker.open(); // grab the service logService = (LogService) logServiceTracker.getService();
if(logService != null) logService.log(LogService.LOG\_INFO, "Yee ha, I'm logging!"); }
public void stop(BundleContext context) throws Exception { if(logService != null) logService.log(LogService.LOG\_INFO, "Yee ha, I'm logging!"); // close the service tracker logServiceTracker.close(); logServiceTracker = null; } } ```
Once acquired, you can log messages using the various utility methods LogService:
```java public interface LogService { public static final int LOG\_ERROR = 1; public static final int LOG\_WARNING = 2; public static final int LOG\_INFO = 3; public static final int LOG\_DEBUG = 4; public void log(int level, String message); public void log(int level, String message, Throwable exception); public void log(ServiceReference sr, int level, String message); public void log(ServiceReference sr, int level, String message, Throwable exception); } ```
The messages are logged as [LogEntry](https://www.osgi.org/javadoc/r4v41/org/osgi/service/log/LogEntry.html) objects.
```java public interface LogEntry { public Bundle getBundle(); public ServiceReference getServiceReference(); public int getLevel(); public String getMessage(); public Throwable getException(); public long getTime(); } ```
It's that simple! The problem with this simplicity is that this type of logging may not be enough for certain projects. The [Equinox](https://www.eclipse.org/equinox) project at Eclipse has recently graduated an [extended log service](https://bugs.eclipse.org/bugs/show_bug.cgi?id=260672). The extended log service is similar to the log service we discussed, but there are a few useful additions like named loggers:
```java public interface ExtendedLogService extends LogService, Logger { public Logger getLogger(String loggerName); public Logger getLogger(Bundle bundle, String loggerName); } public interface Logger { public void log(int level, String message); public void log(int level, String message, Throwable exception); public void log(ServiceReference sr, int level, String message); public void log(ServiceReference sr, int level, String message, Throwable exception); public void log(Object context, int level, String message); public void log(Object context, int level, String message, Throwable exception); public boolean isLoggable(int level); public String getName(); } ```
There is also an extended log entry that has information like a logger name and thread-related information:
```java public interface ExtendedLogEntry extends LogEntry { String getLoggerName(); Object getContext(); long getThreadId(); String getThreadName(); long getSequenceNumber(); } ```
That's it!
For those working in RCP or OSGi projects, how are you guys handling logging? Are you using the LogService, Pax Logging or something more exotic?