This is an automated email from the ASF dual-hosted git repository.
dsmiley pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 824bab96a7a SOLR-18107: fix Log4j2Watcher, register parents (#4113)
824bab96a7a is described below
commit 824bab96a7a4d2843d48aa0c22131f8d731111a9
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.
---
.../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 9e266baa5ad..8f0af382e33 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;
@@ -199,12 +189,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
@@ -218,18 +211,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();