From 268a0bc8f3f042f15d846ff9ec720290bbd09346 Mon Sep 17 00:00:00 2001 From: Will Ezell Date: Tue, 9 Jun 2026 10:20:03 -0400 Subject: [PATCH 1/2] fix(logging): route Tomcat JULI/catalina logs to console + dotcms.log in container (#36075) In the container, only dotCMS application logs (log4j2) reached the container log stream; Tomcat's internal java.util.logging (JULI / catalina) logs went to a separate catalina..log and did not surface. Bridge raw java.util.logging into log4j2 via log4j-jul's Log4jBridgeHandler so everything except access logs is unified to console (stdout) + dotcms.log: - bom/logging/pom.xml: add managed log4j-jul dependency. - dotCMS/pom.xml: declare log4j-jul (provided) and copy its jar into the Tomcat log4j2/lib folder (already on the JVM classpath via setenv.sh). - OVERRIDE tomcat/conf/logging.properties: replace the AsyncFileHandler (catalina..log) and ConsoleHandler with Log4jBridgeHandler. Access logs (AccessLogValve) bypass JULI and remain a separate file by design. Co-Authored-By: Claude Opus 4.8 (1M context) --- bom/logging/pom.xml | 7 +++++ dotCMS/pom.xml | 13 ++++++++++ .../OVERRIDE/tomcat/conf/logging.properties | 26 ++++++++++++------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/bom/logging/pom.xml b/bom/logging/pom.xml index fb2d98a93f0a..a85852d7de85 100644 --- a/bom/logging/pom.xml +++ b/bom/logging/pom.xml @@ -77,6 +77,13 @@ ${log4j.version} runtime + + + org.apache.logging.log4j + log4j-jul + ${log4j.version} + runtime + com.lmax diff --git a/dotCMS/pom.xml b/dotCMS/pom.xml index 17aa12780c8f..4a89e930a65b 100644 --- a/dotCMS/pom.xml +++ b/dotCMS/pom.xml @@ -1433,6 +1433,12 @@ log4j-appserver provided + + + org.apache.logging.log4j + log4j-jul + provided + com.lmax @@ -1697,6 +1703,13 @@ false ${tomcat-log4j-lib-folder} + + org.apache.logging.log4j + log4j-jul + jar + false + ${tomcat-log4j-lib-folder} + org.apache.logging.log4j log4j-slf4j2-impl diff --git a/dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties b/dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties index 77f91c00c3d1..3173d3231b19 100644 --- a/dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties +++ b/dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties @@ -1,14 +1,20 @@ -handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler - -.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler +# Route ALL Tomcat java.util.logging (JULI) records into Log4j2 so they share the +# single dotCMS Log4j2 configuration (Console -> stdout/container logs + dotcms.log). +# This replaces the legacy AsyncFileHandler (separate catalina..log) and the +# stock ConsoleHandler. Tomcat's org.apache.juli.logging facade is already routed to +# Log4j2 by log4j-appserver's TomcatLogger; this bridge additionally captures any code +# that logs directly via java.util.logging. +# +# NOTE: access logs are produced by Tomcat's AccessLogValve (server.xml), which writes +# directly to its own file and does NOT pass through JULI or this bridge -- so access +# logs remain a separate file, by design. +handlers = org.apache.logging.log4j.jul.Log4jBridgeHandler +.handlers = org.apache.logging.log4j.jul.Log4jBridgeHandler ############################################################ -# Handler specific properties. -# Describes specific configuration info for Handlers. +# Log4jBridgeHandler configuration ############################################################ -1catalina.org.apache.juli.AsyncFileHandler.level = INFO -1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs -1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina. -1catalina.org.apache.juli.AsyncFileHandler.maxDays = 2 -1catalina.org.apache.juli.AsyncFileHandler.encoding = UTF-8 \ No newline at end of file +# Mirror the effective Log4j2 levels back onto the JUL loggers so JUL does not +# pre-filter records before they reach Log4j2. +org.apache.logging.log4j.jul.Log4jBridgeHandler.propagateLevels = true From 998cd737241fe707cd643924ce6ef347784537ad Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 9 Jun 2026 16:33:43 +0000 Subject: [PATCH 2/2] fix(bom): change log4j-jul scope from runtime to provided The jar lives on Tomcat's classpath, not the webapp classpath, so provided is the correct scope. Using runtime caused double-loading in modules that inherit the BOM without overriding the scope themselves. https://claude.ai/code/session_0137tNu61fbsugvh9KxeQLkB --- bom/logging/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/logging/pom.xml b/bom/logging/pom.xml index a85852d7de85..27915dc4437f 100644 --- a/bom/logging/pom.xml +++ b/bom/logging/pom.xml @@ -82,7 +82,7 @@ org.apache.logging.log4j log4j-jul ${log4j.version} - runtime + provided