Root Cause Analysis of Missing Logs after Tomcat 7→8 Upgrade
After upgrading from Tomcat 7 to Tomcat 8, the application’s mixed log4j‑1.4 and logback‑1.2.3 dependencies caused the SLF4J binder to be loaded nondeterministically, so Tomcat 8 sometimes selected the Log4j binder without a configuration file, resulting in completely missing log output; removing the conflicting jars or enforcing a deterministic class‑loading order restored logging.
During an optimization of a Java web application, the Tomcat server was upgraded from version 7.0.109 to 8.5.93. While the pre‑release environment worked correctly, the gray‑scale environment showed that new log entries completely disappeared.
Initial investigation steps included checking startup logs for errors, verifying request traffic, ensuring sufficient disk space, and confirming that the logging code was executed. Using Arthas, the watch command verified that the logger instance ( org.slf4j.impl.Log4jLoggerAdapter ) existed, and the trace command showed that the org.apache.log4j.Logger method was called without errors.
The real issue emerged when it was discovered that the application packaged both log4j‑1.4 and logback‑1.2.3 jars. The StaticLoggerBinder class was being loaded from the slf4j‑log4j12‑1.7.7 jar on the problematic machine, causing Log4j to be used despite the absence of Log4j configuration, which resulted in no log output.
Further analysis revealed that Tomcat 7 loads JAR files in alphabetical order, while Tomcat 8 loads them in the order returned by the underlying file system (no sorting). Consequently, Tomcat 7 consistently loaded the Logback binder first, whereas Tomcat 8 could load the Log4j binder depending on the file system's directory listing, leading to nondeterministic behavior.
Key code excerpts:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>Resolution strategies include:
Eliminate the conflicting JARs by excluding one logging implementation via Maven's <exclusions> or the Enforcer plugin.
Force a deterministic class‑loading order by reverting to Tomcat 7 or configuring Tomcat 8 PreResources to prioritize the desired JAR.
Implement a custom ClassLoader or adjust Context.xml to explicitly load the Logback binder first.
By applying these fixes, the missing log issue was resolved, and the application behaved consistently across environments.
DaTaobao Tech
Official account of DaTaobao Technology
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.