This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_10x in repository https://gitbox.apache.org/repos/asf/solr.git
commit 04327534d6e70f7d046f52ff0f2f2057b9c8ab3d Author: David Smiley <[email protected]> AuthorDate: Sat Feb 14 01:34:12 2026 -0500 SOLR-18107: fix Log4j2Watcher, register parents (#4113) The /admin/info/logging endpoint (or just a test) could yield partial logging hierarchies after log4j was upgraded. It should now be robust. (cherry picked from commit 824bab96a7a4d2843d48aa0c22131f8d731111a9) --- .../unreleased/SOLR-18107-Fix-Log4j2Watcher.yml | 8 ++++ .../apache/solr/logging/log4j2/Log4j2Watcher.java | 50 +++++++++++++--------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/changelog/unreleased/SOLR-18107-Fix-Log4j2Watcher.yml b/changelog/unreleased/SOLR-18107-Fix-Log4j2Watcher.yml new file mode 100644 index 00000000000..c8b32293b40 --- /dev/null +++ b/changelog/unreleased/SOLR-18107-Fix-Log4j2Watcher.yml @@ -0,0 +1,8 @@ +# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc +title: The /admin/info/logging endpoint (or just a tests) could yield partial logging hierarchies after log4j was upgraded. It should now be robust. +type: fixed # added, changed, fixed, deprecated, removed, dependency_update, security, other +authors: + - name: David Smiley +links: + - name: SOLR-18107 + url: https://issues.apache.org/jira/browse/SOLR-18107 diff --git a/solr/core/src/java/org/apache/solr/logging/log4j2/Log4j2Watcher.java b/solr/core/src/java/org/apache/solr/logging/log4j2/Log4j2Watcher.java index 4f2def7c462..ec659763989 100644 --- a/solr/core/src/java/org/apache/solr/logging/log4j2/Log4j2Watcher.java +++ b/solr/core/src/java/org/apache/solr/logging/log4j2/Log4j2Watcher.java @@ -90,16 +90,6 @@ public class Log4j2Watcher extends LogWatcher<LogEvent> { private final boolean isSet; - @Override - public String getLevel() { - return (level != null) ? level : null; - } - - @Override - public String getName() { - return name; - } - @Override public boolean isSet() { return isSet; @@ -201,12 +191,15 @@ public class Log4j2Watcher extends LogWatcher<LogEvent> { continue; } - // NOTE: just because we have an explicit configuration, doesn't mean we have an explitly set - // level - // (Configuration might be for some other property, and level is still inherited) + // NOTE: just because we have an explicit configuration, doesn't mean we have an explicitly + // set level (Configuration might be for some other property, and level is still inherited) map.putIfAbsent( name, new Log4j2Info(name, logger.getLevel(), null != config.getValue().getExplicitLevel())); + + // Also add parent loggers in the hierarchy, as they are relevant for level inheritance + // This ensures parent loggers appear even if not in ctx.getLoggers() + addParentLoggers(name, map, ctx); } // Now add any "in use" loggers (that aren't already explicitly configured) and their parents @@ -220,18 +213,35 @@ public class Log4j2Watcher extends LogWatcher<LogEvent> { // If we didn't already see a LoggerConfig for these loggers, then their level is // not (explicitly) set map.putIfAbsent(name, new Log4j2Info(name, logger.getLevel(), false)); - while (true) { - int dot = name.lastIndexOf('.'); - if (dot < 0) break; - - name = name.substring(0, dot); - map.putIfAbsent(name, new Log4j2Info(name, logger.getLevel(), false)); - } + addParentLoggers(name, map, ctx); } return map.values(); } + /** + * Adds all parent loggers in the hierarchy for the given logger name. + * + * <p>For example, given "org.apache.solr.core.SolrCore", this will add: + * + * <ul> + * <li>"org.apache.solr.core" + * <li>"org.apache.solr" + * <li>"org" + * </ul> + */ + private void addParentLoggers(String loggerName, Map<String, LoggerInfo> map, LoggerContext ctx) { + String parentName = loggerName; + while (true) { + int dot = parentName.lastIndexOf('.'); + if (dot < 0) break; + + parentName = parentName.substring(0, dot); + map.putIfAbsent( + parentName, new Log4j2Info(parentName, ctx.getLogger(parentName).getLevel(), false)); + } + } + @Override public void setThreshold(String level) { Log4j2Appender app = getAppender();
