Skip to content

TRUNK-6392: Improvements to the OpenMRS Logging plugin#6104

Open
ibacher wants to merge 10 commits into
masterfrom
fix-logging
Open

TRUNK-6392: Improvements to the OpenMRS Logging plugin#6104
ibacher wants to merge 10 commits into
masterfrom
fix-logging

Conversation

@ibacher
Copy link
Copy Markdown
Member

@ibacher ibacher commented May 18, 2026

Description of what I changed

OpenMRS leverages Log4J2's plugin system to provide a compatibility layer with older versions of OpenMRS's ability to configure the logging system.

This commit addresses a number of small issues in the initial implementation of this plugin that do not work as expected in production conditions. This includes:

  • Proper handling of looking up custom logger properties during application start-up
  • Incorrect synchronization of the MemoryAppender, which could cause message losses between reconfigurations
  • Not acquiring correct privileges to read global properties
  • applyLogLevels could apply to the wrong logger, especially when being used to configure loggers that aren't part of the default configuration
  • Composite logger configurations were not correctly handled

It also adds regression testing for most of the features in the logging plugin.

Issue I worked on

see https://issues.openmrs.org/browse/TRUNK-6392

Note that this goes a bit beyond the scope of that ticket, but does address the concern as well.

Checklist: I completed these to help reviewers :)

  • My IDE is configured to follow the code style of this project.

    No? Unsure? -> configure your IDE, format the code and add the changes with git add . && git commit --amend

  • I have added tests to cover my changes. (If you refactored
    existing code that was well tested you do not have to add tests)

    No? -> write tests and add them to this commit git add . && git commit --amend

  • I ran mvn clean package right before creating this pull request and
    added all formatting changes to my commit.

    No? -> execute above command

  • All new and existing tests passed.

    No? -> figure out why and add the fix to your commit. It is your responsibility to make sure your code works.

  • My pull request is based on the latest changes of the master branch.

    No? Unsure? -> execute command git pull --rebase upstream master

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability of logging configuration reload behavior when log-level properties are deleted
    • Fixed log event buffer management during capacity adjustments and event migration
  • Tests

    • Added comprehensive test coverage for logging configuration management, buffer operations, and property-level changes

Review Change Stack

OpenMRS leverages Log4J2's plugin system to provide a compatibility layer
with older versions of OpenMRS's ability to configure the logging system.

This commit addresses a number of small issues in the initial implementation
of this plugin that do not work as expected in production conditions.
This includes:

- Proper handling of looking up custom logger properties during application
  start-up
- Incorrect synchronization of the MemoryAppender, which could cause
  message losses between reconfigurations
- Not acquiring correct privileges to read global properties
- applyLogLevels could apply to the wrong logger, especially when being
  used to configure loggers that aren't part of the default configuration
- Composite logger configurations were not correctly handled

It also adds regression testing for most of the features in the logging
plugin.
@ibacher ibacher requested a review from Copilot May 18, 2026 20:31
@openmrs openmrs deleted a comment from coderabbitai Bot May 18, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request improves the OpenMRS Log4J2 logging plugin compatibility layer to behave more reliably under real startup and reconfiguration conditions, and adds regression tests around property lookup, configuration discovery, log-level application, and global property listener behavior.

Changes:

  • Add proxy-privilege handling when reading global properties for logging configuration/lookup.
  • Improve logger level application to correctly target non-default/custom logger names and handle composite configurations.
  • Refactor in-memory log buffering (MemoryAppender) and add comprehensive unit/integration-style tests for the logging utilities and plugin behaviors.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
api/src/main/java/org/openmrs/logging/OpenmrsConfigurationFactory.java Improves config discovery and multi-config composition; applies log levels with privilege elevation.
api/src/main/java/org/openmrs/logging/OpenmrsLoggingUtil.java Fixes log appender lookup, adds privilege elevation for GP reads, and improves logger config targeting.
api/src/main/java/org/openmrs/logging/OpenmrsPropertyLookup.java Adds startup-safe defaults and privilege elevation for GP lookups used in Log4J2 configs.
api/src/main/java/org/openmrs/logging/MemoryAppender.java Refactors buffer lifecycle/sharing across reconfigurations and adds queue-capacity awareness.
api/src/main/java/org/openmrs/logging/LoggingConfigurationGlobalPropertyListener.java Adjusts deletion handling to avoid unnecessary reloads for log.level and fixes switch flow.
api/src/main/java/org/openmrs/util/ThreadSafeCircularFifoQueue.java Adds capacity() accessor used by MemoryAppender refactor.
api/src/main/java/org/openmrs/util/MemoryAppender.java Updates deprecated adapter to match new MemoryAppender constructor signature.
api/src/test/java/org/openmrs/logging/OpenmrsPropertyLookupTest.java New tests for property lookup behavior across startup vs normal operation, including privilege handling.
api/src/test/java/org/openmrs/logging/OpenmrsLoggingUtilTest.java New tests for logger level application, log location lookup, and reload behavior.
api/src/test/java/org/openmrs/logging/OpenmrsConfigurationFactoryTest.java New tests for discovering/sorting/ignoring config files and extension constants.
api/src/test/java/org/openmrs/logging/MemoryAppenderTest.java Expanded tests for buffer sizing/defaults, ordering, overwrites, plugin factory behavior, and layout validation.
api/src/test/java/org/openmrs/logging/LoggingConfigurationGlobalPropertyListenerTest.java New tests ensuring correct reload/apply behavior and caching semantics on GP updates/deletes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread api/src/main/java/org/openmrs/logging/OpenmrsConfigurationFactory.java Outdated
Comment thread api/src/main/java/org/openmrs/logging/MemoryAppender.java Outdated
coderabbitai[bot]

