spring-bootlog4j2

log4j isn't working on my Spring Boot project


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?


Solution

  • 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.

    Project Tree

    ycrmyy-2
    ├── pom.xml
    └── src
        └── main
            ├── java
            │   └── com
            │       └── example
            │           └── ycrmyy
            │               ├── HelloController.java
            │               ├── QueryController.java
            │               ├── ServletInitializer.java
            │               └── YcrmyyApplication.java
            └── resources
                ├── application.properties
                └── log4j2-spring.xml
    

    pom.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.

    YcrmyyApplication.java

    default, nothing special.

    ServletInitializer.java

    default, nothing special.

    QueryController.java

    I use SLF4J as the logger.

    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();
        }
    }
    

    application.properties

    default, nothing special.

    log4j2-spring.xml

    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>
    

    Build and install

    Build

    mvn clean package
    

    Install

    put app.war into apache-tomcat-9.0.107\webapps

    TEST

    curl http://localhost:8080/app/api/HELLOAAAA/upload
    

    Check logs

    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