Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 339799

Summary: Allow to disable the Equinox built-in log writer
Product: [Eclipse Project] Equinox Reporter: Gunnar Wagenknecht <gunnar>
Component: FrameworkAssignee: Thomas Watson <tjwatson>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: P3 CC: pnehrer, remy.suen, tjwatson
Version: 3.7   
Target Milestone: 3.7 M7   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
possible solution (work in progress)
none
possible fix none

Description Gunnar Wagenknecht CLA 2011-03-12 12:31:58 EST
Eclipse 3.7M6

The following exception is thrown. Looking at the source (InternalPlatform#getLog) the ExtendedLogReaderService seems to be null. Since this isn't a regular SDK/IDE but a headless server runtime I'm wondering if an ExtendedLogReaderService *always* mußt exists or if the legacy runtime log should also work if non is available.

java.lang.NullPointerException
	at org.eclipse.core.internal.runtime.InternalPlatform.getLog(InternalPlatform.java:418)
	at org.eclipse.core.runtime.Plugin.getLog(Plugin.java:291)
	at org.eclipse.ui.internal.WorkbenchPlugin.log(WorkbenchPlugin.java:940)
	at org.eclipse.ui.internal.AbstractSelectionService.fireSelection(AbstractSelectionService.java:158)
	at org.eclipse.ui.internal.AbstractSelectionService$1.selectionChanged(AbstractSelectionService.java:62)
	at org.eclipse.jface.viewers.Viewer$2.run(Viewer.java:163)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:51)
	at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
	at org.eclipse.jface.viewers.Viewer.fireSelectionChanged(Viewer.java:161)
	at org.eclipse.jface.viewers.StructuredViewer.updateSelection(StructuredViewer.java:2168)
	at org.eclipse.jface.viewers.StructuredViewer.handleSelect(StructuredViewer.java:1191)
	at org.eclipse.jface.viewers.StructuredViewer$4.widgetSelected(StructuredViewer.java:1221)
	at org.eclipse.jface.util.OpenStrategy.fireSelectionEvent(OpenStrategy.java:229)
	at org.eclipse.jface.util.OpenStrategy.access$3(OpenStrategy.java:223)
	at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:400)
	at org.eclipse.swt.internal.widgets.UntypedEventAdapter.dispatchEvent(UntypedEventAdapter.java:652)
	at org.eclipse.swt.internal.widgets.UntypedEventAdapter.widgetSelected(UntypedEventAdapter.java:88)
	at org.eclipse.swt.events.SelectionEvent.dispatchToObserver(SelectionEvent.java:196)
	at org.eclipse.rwt.internal.events.Event.processEvent(Event.java:44)
	at org.eclipse.swt.events.TypedEvent.processEvent(TypedEvent.java:163)
	at org.eclipse.swt.events.TypedEvent.executeNext(TypedEvent.java:203)
	at org.eclipse.swt.widgets.Display.runPendingMessages(Display.java:1143)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:1133)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2733)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2694)
	at org.eclipse.ui.internal.Workbench.access$5(Workbench.java:2530)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:702)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:685)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:157)
	at org.eclipse.gyrex.admin.ui.internal.application.AdminApplication.createUI(AdminApplication.java:28)
	at org.eclipse.rwt.internal.lifecycle.EntryPointManagerInstance.createUI(EntryPointManagerInstance.java:86)
	at org.eclipse.rwt.internal.lifecycle.EntryPointManager.createUI(EntryPointManager.java:33)
	at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:242)
	at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:111)
	at java.lang.Thread.run(Thread.java:662)
	at org.eclipse.rwt.internal.lifecycle.UIThread.run(UIThread.java:102)
Comment 1 Gunnar Wagenknecht CLA 2011-03-12 12:34:31 EST
Hmm, after some further investigation down the road I think it might be related to the following setting:

osgi.hook.configurators.exclude=org.eclipse.core.runtime.internal.adaptor.EclipseLogHook

So the question is, is it (still?) allowed to provide a custom log hook and if yes, does the log hook need to provide an ExtendedLogReaderService?
Comment 2 Thomas Watson CLA 2011-03-14 11:43:04 EDT
This is actually going to be a bit more difficult now that the log service in core wants to aggregate logs readers and writers from different log systems.  Perhaps you can build your solution on the extended log service instead of replacing the implementation provided by the framework?