This comment was marked as low quality.

@openmrs openmrs deleted a comment from coderabbitai Bot May 18, 2026
@ibacher ibacher requested a review from Copilot May 18, 2026 21:49
@openmrs openmrs deleted a comment from coderabbitai Bot May 18, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

api/src/main/java/org/openmrs/logging/LoggingConfigurationGlobalPropertyListener.java:89

  • In globalPropertyDeleted(), the GLOBAL_PROPERTY_LOG_LEVEL case falls through to the unconditional reloadLoggingConfiguration() call, so deleting log.level will still trigger a full logging reconfiguration. This contradicts the class javadoc and the listener’s globalPropertyChanged() behavior (which returns early for log.level). Consider returning immediately for GLOBAL_PROPERTY_LOG_LEVEL so deletion does not reload the whole configuration.
	public void globalPropertyDeleted(String propertyName) {
		switch (propertyName) {
			case OpenmrsConstants.GP_LOG_LAYOUT:
				logLayout = null;
				break;
			case OpenmrsConstants.GP_LOG_LOCATION:
				logLocation = null;
				break;
			case OpenmrsConstants.GLOBAL_PROPERTY_LOG_LEVEL:
				break;
			default:
				return;
		}

		OpenmrsLoggingUtil.reloadLoggingConfiguration();
	}

Comment thread api/src/main/java/org/openmrs/logging/OpenmrsLoggingUtil.java
Comment thread api/src/main/java/org/openmrs/logging/OpenmrsLoggingUtil.java
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

api/src/main/java/org/openmrs/logging/OpenmrsLoggingUtil.java:219

  • The @NonNull annotation on logLevel conflicts with the explicit logLevel == null handling (and corresponding tests that pass null). To avoid misleading nullness tooling, either change the parameter to @Nullable (and keep the guard) or remove the null guard and enforce non-null at call sites.
	public static Level stringToLevel(@NonNull String logLevel, @Nullable String logClass) {
		Level level;
		if (logLevel == null) {
			return Level.WARN;
		}

Comment thread api/src/main/java/org/openmrs/logging/OpenmrsLoggingUtil.java
Comment thread api/src/main/java/org/openmrs/logging/MemoryAppender.java
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

api/src/test/java/org/openmrs/logging/MemoryAppenderTest.java:346

  • In this test, appender1/appender2 are started but never stopped. That can leave background logging components registered and make the test suite order-dependent. Stop both appenders in the finally block to ensure proper cleanup.
			// All events should be preserved
			List<String> logLines = appender2.getLogLines();
			assertThat(logLines, contains("A", "B", "C"));
			assertThat(appender2.getBufferSize(), equalTo(10));
		} finally {
			migrationLogger.removeAppender(appender1);
			migrationLogger.setLevel(null);
			((Logger) LogManager.getRootLogger()).getContext().updateLoggers();
		}

Comment thread api/src/main/java/org/openmrs/logging/MemoryAppender.java
Comment thread api/src/main/java/org/openmrs/logging/OpenmrsLoggingUtil.java
Comment thread api/src/test/java/org/openmrs/logging/MemoryAppenderTest.java Outdated
Comment thread api/src/test/java/org/openmrs/logging/OpenmrsConfigurationFactoryTest.java Outdated
@openmrs openmrs deleted a comment from Copilot AI May 19, 2026
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 19, 2026

Codecov Report

❌ Patch coverage is 63.77953% with 46 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.22%. Comparing base (708c62c) to head (1b973be).

Files with missing lines Patch % Lines
...g/openmrs/logging/OpenmrsConfigurationFactory.java 0.00% 32 Missing ⚠️
.../main/java/org/openmrs/logging/MemoryAppender.java 83.78% 5 Missing and 1 partial ⚠️
...n/java/org/openmrs/logging/OpenmrsLoggingUtil.java 86.48% 1 Missing and 4 partials ⚠️
...ava/org/openmrs/logging/OpenmrsPropertyLookup.java 87.50% 0 Missing and 2 partials ⚠️
...src/main/java/org/openmrs/util/MemoryAppender.java 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #6104      +/-   ##
============================================
+ Coverage     59.04%   59.22%   +0.17%     
- Complexity     9237     9296      +59     
============================================
  Files           693      693              
  Lines         37257    37306      +49     
  Branches       5485     5495      +10     
============================================
+ Hits          21999    22094      +95     
+ Misses        13287    13230      -57     
- Partials       1971     1982      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Also moves GP check to cases where we actually have a session to use
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants