I'm using the Apache Log4j log4j2.properties file for my JAVA application. When I run my Java App on Windows it logs to console and file.
But when I run in on my Amazon Linux 2023 (AL23) server I'm not getting any logs to file or console.
---This is my config for Amazon Linux 2023.
- Apache Tomcat version: 11.0.4
- log4j-api-2.24.0.jar
- log4j-core-2.24.0.jar
Java versions: Linux:
- openjdk version "17.0.14" 2025年01月21日 LTS
- openJDK Runtime Environment Corretto-17.0.14.7.1 (build 17.0.14+7-LTS)
- openJDK 64-Bit Server VM Corretto-17.0.14.7.1 (build 17.0.14+7-LTS, mixed mode)
Windows:
- java version "17.0.14.0.1" 2025年01月21日 LTS
- java(TM) SE Runtime Environment (build 17.0.14.0.1+1-LTS-1)
- java HotSpot(TM) 64-Bit Server VM (build 17.0.14.0.1+1-LTS-1, mixed mode, sharing)
--Here's my log4j2.properties file
rootLogger = INFO, STDOUT, LOGFILE
# Log to console
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %level [%c{1}:%L]%m%n
# Log to file location
appender.file.type = File
appender.file.name = LOGFILE
appender.file.fileName= ${basePath}/app.log
appender.file.filePattern= ${basePath}/app_%d{yyyyMMdd}.log
appender.file.layout.type = PatternLayout
appender.file.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %level [%c{1}:%L]%m%n
appender.file.policies.size.type = SizeBasedTriggeringPolicy
appender.file.policies.size.size = 10MB
appender.file.policies.time.type = TimeBasedTriggeringPolicy
appender.file.policies.time.interval = 1
appender.file.policies.time.modulate = true
appender.file.strategy.type = DefaultRolloverStrategy
appender.file.strategy.delete.type = Delete
appender.file.strategy.delete.basePath = ${basePath}
appender.file.strategy.delete.maxDepth = 10
appender.file.strategy.delete.ifLastModified.type = IfLastModified
# Delete all files older than 30 days
appender.file.strategy.delete.ifLastModified.age = 30d
# Log to console for apps
logger.app.name = my.app.MyAppName
logger.app.includeLocation = true
logger.app.appenderRef = STDOUT
logger.app.appenderRef = LOGFILE
logger.app.level = info
logger.app.stdout.console.ref = STDOUT
logger.app.appenderRef.rolling.ref = LOGFILE
# Configure root logger
rootLogger.level = debug
rootLogger.appenderRef.stdout.ref = STDOUT
rootLogger.appenderRef.rolling.ref = LOGFILE
--Here's my JAVA app file structure
-> src/main/java
-> my.app
-> log4j2.properties
--Here's my JAVA controller/servlet file
public class MyAppName extends HttpServlet() {
private static Logger logger = LogManager.getLogger(MyAppName.class);
final int count = 88;
try {
for (int i = 0; i < count; i++) {
logger.info("This is message #{} at INFO level.", i);
}
} catch (Exception: e) {
logger.error("Exception: " + e.getMessage());
}
}
--Here's my JAVA output to console for Linux and Windows - Blank, nothing gets logged to console or file
--Console on Windows and file
[INFO] 2024年05月08日 09:26:15 [MyAppName:23] This is my app info
[ERROR] 2024年05月08日 09:26:15 [MyAppName:24] This is my app error info
[WARN] 2024年05月08日 09:26:15 [MyAppName:25] This is my app warning info
On the Windows console the line count shows the line number in the code. On the Linux console is blank and no log files. What could I be doing wrong? Can someone help? Thank you
UPDATE: Console on Linux and file not showing line number
[INFO] 2024年05月08日 09:26:15 [MyAppName:-1] This is my app info
[ERROR] 2024年05月08日 09:26:15 [MyAppName:-1] This is my app error info
[WARN] 2024年05月08日 09:26:15 [MyAppName:1-] This is my app warning info
1 Answer 1
Project Tree
servlet_log4j2_tomcat11
├── pom.xml
└── src
└── main
├── java
│ └── my
│ └── app
│ └── MyAppName.java
└── resources
└── log4j2.xml
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.jee10</groupId>
<artifactId>servlet-log4j2-tomcat11</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>servlet-log4j2-tomcat11</name>
<description>Jakarta EE 10 Hello Web</description>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.24.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.24.0</version>
</dependency>
</dependencies>
<build>
<finalName>hello</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
MyAppName.java
package my.app;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@WebServlet("/myapp")
public class MyAppName extends HttpServlet {
private static Logger logger = LogManager.getLogger(MyAppName.class);
private static final long serialVersionUID = 1L;
public MyAppName() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//********
final int count = 3;
try {
for (int i = 0; i < count; i++) {
logger.info(">>>>> This is message #{} at INFO level.", i);
}
} catch (Exception e) {
logger.error(">>>>> Exception: " + e.getMessage());
}
//********
response.getWriter().append("Served at: ").append(request.getContextPath());
}
}
log4j2.properties
The answer I provided sets basePath to ${sys:catalina.base}/logs, which will output log files to the tomcat/logs directory.
status = error
name = PropertiesConfig
property.basePath = ${sys:catalina.base}/logs
# Console Appender
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %level [%c{1}:%L] %m%n
# Rolling File Appender
appender.rolling.type = RollingFile
appender.rolling.name = LOGFILE
appender.rolling.fileName = ${basePath}/app.log
appender.rolling.filePattern = ${basePath}/app_%d{yyyyMMdd}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %level [%c{1}:%L] %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size = 10MB
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.delete.type = Delete
appender.rolling.strategy.delete.basePath = ${basePath}
appender.rolling.strategy.delete.maxDepth = 10
appender.rolling.strategy.delete.ifLastModified.type = IfLastModified
appender.rolling.strategy.delete.ifLastModified.age = 30d
# Log to console for apps
logger.myapp.name = my.app.MyAppName
logger.myapp.level = info
logger.myapp.additivity = false
logger.myapp.appenderRef.stdout.ref = STDOUT
logger.myapp.appenderRef.rolling.ref = LOGFILE
# Root logger
rootLogger.level = debug
rootLogger.appenderRef.stdout.ref = STDOUT
rootLogger.appenderRef.rolling.ref = LOGFILE
or
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" name="PropertiesConfig">
<Properties>
<Property name="basePath">${sys:catalina.base}/logs</Property>
</Properties>
<Appenders>
<!-- Console Appender -->
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %level [%c{1}:%L] %m%n"/>
</Console>
<!-- Rolling File Appender -->
<RollingFile name="LOGFILE"
fileName="${basePath}/app.log"
filePattern="${basePath}/app_%d{yyyyMMdd}-%i.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %level [%c{1}:%L] %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="10MB"/>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${basePath}" maxDepth="10">
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="my.app.MyAppName" level="info" additivity="false">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="LOGFILE"/>
</Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="LOGFILE"/>
</Root>
</Loggers>
</Configuration>
Build
mvn clean package
Install JDK
sudo dnf install java-17-amazon-corretto -y
sudo dnf install java-17-amazon-corretto-devel -y
Check version
$ javac -version
javac 17.0.14
$ java -version
openjdk version "17.0.14" 2025年01月21日 LTS
OpenJDK Runtime Environment Corretto-17.0.14.7.1 (build 17.0.14+7-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.14.7.1 (build 17.0.14+7-LTS, mixed mode, sharing)
Install Tomcat
cd /opt
sudo curl -O https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.6/bin/apache-tomcat-11.0.6.tar.gz
sudo tar -xvzf apache-tomcat-11.0.6.tar.gz
install war (if hello.war full path is: ~/hello.war)
sudo mv ~/hello.war /opt/apache-tomcat-11.0.6/webapps/
startup tomcat
sudo /opt/apache-tomcat-11.0.6/bin/startup.sh
find your Amazon Linux 2023 (AL23) server IP Address.
or dns name.
Test
browser open http://your-amazon-server:8080/hello/myapp
output: Served at: /hello
check logs
sudo cat /opt/apache-tomcat-11.0.6/logs/app.log
output
2025年04月23日 21:43:36 INFO [MyAppName:27] >>>>> This is message #0 at INFO level.
2025年04月23日 21:43:36 INFO [MyAppName:27] >>>>> This is message #1 at INFO level.
2025年04月23日 21:43:36 INFO [MyAppName:27] >>>>> This is message #2 at INFO level.
sudo cat /opt/apache-tomcat-11.0.6/logs/catalina.out
output
2025年04月23日 21:43:36 INFO [MyAppName:27] >>>>> This is message #0 at INFO level.
2025年04月23日 21:43:36 INFO [MyAppName:27] >>>>> This is message #1 at INFO level.
2025年04月23日 21:43:36 INFO [MyAppName:27] >>>>> This is message #2 at INFO level.
Java version
$ java -version
openjdk version "17.0.12" 2024年07月16日
OpenJDK Runtime Environment Temurin-17.0.12+7 (build 17.0.12+7)
OpenJDK 64-Bit Server VM Temurin-17.0.12+7 (build 17.0.12+7, mixed mode, sharing)
Tomcat
open https://tomcat.apache.org/download-11.cgi
Binary Distributions/Core / tar.gz
download apache-tomcat-11.0.6.tar.gz
unzip apache-tomcat-11.0.6.tar.gz into your home directory.
I don't know how you installed Tomcat. I downloaded apache-tomcat-11.0.6.tar.gz and decompressed it, and then used ./startup.sh to start tomcat.
After Tomcat is started, the directory contents of hello are:
apache-tomcat-11.0.6/webapps/hello
├── META-INF
...
└── WEB-INF
├── classes
│ ├── log4j2.xml
│ ├── my
│ │ └── app
│ │ └── MyAppName.class
│ ├── my_log4j2.properties
│ └── org_log4j2.properties
└── lib
├── log4j-api-2.24.0.jar
└── log4j-core-2.24.0.jar
sudo dnf search tomcat. So I should manually download tomcat 11 and then unzip it. As for the startup method, it depends on how the OP sets it up. The simplest test is to usesudo /opt/apache-tomcat-11.0.6/bin/startup.shbasePathto${sys:catalina.base}/logs, which will output log files to the tomcat/logs directory.