When working with Tomcat 9 on Ubuntu 18.04, you might encounter a situation where standard output from your web applications mysteriously vanishes. While catalina.date.log exists in the /logs directory, it fails to capture application console output.
Tomcat 9 made significant changes to its logging mechanism. The traditional catalina.out behavior was modified to use java.util.logging by default. Here's what's happening under the hood:
// Default logging.properties location in Tomcat 9
/conf/logging.properties
// Typical handler configuration
handlers = 1catalina.org.apache.juli.AsyncFileHandler, \
2localhost.org.apache.juli.AsyncFileHandler, \
3manager.org.apache.juli.AsyncFileHandler, \
4host-manager.org.apache.juli.AsyncFileHandler, \
java.util.logging.ConsoleHandler
First, verify your logging.properties contains these critical settings:
# Ensure ConsoleHandler is properly configured
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
# Add this to capture stdout/stderr
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = ALL
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = java.util.logging.ConsoleHandler
If logging.properties changes don't work, try redirecting directly in your startup script:
# Modify your catalina.sh or setenv.sh
#!/bin/sh
export CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
exec "$CATALINA_HOME"/bin/catalina.sh run 2>&1 | tee -a "$CATALINA_OUT"
For persistent cases, use JMX to inspect the logging configuration at runtime:
// Connect via JConsole or similar tool
// Navigate to:
MBeans > java.util.logging > Logging > Operations > getLoggerLevel
// Check logger levels for:
org.apache.catalina.core.ContainerBase.[Catalina].[localhost]
After making changes, test with a simple Servlet:
@WebServlet("/TestLogging")
public class TestLogging extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
System.out.println("This should appear in catalina.out");
Logger.getLogger("com.example").info("This tests JUL logging");
}
}
Access this servlet and check both catalina.out and catalina.date.log for the output.
I recently encountered a frustrating issue with Tomcat 9 on Ubuntu 18.04 where the console output from my web applications wasn't appearing in catalina.out, despite having a catalina.date.log file present. Here's how I solved it and what you need to know.
Tomcat 9 made significant changes to its logging mechanism. Unlike previous versions, it no longer automatically redirects System.out and System.err to catalina.out by default. Instead, it uses java.util.logging (JUL) more extensively.
First, verify your logging.properties file (usually in $CATALINA_BASE/conf):
handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler .handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
Add this to your setenv.sh file in $CATALINA_BASE/bin:
#!/bin/sh JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.startup.TldConfig.useTldListeners=true" JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
Ensure your logging.properties has these critical settings:
# Configure the root logger .level = ALL # Configure ConsoleHandler java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
If you prefer Log4j, add this to your pom.xml (if using Maven):
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.17.1</version>
Then create log4j2.xml in your resources folder:
<Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="all"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
Create a simple servlet to test logging:
@WebServlet("/TestLog") public class TestLog extends HttpServlet { private static final Logger logger = Logger.getLogger(TestLog.class.getName()); protected void doGet(HttpServletRequest request, HttpServletResponse response) { logger.info("This is an INFO message"); System.out.println("This is a System.out message"); System.err.println("This is a System.err message"); } }
If you're still not seeing logs:
- Check file permissions in the logs directory
- Verify no other logging framework is interfering
- Restart Tomcat completely after configuration changes
- Check for duplicate logging.properties files