Currently it appears there is no way to disable our built-in writer that writes out to the default .log file.  We probably should provide a way to disable this so you can plug in your own backend writer for all logs.
Comment 3 Gunnar Wagenknecht CLA 2011-03-14 12:10:06 EDT
(In reply to comment #2)
> This is actually going to be a bit more difficult now that the log service in
> core wants to aggregate logs readers and writers from different log systems. 
> Perhaps you can build your solution on the extended log service instead of
> replacing the implementation provided by the framework?

I think that is doable. All I want is capturing log events from the framework and route it to my log system (eg. syslog log server) instead of the ".log" file.

From my understanding, all I need to provide is a LogListener? 

> Currently it appears there is no way to disable our built-in writer that writes
> out to the default .log file.  We probably should provide a way to disable this
> so you can plug in your own backend writer for all logs.

The only option I saw (and implemented) was to replace the EclipseLogHook with my own implementation. I think that's still a valid option, though. It avoids too many layers of routing because it would allow me to capture events directly. ;)

Should I re-phrase the request to allow disabling the built-in writer? What is necessary to ensure that I get *all* log events? I assume that I have to implement some kind of start ordering. So that my log listener would be available very early?
Comment 4 Thomas Watson CLA 2011-03-14 17:20:19 EDT
(In reply to comment #3)
> (In reply to comment #2)
> > This is actually going to be a bit more difficult now that the log service in
> > core wants to aggregate logs readers and writers from different log systems. 
> > Perhaps you can build your solution on the extended log service instead of
> > replacing the implementation provided by the framework?
> 
> I think that is doable. All I want is capturing log events from the framework
> and route it to my log system (eg. syslog log server) instead of the ".log"
> file.
> 
> From my understanding, all I need to provide is a LogListener? 

You need a LogListener and a LogFilter that listens to the "org.eclipse.equinox.logger" loggerName.  See org.eclipse.core.runtime.internal.adaptor.EclipseLogWriter.isLoggable(Bundle, String, int) for an example.

> 
> > Currently it appears there is no way to disable our built-in writer that writes
> > out to the default .log file.  We probably should provide a way to disable this
> > so you can plug in your own backend writer for all logs.
> 
> The only option I saw (and implemented) was to replace the EclipseLogHook with
> my own implementation. I think that's still a valid option, though. It avoids
> too many layers of routing because it would allow me to capture events
> directly. ;)

But then it avoids registering the ExtendedLogService which is still needed by the rest of the platform.

> 
> Should I re-phrase the request to allow disabling the built-in writer? 

Yes, I think we should be able to disable the built-in eclipse log writer.

> What is
> necessary to ensure that I get *all* log events? I assume that I have to
> implement some kind of start ordering. So that my log listener would be
> available very early?

If you need to be very early you would have to use a framework extension and implement the org.eclipse.osgi.baseadaptor.hooks.AdaptorHook.frameworkStart(BundleContext)

to register your LogListener and LogFilter with the org.eclipse.equinox.log.ExtendedLogReaderService.addLogListener(LogListener, LogFilter) method
Comment 5 Gunnar Wagenknecht CLA 2011-03-14 17:28:24 EDT
Thanks Thomas! Do you think it's possible to get a patch in for M7? If yes I'm happy to work on one.

I think it should be possible to prevent the .log file using a system/framework property. What's your opinion about the logs generated in the configuration area? I often find them useful in case something really goes wrong. Should they still be written? IMHO it's sufficient to "just" disable the built-in writer the writes the instance/.metadata/.log file.
Comment 6 Thomas Watson CLA 2011-03-14 17:38:44 EDT
(In reply to comment #5)
> Thanks Thomas! Do you think it's possible to get a patch in for M7? If yes I'm
> happy to work on one.
> 
> I think it should be possible to prevent the .log file using a system/framework
> property. What's your opinion about the logs generated in the configuration
> area? I often find them useful in case something really goes wrong. Should they
> still be written? IMHO it's sufficient to "just" disable the built-in writer
> the writes the instance/.metadata/.log file.

This writer is one and the same in Equinox.  So disabling it will also disable the writer of the log to the configuration area.  What happens at the platform level is when the workspace is choosen the platform tells the log implementation about the new place to write the log and the eclipse log writer moves it to the workspace.  So I am not sure we can disable the way you are describing.

Yes, I was thinking the eclipse .log writer could be disabled with a configuration property.

One possibility could be to automatically disable the built-in logger if another LogFilter comes along that returns true for the logger "org.eclipse.equinox.logger".  We could try to call org.eclipse.equinox.log.LogFilter.isLoggable(null, "org.eclipse.equinox.logger", loglevel) for all loglevels that are configured to be logged.  That is a bit hacky and magical to me though which usually causes more confusion when things go wrong.
Comment 7 Gunnar Wagenknecht CLA 2011-03-15 03:09:34 EDT
(In reply to comment #6)
> One possibility could be to automatically disable the built-in logger if
> another LogFilter comes along that returns true for the logger
> "org.eclipse.equinox.logger".

Although such a magic sounds smart, I also think that it causes more confusion. Having a property that must explicitly be set it more predictable.
Comment 8 Thomas Watson CLA 2011-03-17 10:38:58 EDT
I will look at adding a way to disable the built-in log writer.
Comment 9 Thomas Watson CLA 2011-03-21 17:24:00 EDT
Created attachment 191646 [details]
possible solution (work in progress)

This patch is a work in progress.  I still need to do more testing.  It adds a configuration option eclipse.log.enabled which defaults to "true".  Setting it to "false" will disable all writing of log entries to the eclipse .log file.

This patch also contains some unrelated fixes to RuntimeLog/PltformLogWriter from common.  These are not strictly needed for this fix but I think it cleans up the LogFilter story so that the org.eclipse.equinox.logger named logger really does nothing unless there is a real listener doing work for that named logger.
Comment 10 Thomas Watson CLA 2011-03-22 10:07:27 EDT
Created attachment 191680 [details]
possible fix

After more testing I decided to split the changes to common in bug340659.
Comment 11 Thomas Watson CLA 2011-03-22 11:59:03 EDT
I released the latest patch.  Gunner, let me know if this is sufficient for your needs.  Thanks.
Comment 12 Gunnar Wagenknecht CLA 2011-03-22 12:02:22 EDT
Thanks a lot! Will try to update soon. Not sure if I get to this this week, though.
Comment 13 Thomas Watson CLA 2014-03-19 17:31:06 EDT
*** Bug 430661 has been marked as a duplicate of this bug. ***