Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[platform-dev] Logging in Eclipse Platform

Hi platform team,

 

I was not active for quite a while, but now I am trying to get back more active in platform development again. I wanted to look at the logging mess that we have for quite a while and noticed that there is some activity in the meanwhile, e.g.

 

https://git.eclipse.org/r/#/c/148261/

https://git.eclipse.org/r/#/c/148262/

 

and several others where the different logging statements are now replaced with Platform#getLog() to get a static logging style.

 

I personally don’t like that static approach as it introduces more issues on the way than it solves. And actually my understanding was that with E4 we wanted to get rid of those static helpers as much as possible.

But it is indeed a good starting point to consolidate, so further improvements are easier to implement.

 

My idea would be to make use of the OSGi R7 Logging mechanism. There the LoggerFactory service is used to create Logger instances. The API is similar to the SLF4J API and has several benefits, e.g. String formatting via parameter etc.

 

Inside a Declarative Service the Logger could be retrieved simply via injection:

@Reference(service=LoggerFactory.class)

private Logger logger;

 

DS 1.4 is unfortunately not yet supported in PDE, so for the moment we would need to get the LoggerFactory injected and then create and retrieve the Logger manually:

LoggerFactory factory;

Logger logger;

 

@Reference

void setLogger(LoggerFactory factory) {

     this.factory = factory;

     this.logger = factory.getLogger(getClass());

}

 

For RCP Developers we could provide an ExtendedObjectSupplier so they can inject a Logger similarly in E4 classes:

@Qualifier

@Documented

@Target({ElementType.PARAMETER, ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)

public @interface Log {

       // Nop

}

 

@Component(

              service=ExtendedObjectSupplier.class,

              property = "dependency.injection.annotation=org.eclipse.e4.core.di.extensions.Log")

public class LoggerSupplier extends ExtendedObjectSupplier {

 

       @Reference

       private LoggerFactory factory;

 

       @Override

       public Object get(IObjectDescriptor descriptor, IRequestor requestorboolean trackboolean group) {

              if (requestor != null) {

                     Class<?> requestingObjectClass = requestor.getRequestingObjectClass();

                     if (requestingObjectClass != null) {

                           return factory.getLogger(

                                         FrameworkUtil.getBundle(requestingObjectClass), requestingObjectClass.getName(),

                                         Logger.class);

                     }

              }

              return factory.getLogger(requestor.getClass());

       }

 

}

 

 

The usage would then look like this:

@Log

@Inject

Logger logger;

 

In non-OSGi environments a custom ExtendedObjectSupplier that returns for example a SLF4J logger could be implemented. Maybe by creating an implementation of the org.osg.service.log.Logger that forwards to an SLF4J instance.

 

For the Platform development it would be a bit more complicated, as mostly we can’t use E4 dependency injection and also no DS dependency injection. But the Logger could be retrieved programmatically. If needed via static helper in Platform, although not my preferred solution a possible temporary workaround.

 

What I noticed as a possible issue is the usage of Platform#addLogListener(). Although the logs that are written via Platform#getLog() are forwarded to the OSGi LogService, the listeners are called on a higher level. So OSGi logs are NOT handled by those listeners. The question would be, is this intended or did it simply happen?

If it was not intended we could think about migrating those listeners to org.osgi.service.log.LogListener. I did a small test with the LogView that worked fine so far. But of course I am not sure if I tested everything and if every feature still works as intended.

 

Also if we migrate we won’t use IStatus anymore. For me it is also unclear what IStatus#CANCEL and IStatus#OK are used for in the context of logging. So the question here, is this still needed?

 

If you have a closer look to the logger class hierarchy in the platform, it looks like at the end everything ends in the OSGi LogService.

 

So despite of all the work that would be involved to migrate the log listeners and Logger etc, would it have any negative impacts if we deprecate LogHelper, FrameworkLog, PlatformLogWriter, IStatus, RuntimeLog etc. and move to the generic OSGi Logger? Do I miss something in my idea that would break existing use cases?

 

Feedback and discussion is welcome. The logging topic is ongoing for a long time. And I would like to get this solved in a good OSGi way that cleans up things.

Greez, 

Dirk 

 





Back to the top