I'm working on a project using Spring Boot 2.x, Log4j,Tomcat 9 and JDK 8. The application runs exclusively on our company's intranet, not the internet. Because of this, security isn't a major priority, and we're required to use an older SQL Server 2008 R2 database that the company has decided not to upgrade. I'm trying to use Log4j to log the JSON from API requests and responses, but it isn't working.
Here is my pom.xml file
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>ycrmyy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>ycrmyy</name>
<description>ycrmyy</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>1.8</java.version>
<mssql.jdbc.version>10.2.1.jre8</mssql.jdbc.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.parameters>true</maven.compiler.parameters>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope> <!-- key point -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>${mssql.jdbc.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.example.DemoApplication</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
here is my log4j2-spring.xml in the resources folder
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" shutdownHook="disable">
<Properties>
<Property name="logPath">D:/logs/</Property>
<Property name="jsonTpl">classpath:LogstashJsonEventLayoutV1.json</Property>
</Properties>
<Appenders>
<Console name="CONSOLE">
<JsonTemplateLayout eventTemplateUri="${jsonTpl}"/>
</Console>
<RollingFile name="FILE"
fileName="${logPath}/ycrmyy.log"
filePattern="${logPath}/ycrmyy-%d{yyyy-MM-dd}.log.gz">
<JsonTemplateLayout eventTemplateUri="${jsonTpl}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.example.ycrmyy" level="INFO" additivity="false">
<AppenderRef ref="CONSOLE"/>
<AppenderRef ref="FILE"/>
</Logger>
<Logger name="org.springframework" level="WARN"/>
<Root level="ERROR">
<AppenderRef ref="CONSOLE"/>
</Root>
</Loggers>
</Configuration>
here is how I use log4j2 in my controller
@Controller
@RequiredArgsConstructor
@RequestMapping("/query")
public class QueryController {
private final RestTemplate restTemplate;
private static final Logger logger = LogManager.getLogger(QueryController.class);
@GetMapping("/api/{listNo}/upload")
@ResponseBody
public ResponseEntity<?> upload(@PathVariable String listNo) {
logger.info("Initiating upload for listNo: {}", listNo);
..........
........
String uploadRequestJson = convertObjectToJson(payload);
logger.info("Upload Request JSON: {}", uploadRequestJson);
...........
...........
return ResponseEntity.ok().build();
}
}
My program runs correctly, but I'm having trouble with Log4j. The log file isn't being generated at all. Any idea what I might be doing wrong?
Your content doesn't seem to have any major issues. I mainly modified pom.xml, QueryController.java, and log4j2-spring.xml to complete my testing. In addition, I commented out other parts that are unrelated to Log4j2.
ycrmyy-2
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ └── ycrmyy
│ ├── HelloController.java
│ ├── QueryController.java
│ ├── ServletInitializer.java
│ └── YcrmyyApplication.java
└── resources
├── application.properties
└── log4j2-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>ycrmyy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>ycrmyy</name>
<description>ycrmyy</description>
<properties>
<!--
<java.version>1.8</java.version>
-->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
-->
</dependencies>
<build>
<finalName>app</finalName>
<plugins>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
-->
<!-- YOURS
<configuration>
<mainClass>com.example.DemoApplication</mainClass>
</configuration>
-->
</plugin>
</plugins>
</build>
</project>
For parts that are unrelated to Spring Boot and Log4j2, I have commented them out.
I placed the exclusion of spring-boot-starter-logging under spring-boot-starter-web.
default, nothing special.
default, nothing special.
I use SLF4J as the logger.
final static Logger logger = LoggerFactory.getLogger(QueryController.class);
package com.example.ycrmyy;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestController
public class QueryController {
final static Logger logger = LoggerFactory.getLogger(QueryController.class);
//private static final Logger logger = LogManager.getLogger(QueryController.class);
@GetMapping("/api/{listNo}/upload")
@ResponseBody
public ResponseEntity<?> upload(@PathVariable String listNo) {
logger.info("Initiating upload for listNo: {}", listNo);
return ResponseEntity.ok().build();
}
}
default, nothing special.
Since I don't have the LogstashJsonEventLayoutV1.json
file for testing, I switched to using PatternLayout
instead.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" shutdownHook="disable">
<Properties>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - >>> %msg%n</Property>
<Property name="jsonTpl">classpath:LogstashJsonEventLayoutV1.json</Property>
<Property name="logPath">D:/logs/</Property>
<!-- For Tomcat/logs
<Property name="logPath">${sys:catalina.base}/logs</Property>
-->
</Properties>
<Appenders>
<RollingFile name="FILE"
fileName="${logPath}/ycrmyy.log"
filePattern="${logPath}/ycrmyy-%d{yyyy-MM-dd}.log.gz">
<!--
<JsonTemplateLayout eventTemplateUri="${jsonTpl}"/>
-->
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
</RollingFile>
<Console name="CONSOLE">
<!--
<JsonTemplateLayout eventTemplateUri="${jsonTpl}"/>
-->
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
</Appenders>Your content doesn't seem to have any major issues. I mainly modified pom.xml, QueryController.java, and log4j2-spring.xml to complete my testing. In addition, I commented out other parts that are unrelated to Log4j2.
<Loggers>
<Logger name="com.example.ycrmyy" level="INFO" additivity="false">
<AppenderRef ref="CONSOLE"/>
<AppenderRef ref="FILE"/>
</Logger>
<Logger name="org.springframework" level="WARN"/>
<Root level="ERROR">
<AppenderRef ref="CONSOLE"/>
</Root>
</Loggers>
</Configuration>
mvn clean package
put app.war
into apache-tomcat-9.0.107\webapps
curl http://localhost:8080/app/api/HELLOAAAA/upload
logs\ycrmyy.log
2025-07-17 22:49:26 [main] INFO com.example.ycrmyy.ServletInitializer - >>> Starting ServletInitializer v0.0.1-SNAPSHOT using Java 1.8.0_442 on MSEDGEWIN10 with PID 9376 (C:\TOOLS\apache-tomcat-9.0.107\webapps\app\WEB-INF\classes started by IEUser in C:\TOOLS\apache-tomcat-9.0.107\bin)
2025-07-17 22:49:26 [main] INFO com.example.ycrmyy.ServletInitializer - >>> No active profile set, falling back to 1 default profile: "default"
2025-07-17 22:49:28 [main] INFO com.example.ycrmyy.ServletInitializer - >>> Started ServletInitializer in 2.88 seconds (JVM running for 10.753)
2025-07-17 22:50:36 [http-nio-8080-exec-2] INFO com.example.ycrmyy.QueryController - >>> Initiating upload for listNo: HELLOAAAA