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
requestor, *boolean* track, *boolean* 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
_______________________________________________
platform-dev mailing list
platform-dev@eclipse.org
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://www.eclipse.org/mailman/listinfo/platform-dev

Reply via email to