Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible performance improvement for high frequency logging using EquinoxLogWriter #221

Closed
alxflam-work opened this issue Feb 24, 2023 · 8 comments
Labels

Comments

@alxflam-work
Copy link
Contributor

alxflam-work commented Feb 24, 2023

Hi,

i've been taking a look at EquinoxLogWriter recently and noticed the following behavior:

log(FrameworkLogEntry logEntry) always creates a new BufferedWriter with a new FileOutputStream for the given log file as the finally block in log always sets the writer to null (closeFile is called). If one makes heavy usage of logging, this can be a performance issue: Say you log a large number of FrameworkLogEntrys, then the FOS is opened and closed for every single log invocation.

Wouldn't it be possible to improve performance by only re-creating the BufferedWriter when necessary:

  • once the log file changes by use of the setter: setOutput is already called by setFile, therefore the writer is closed and set to null
  • once the log file rotates due to the max size restriction: checkLogFileSize already calls setOutput and therefore ensures the writer is closed and set to null if the log file changes

As both setFile and log are synchronized, wouldn't it be possible to omit the closeFile call in the log method to keep the writer instance and thereby improving performance for consecutive log invocations? Sure, then there's an open FOS for the runtime of the equinox application, e.g. for the complete runtime of an eclipse RCP. But isn't that somewhat expectable for the log file? A new dispose method may be required which can be called to free the writer and any other members, this could be called e.g. by EquinoxLogServices#stop.

What do you think - is this something that could be improved as outlined? I may just not spot the reason why the writer is not reused.

Greetings,
Alex

@tjwatson
Copy link
Contributor

tjwatson commented Feb 24, 2023

The log writing code itself predates even Equinox. IIRC the current behavior be necessary for things like the PDE log viewer so that it gets notified when the content of the file changes. At the least we need to make sure the content is flushed to disk each entry write I think.

@alxflam-work
Copy link
Contributor Author

@tjwatson i think flushing the stream would be fine if the writer is cached, the performance is still improved as the SecurityManager checks as well as the native file opening are then still omitted. This still is a large improvement, e.g. 50k log invocations take ~2s if the writer is reused whereas closing and re-creating the writer on every log invocation yields ~40s. While such large numbers of log invocations usually do not occur, it will still be a minor performance improvement even if logging is not used that frequently.

Regarding the LogView i've checked the code and the view registers itself as a LogListener using the LogReaderService. Therefore, once the log view got created the ExtendedLogReaderServiceFactory will not only have the EquinoxLogWriter as a listener, but additionally the LogView. So the log view is informed about new logs without actually parsing them from the file. There are situations when the log file is actually parsed by the view, e.g. when the view is initially opened.

So i think that such a change should not affect the LogView in eclipse as long as flush is called for every log entry.

@laeubi
Copy link
Member

laeubi commented Feb 27, 2023

If different classes access the same file, one only needs to make sure it can be shared (e.g. windows don't like to write a file that is currently opened by another process) so this should be checked both on windows/linux to work smoothly.

@tjwatson
Copy link
Contributor

If different classes access the same file, one only needs to make sure it can be shared (e.g. windows don't like to write a file that is currently opened by another process) so this should be checked both on windows/linux to work smoothly.

The log is either instance specific with a unique name contained in the framework storage area, or it has been set to the .log in the workspace data area which has to be locked first before we change the log location to the workspace data area. So I don't think windows file locking behavior should be an issue here since multiple processes should not be using the same log file location.

@tjwatson
Copy link
Contributor

@alxflam-work best way to get this done is to open a PR with your suggested changes. Thanks.

@github-actions
Copy link

This issue has been inactive for 180 days and is therefore labeled as stale.
If this issue became irrelevant in the meantime please close it as completed. If it is still relevant and you think it should be fixed some possibilities are listed below.
Please read https://github.com/eclipse-equinox/.github/blob/main/CONTRIBUTING.md#contributing-to-eclipse-equinox for ways to influence development.

@github-actions github-actions bot added the stale label Aug 27, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Sep 3, 2023
@iloveeclipse iloveeclipse reopened this Oct 19, 2023
@github-actions github-actions bot removed the stale label Oct 20, 2023
alxflam-work added a commit to alxflam-work/equinox that referenced this issue Oct 24, 2023
Closes eclipse-equinox#221. The eager behavior can be enabled by setting configuration
eclipse.log.closeFile.eagerClose to true (defaults to false).
iloveeclipse added a commit to iloveeclipse/equinox that referenced this issue Oct 25, 2023
invocation"

This reverts commit 53dc6b6 as it
caused test failures in
- org.eclipse.core.tests.internal.runtime.LogSerializationTest
- org.eclipse.equinox.p2.tests.mirror.ArtifactMirrorApplicationTest
- org.eclipse.equinox.p2.tests.mirror.NewMirrorApplicationArtifactTest

Note: pom and manifest files are left unchanged to avoid going back with
bundle versions.

Original PR: eclipse-equinox#382
Original ticket: eclipse-equinox#221
iloveeclipse added a commit that referenced this issue Oct 25, 2023
invocation"

This reverts commit 53dc6b6 as it
caused test failures in
- org.eclipse.core.tests.internal.runtime.LogSerializationTest
- org.eclipse.equinox.p2.tests.mirror.ArtifactMirrorApplicationTest
- org.eclipse.equinox.p2.tests.mirror.NewMirrorApplicationArtifactTest

Note: pom and manifest files are left unchanged to avoid going back with
bundle versions.

Original PR: #382
Original ticket: #221
@iloveeclipse
Copy link
Member

Reopening, change reverted in #388, see discussion on #382.

@iloveeclipse iloveeclipse reopened this Oct 25, 2023
Copy link

This issue has been inactive for 180 days and is therefore labeled as stale.
If this issue became irrelevant in the meantime please close it as completed. If it is still relevant and you think it should be fixed some possibilities are listed below.
Please read https://github.com/eclipse-equinox/.github/blob/main/CONTRIBUTING.md#contributing-to-eclipse-equinox for ways to influence development.

@github-actions github-actions bot added the stale label Apr 23, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants