Spring boot integration log4j2

Posted by Jbert2 on Tue, 07 Dec 2021 11:04:37 +0100

First, let's talk about why to reference logs:

1. Background introduction

Log4j may be the most commonly used log generation dependent jar package. Of course, there are other log generation jar packages, such as log4j2, and so on. South is System.out.print/println, which is our common console printing method.

Log4j is an open source project of Apache. By using log4j, we can control that the destinations of log information transmission are console, files, GUI components, even socket server, NT event recorder, UNIX Syslog daemon, etc; We can also control the output format of each log; By defining the level of each log information, we can control the log generation process in more detail. The most interesting thing is that these can be flexibly configured through a configuration file without modifying the application code.

2. Knowledge analysis

Log4j has three main components: loggers and Appenders   (output source) and layouts. It can be simply understood here as log category, where the log is to be output and in what form.

Loggers components are divided into five levels in this system: DEBUG, INFO, WARN, ERROR and FATAL.

These five levels are in order. Debug < info < warn < error < fatal are used to specify the importance of this log information respectively.

Log4j has a rule: only log information with a level not lower than the set level is output.

Appenders configures log information output.

Layouts sets the format of log output. Layouts provides four log output styles, such as HTML style, freely specified style, style containing log level and information, and style containing log time, thread, category and other information.

3. Why not use sout h

We saw that the configuration file of log4j has the relevant configuration output to the file, which is the difference between it and south, and it is also the key point why we use log, because when we find the log information, we can check it in the corresponding log file, and the previous log information will not be lost due to factors such as program shutdown. If it is south, the program will be closed, The information is lost. If we want to see the error report, we must run the program again.

4. Expand thinking

We use xml to configure log4j

The log and South information are customized by us. Is only the customized information entered into the. Log file?


reference: https://www.jianshu.com/p/398ba7499db9

Let's start the integration  

Create a maven project in idea

Go directly to 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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>log4j</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>log4j</name>
    <description>log4j project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>

        <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>
<!--        &lt;!&ndash; https://mvnrepository.com/artifact/log4j/log4j &ndash;&gt;-->
<!--        <dependency>-->
<!--            <groupId>log4j</groupId>-->
<!--            <artifactId>log4j</artifactId>-->
<!--            <version>1.2.17</version>-->
<!--        </dependency>-->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

Note that the springboot has its own log, which needs to be removed. Please see

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

This basically completes the dependency injection, so let's write a controller     HelloConreoller

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    final static Logger logger= LoggerFactory.getLogger(HelloController.class);
    @RequestMapping("/hello")
    public Object hello(){

        logger.info("info:hello");
        logger.debug("debug:hello");
        logger.warn("warn:hello");
        logger.error("error:hello error");
        //There are five levels, but these four are commonly used
        return "hello world  my log4j  ";
    }
}

You also need to configure the port in application.yml  
 

spring:
  port: 8001

Then, the last step is to create a new log4j2.xml in the resources directory and copy the code

<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration hinder status,This is used to set log4j2 The internal information output can not be set when it is set to trace You'll see log4j2 Various internal detailed outputs-->
<!--monitorInterval: Log4j It can automatically detect and modify the configuration file and reconfigure itself, and set the interval seconds-->
<configuration monitorInterval="5">
    <!--Log level and prioritization: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

    <!--Variable configuration-->
    <Properties>
        <!-- Format output:%date Indicates the date,%thread Represents the thread name,%-5level: The level is displayed 5 characters wide from the left %msg: Log messages,%n Is a newline character-->
        <!-- %logger{36} express Logger The maximum length of the first name is 36 characters -->
        <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36}  - %msg%n" />
        <!-- Define the path of log storage. Do not configure relative paths -->
        <property name="FILE_PATH" value="D:/logss" />
        <!--entry name-->
        <property name="FILE_NAME" value="log4j2" />
    </Properties>

    <appenders>

        <console name="Console" target="SYSTEM_OUT">
            <!--Format of output log-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <!--Console output only level And above( onMatch),Other direct rejection( onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
        </console>

        <!--The file will print out all the information, this log The program will be emptied automatically every time it is run, and the append Attribute, suitable for temporary testing-->
        <File name="Filelog" fileName="${FILE_PATH}/test.log" append="false">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </File>

        <!-- This will print out all the information info And below, each time the size exceeds size,Then this size Logs of size are automatically saved by year-The folder created in the month is compressed as an archive-->
        <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
            <!--Console output only level And above( onMatch),Other direct rejection( onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval Property is used to specify how often to scroll. The default is 1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy If the property is not set, the default is to start overwriting up to 7 files in the same folder-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- This will print out all the information warn And below, each time the size exceeds size,Then this size Logs of size are automatically saved by year-The folder created in the month is compressed as an archive-->
        <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/${FILE_NAME}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
            <!--Console output only level And above( onMatch),Other direct rejection( onMismatch)-->
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval Property is used to specify how often to scroll. The default is 1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy If the property is not set, the default is to start overwriting up to 7 files in the same folder-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- This will print out all the information error And below, each time the size exceeds size,Then this size Logs of size are automatically saved by year-The folder created in the month is compressed as an archive-->
        <RollingFile name="RollingFileError" fileName="${FILE_PATH}/${FILE_NAME}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
            <!--Console output only level And above( onMatch),Other direct rejection( onMismatch)-->
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval Property is used to specify how often to scroll. The default is 1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy If the property is not set, the default is to start overwriting up to 7 files in the same folder-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

    </appenders>

    <!--Logger The node is used to specify the log format separately, for example, for the log under the specified package class Specify different log levels, etc.-->
    <!--Then define loggers,Only defined logger And introduced appender,appender Will take effect-->
    <loggers>

        <!--Filter out spring and mybatis Some useless DEBUG information-->
        <logger name="org.mybatis" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </logger>
        <!--Monitoring system information-->
        <!--If additivity Set as false,Zezi Logger Only in their own appender Output in, not in the parent Logger of appender Output in.-->
        <Logger name="org.springframework" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>

        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="Filelog"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>
    </loggers>
</configuration>

It is worth mentioning that:

 <property name="FILE_PATH" value="D:/logss" />

#  value is the absolute path where you save the log file

Let's take a look at our project structure

Now that the integration is complete, start the project localhost:8001/hello

 

  See if the log is output locally

 

  In this way, the simple deployment is successful, and the code for deploying to the database will be written later

Topics: log4j Spring Boot log4j2