Log frame - Yanchi

Keywords: Java log4j Logback slf4j log4j2

All test contents are synchronized to: https://gitee.com/panlsp/logging_framework

Common log frameworks and log facade common log implementations: JUL, log4j, logback, log4j2

Common log facade: JCL, slf4j

Order of occurrence: log4j -- > Jul – > JCL – > slf4j -- > logback -- > log4j2e

1. log4j logging framework

Import dependency

<!-- log4j journal -->
<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>

<!-- junit unit testing  -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

Pay attention to loading initialization information: Basicconfigurator.configure();

Log level description:

Log4j provides 8 levels of log output:

ALL lowest level is used to turn on logging at ALL levels

The TRACE information promoted by the TRACE program. The log level of this TRACE information is very low and will not be used under normal circumstances

DEBUG points out that fine-grained information events are very helpful for debugging applications. They mainly cooperate with development and print some important operation information during the development process

The coarse-grained level of the INFO message

WARN indicates a warning. Hidden errors that may occur during the operation of the program. Note that some information is not an error, but the purpose of this level of output is to prompt the programmer

ERROR is the ERROR message of the system. The ERROR does not affect the operation of the system. Generally, if you do not want to output too many logs, you can use this level

FATAL indicates a serious error. It is a serious error that the system cannot continue to run once it occurs. If this level of error occurs, it indicates that the program can stop running

OFF the highest level, the user turns OFF all logging

1.1 introduction case

public class MyTest {
    static Logger logger = Logger.getLogger(MyTest.class);

    // Use the default log (console log, no configuration file required)
    @Test
    public void test1() {
        // Load initialization information
        BasicConfigurator.configure();
        
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
        logger.fatal("fatal information");
    }
}

Log default level: debug

1.2. Get started quickly

Configuration file: log4j.properties (to be placed in the resources folder)

#Configure root node logger log4j. Rootlogger = log level, {custom name 1, custom name 2}
log4j.rootLogger=trace,console,file

#Configure. appender output mode to output to the console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#Configure the format of output to the console
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=[%-6p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

#Configure appender output mode to output to file
log4j.appender.file=org.apache.log4j.FileAppender
#Configure the format of output to a file
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=[%-6p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
#The first file is our own named appenderName, and the second file is the attribute used to specify the file location
log4j.appender.file.file=D://test//log4j.log
#Configure output character encoding
log4j.appender.file.encoding=UTF-8

Test:

// 2. Get started quickly
@Test
public void test2() {
    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
    logger.fatal("fatal information");
}

Generated log files:

1.3. Split logs according to file size

When there are too many logs, the new log will overwrite the old log

Profile configuration:

#Configure root node logger log4j. Rootlogger = log level, {custom name 1, custom name 2}
log4j.rootLogger=trace,rollingFile

#Configure appender output mode to output to file (split by file size)
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
#Configure the format of output to a file
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.conversionPattern=[%-6p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
#The first file is our own named appenderName, and the second file is the attribute used to specify the file location
log4j.appender.rollingFile.file=D://test//log4j.log
#Configure output character encoding
log4j.appender.rollingFile.encoding=UTF-8
#Maximum size of configuration file (default: 10485760L) 10M
log4j.appender.rollingFile.MaxFileSize=10M
#Configure the maximum number of log files (default: 1)
log4j.appender.rollingFile.MaxBackupIndex=5

Test:

// 3. Split logs by file size
@Test
public void test3() {

    for (int i = 0; i < 100000; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
        logger.fatal("fatal information");
    }
}

Generated log files:

1.4 log splitting by time

Log redundancy requires manual cleaning or shell script writing

Profile configuration:

#Configure root node logger log4j. Rootlogger = log level, {custom name 1, custom name 2}
log4j.rootLogger=trace,console,dailyRollingFile

#Configure. appender output mode to output to the console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#Configure the format of output to the console
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=[%-6p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

#Configure the appender output mode to output to a file (split the file time)
log4j.appender.dailyRollingFile=org.apache.log4j.DailyRollingFileAppender
#Configure the format of output to a file
log4j.appender.dailyRollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyRollingFile.layout.conversionPattern=[%-6p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
#The first file is our own named appenderName, and the second file is the attribute used to specify the file location
log4j.appender.dailyRollingFile.file=D://test//log4j.log
#Configure output character encoding
log4j.appender.dailyRollingFile.encoding=UTF-8
#The split time of the configuration file (default value: '. Yyyy MM DD) scrolls at midnight every day. Easy to test, the following is one minute
log4j.appender.dailyRollingFile.DatePattern='.'yyyy-MM-dd-HH-mm

Test:

// 3. Split logs by time
@Test
public void test4() throws InterruptedException {

    for (int i = 0; i < 3; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
        logger.fatal("fatal information");
        // Sleep for one minute
        Thread.sleep(1000 * 60);
    }
}

Generated log files:

1.5. Log persistence to database table

Driver for importing mysql:

<!-- mysql drive -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.49</version>
</dependency>

Data table structure (tb(u log4j):

CREATE TABLE `tb_log4j` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL COMMENT 'entry name',
  `createTime` varchar(255) DEFAULT NULL COMMENT 'Creation time',
  `level` varchar(255) DEFAULT NULL COMMENT 'log level',
  `category` varchar(255) DEFAULT NULL COMMENT 'Full path of class',
  `fileName` varchar(255) DEFAULT NULL COMMENT 'File name',
  `message` varchar(255) DEFAULT NULL COMMENT 'Log message',
  PRIMARY KEY (`id`)
)

Profile:

#Configure root node logger log4j. Rootlogger = log level, {custom name 1, custom name 2}
log4j.rootLogger=trace,console,logDB

#Configure the appender output mode to output to the database table
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
#Configure the format of output to a file
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
#Configuration database connection
log4j.appender.logDB.URL=jdbc:mysql://localhost:3306/log4j?useSSL=false&useUnicode=true&characterEncoding=UTF-8
log4j.appender.logDB.User=root
log4j.appender.logDB.Password=root
log4j.appender.logDB.Sql=insert into tb_log4j(name,createTime,level,category,fileName,message) values ('log4j_project','%d{yyyy-MM-dd HH:mm:ss:SSS}','%p','%c','%F','%m')

Test:

// 3. Log persistence to database tables
@Test
public void test5() {
    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
    logger.fatal("fatal information");
}

Log information:

1.6. Configure user-defined logger

Profile:

#Configure root node logger log4j. Rootlogger = log level, {custom name 1, custom name 2}
log4j.rootLogger=trace,file

#Configure custom logger (log print level)
log4j.logger.com.yanchi=info,console

#Configure. appender output mode to output to the console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#Configure the format of output to the console
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=[%-6p]%r %c %t %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

#Configure appender output mode to output to file
log4j.appender.file=org.apache.log4j.FileAppender
#Configure the format of output to a file
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=[%-6p]%r %c %t %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
#The first file is our own named appenderName, and the second file is the attribute used to specify the file location
log4j.appender.file.file=D://test//log4j.log
#Configure output character encoding
log4j.appender.file.encoding=UTF-8

Test:

// 4. Configure custom logger
@Test
public void test6() {
    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
    logger.fatal("fatal information");
}

Log information:

1.7. Full version configuration (modified as needed)

#Configure root node logger log4j. Rootlogger = log level, {custom name 1, custom name 2}
log4j.rootLogger=trace,file

#Configure custom logger
log4j.logger.com.yanchi=info,console

#Configure. appender output mode to output to the console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#Configure the format of output to the console
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=[%-6p]%r %c %t %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

#Configure appender output mode to output to file
log4j.appender.file=org.apache.log4j.FileAppender
#Configure the format of output to a file
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=[%-6p]%r %c %t %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
#The first file is our own named appenderName, and the second file is the attribute used to specify the file location
log4j.appender.file.file=D://test//log4j.log
#Configure output character encoding
log4j.appender.file.encoding=UTF-8

#Configure appender output mode to output to file (split by file size)
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
#Configure the format of output to a file
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.conversionPattern=[%-6p]%r %c %t %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
#The first file is our own named appenderName, and the second file is the attribute used to specify the file location
log4j.appender.rollingFile.file=D://test//log4j.log
#Configure output character encoding
log4j.appender.rollingFile.encoding=UTF-8
#Maximum size of configuration file (default: 10485760L) 10M
log4j.appender.rollingFile.MaxFileSize=10M
#Configure the maximum number of log files (default: 1)
log4j.appender.rollingFile.MaxBackupIndex=5

#Configure the appender output mode to output to a file (split the file time)
log4j.appender.dailyRollingFile=org.apache.log4j.DailyRollingFileAppender
#Configure the format of output to a file
log4j.appender.dailyRollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyRollingFile.layout.conversionPattern=[%-6p]%r %c %t %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
#The first file is our own named appenderName, and the second file is the attribute used to specify the file location
log4j.appender.dailyRollingFile.file=D://test//log4j.log
#Configure output character encoding
log4j.appender.dailyRollingFile.encoding=UTF-8
#The split time of the configuration file (default value: '. Yyyy MM DD) scrolls at midnight every day. Easy to test, the following is one minute
log4j.appender.dailyRollingFile.DatePattern='.'yyyy-MM-dd-HH-mm

#Configure the appender output mode to output to the database table
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
#Configure the format of output to a file
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
#Configuration database connection
log4j.appender.logDB.URL=jdbc:mysql://localhost:3306/log4j?useSSL=false&useUnicode=true&characterEncoding=UTF-8
log4j.appender.logDB.User=root
log4j.appender.logDB.Password=root
log4j.appender.logDB.Sql=insert into tb_log4j(name,createTime,level,category,fileName,message) values ('log4j_project','%d{yyyy-MM-dd HH:mm:ss:SSS}','%p','%c','%F','%m')

2. JCL log facade

Introduction:

The full name is Jakarta common logging, which is a general logging API provided by Apache

Users can freely choose the third-party log component as the specific implementation, such as log4j or jul of jdk. Common logging will automatically find the real log library during program running through the dynamic search mechanism.

Of course, there is a simple implementation of Simple logger in common logging, but the function is very weak. Therefore, common logging is usually used in conjunction with log4j and other logging frameworks.

The advantage of using it is that the code depends on the API of common logging rather than log4j, which avoids direct coupling with the specific logging API. If necessary, the third-party library of the logging implementation can be changed.

JCL has two basic abstract classes:

Log: logger

LogFactory: Log factory (responsible for creating Log instances)

Import dependency

<!-- JUL rely on -->
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

<!-- junit unit testing  -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

2.1 introduction cases

Test:

@Test
public void test1(){

    /*
    We have not imported a third-party logging framework, such as log4j
    By default, the JUL logging framework is used for logging operations

    JCL Use principle:
    	If log4j is available, log4j is preferred
    	If there is no third-party logging framework, we use JUL

     */
    Log log = LogFactory.getLog(JCLTest.class);
    log.info("info information");

}

Log information:

2.2. Integration Log4j

Import dependency:

<!-- log4j journal -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

Write profile:

#Configure root node logger log4j. Rootlogger = log level, {custom name 1, custom name 2}
log4j.rootLogger=trace,console

#Configure. appender output mode to output to the console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#Configure the format of output to the console
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=[%-6p]%r %c %t %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

Test:

@Test
public void test2(){

    /*
        Import log4j dependency and continue to test the original program

        Summary:
            In our last case, we used UL, but after integrating the log4j environment, we used log4j again
            Through the test observation, although the logging framework has changed, the code has not changed at all
        Benefits of log facade Technology:
            Facade technology is interface oriented development, which no longer depends on specific implementation classes and reduces code coupling
            The logging framework can be flexibly switched according to actual needs
            Unified API for developers to learn and use
            Unified configuration management facilitates the maintenance of project logs
     */
    Log log = LogFactory.getLog(JCLTest.class);
    log.info("info information");

}

Log information:

3. SLF4J log facade

Simple Logging Facade, corresponding to Simple Logging Facade in English, is a standard interface for accessing logs, including specific implementations of slf4j, log4j, jdk logging api and Apache common log.

There are two main functions: binding of log framework and bridging of log framework

Import dependency:

<!-- junit unit testing  -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

<!-- slf4j Core dependency -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version>
</dependency>

<!-- slf4j Self contained simple log implementation -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.32</version>
</dependency>

3.1 introduction cases

Test:

@Test
public void test1(){
    /*

    Introductory case
        SLF4J Level division of logs
        trace,debug,info,warn,error Five levels
        trace:Log trace information
        debug:Log details
        info:The default print level of key information in the log
        warn:Log warning information
        error:Log error message
        On the basis of framework integration without any other log implementation
        slf4j The built-in framework slf4j simple is used
        slf4j-simple It must also be imported as a separate dependency

     */
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);

    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");

}

Log information:

3.2. Dynamic log printing

Test:

// Implementation of dynamic log printing
@Test
public void test2(){
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);

    String name = "yanchi";
    int age = 18;

    logger.info("full name:{},Age:{}",name,age);
}

Log information:

3.3. Print abnormal information

Test:

// Print exception information
@Test
public void test3(){
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);

    try {
        Class.forName("aaa");
    } catch (Exception e) {
        logger.error("Exception information:",e);
    }
}

Log information:

3.4. Integrated logback

Dependency:

        <!-- logback rely on -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.6</version>
        </dependency>

        <!-- slf4j Self contained simple log implementation -->
<!--        <dependency>-->
<!--            <groupId>org.slf4j</groupId>-->
<!--            <artifactId>slf4j-simple</artifactId>-->
<!--            <version>1.7.32</version>-->
<!--        </dependency>-->

Test:

/*
    Remove slf4j's own simple log implementation
    Integration logback log
 */
@Test
public void test4(){
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
    try {
        Class.forName("bbb");
    } catch (Exception e) {
        logger.error("Abnormal information( logback Version:",e);
    }
}

Log information:

3.5 integration log4j

Dependency:

<!-- log4j Adapter dependency -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.32</version>
</dependency>

<!-- log4j journal -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

Write profile:

#Configure root node logger log4j. Rootlogger = log level, {custom name 1, custom name 2}
log4j.rootLogger=trace,console

#Configure. appender output mode to output to the console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#Configure the format of output to the console
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=[%-6p]%r %c %t %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

Test:

/*
Remove slf4j's own simple log implementation and logback log implementation
 Integration log4j log
 */
@Test
public void test5(){
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
    try {
        Class.forName("ccc");
    } catch (Exception e) {
        logger.error("Abnormal information( log4j Version:",e);
    }
}

Log information:

3.6. Integrated JUL

Dependency:

<!-- JUL Adapter dependency-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-jdk14</artifactId>
    <version>1.7.32</version>
</dependency>

Test:

/*
   Remove all third-party log implementations
   Integrated JDK comes with JUL log
*/
@Test
public void test6() {
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);

    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
}

Log information:

3.7 use of bridge

Note: bridges and adapters cannot be imported at the same time

This test: the default log4j log is switched to logback log (other bridging problems are similar)

Dependency:

Comment out the default log4j and import the log4j bridging dependency

        <!-- log4j journal -->
<!--        <dependency>-->
<!--            <groupId>log4j</groupId>-->
<!--            <artifactId>log4j</artifactId>-->
<!--            <version>1.2.17</version>-->
<!--        </dependency>-->

<!-- slf4j Core dependency -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version>
</dependency>

<!-- log4j bridging -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>1.7.32</version>
</dependency>

<!-- logback rely on -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

Test:

package com.yanchi;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.junit.Test;

public class SLF4JBridge {
    @Test
    public void test(){

        Logger logger = LogManager.getLogger(SLF4JBridge.class);

        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");

    }

}

Log information:

4. logback log

4.1 introduction cases

Dependency:

<!-- junit unit testing  -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

<!-- logback journal -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

<!-- slf4j Core dependency -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version>
</dependency>

Test:

// 1. Introductory case
@Test
public void test1() {
    
    Logger logger = LoggerFactory.getLogger(MyTest.class);
    
    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
}

Log information:

4.2 introduction to configuration

Configuration file configuration: logback.xml (it needs to be placed in the resources folder)

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <!-- <property/> General properties of the configuration file for easy reference -->
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %c %M %L %thread %m%n"/>

    <!-- Configuration Console  appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">

        <!--
            Indicates the configuration of the log output destination
            Default: System.out Indicates that the log is output in the default font
            set up: System.err Indicates that the log is output in red font
        -->
        <target>
            System.err
        </target>

        <!--
            Configure log output format
            How to manually configure the format
            You can directly import the above general attributes
        -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>

    </appender>

    <!--
        Loggers
        to configure root logger
        level: Configure log level
    -->
    <root level="ALL">
        <!-- introduce appender -->
        <appender-ref ref="consoleAppender"/>
    </root>

</configuration>

Test:

// 2. Configuration case
@Test
public void test2() {

    Logger logger = LoggerFactory.getLogger(LogbackTest.class);

    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
}

Log information:

4.3 log file output

Profile:

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <!-- <property/> General properties of the configuration file for easy reference -->
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %c %M %L %thread %m%n"/>
    <!-- Configuration file output path -->
    <property name="logDir" value="D://test"/>

    <!-- configuration file appender -->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <!-- Import file location -->
        <file>${logDir}/logback.log</file>

        <!-- Format output -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!-- Configuration Console  appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">

        <!--
            Indicates the configuration of the log output destination
            Default: System.out Indicates that the log is output in the default font
            set up: System.err Indicates that the log is output in red font
        -->
        <target>
            System.err
        </target>

        <!--
            Configure log output format
            How to manually configure the format
            You can directly import the above general attributes
        -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>

    </appender>

    <!--
        Loggers
        to configure root logger
        level: Configure log level
    -->
    <root level="ALL">
        <!-- introduce appender -->
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="fileAppender"/>
    </root>

</configuration>

Test:

// 3. Log file output
@Test
public void test3() {

    Logger logger = LoggerFactory.getLogger(LogbackTest.class);

    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
}

Log information:

4.4 log splitting

Configuring files for split archives

Profile:

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <!-- <property/> General properties of the configuration file for easy reference -->
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %c %M %L %thread %m%n"/>
    <!-- Configuration file output path -->
    <property name="logDir" value="D://test"/>

    <!-- configuration file appender -->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <!-- Import file location -->
        <file>${logDir}/logback.log</file>

        <!-- Format output -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!-- Configuring files for split archives appender -->
    <appender name="rollAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- Import file location -->
        <file>${logDir}/roll_logback.log</file>

        <!-- Format output -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>

        <!-- Specify split rules -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">

            <!-- Declare file names in time and compression format gz -->
            <fileNamePattern>${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>

            <!-- Split by file size-->
            <maxFileSize>1kb</maxFileSize>

        </rollingPolicy>
    </appender>

    <!-- Configuration Console  appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">

        <!--
            Indicates the configuration of the log output destination
            Default: System.out Indicates that the log is output in the default font
            set up: System.err Indicates that the log is output in red font
        -->
        <target>
            System.err
        </target>

        <!--
            Configure log output format
            How to manually configure the format
            You can directly import the above general attributes
        -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>

    </appender>

    <!--
        Loggers
        to configure root logger
        level: Configure log level
    -->
    <root level="ALL">
        <!-- introduce appender -->
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="rollAppender"/>
    </root>

</configuration>

Test:

// 4. Configuring files for split archives
@Test
public void test4() {

    Logger logger = LoggerFactory.getLogger(LogbackTest.class);

    for (int i = 0; i < 10; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }

}

Log information:

4.4 asynchronous log

Configuration information:

    <!-- Configuration Console  appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">

        <!--
            Indicates the configuration of the log output destination
            Default: System.out Indicates that the log is output in the default font
            set up: System.err Indicates that the log is output in red font
        -->
        <target>
            System.err
        </target>

        <!--
            Configure log output format
            How to manually configure the format
            You can directly import the above general attributes
        -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>

    </appender>

    <!-- Configure asynchronous appender -->
    <appender name="asyncAppender" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="consoleAppender"/>
    </appender>

    <!--
        Loggers
        to configure root logger
        level: Configure log level
    -->
    <root level="ALL">
        <!-- introduce appender -->
<!--        <appender-ref ref="consoleAppender"/>-->
<!--        <appender-ref ref="rollAppender"/>-->
        <appender-ref ref="asyncAppender"/>
    </root>

Test:

// 5. Asynchronous log
@Test
public void test5() {

    Logger logger = LoggerFactory.getLogger(LogbackTest.class);

    for (int i = 0; i < 50; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }

    System.out.println("1--------------------");
    System.out.println("2--------------------");
    System.out.println("3--------------------");
    System.out.println("4--------------------");
    System.out.println("5--------------------");

}

Log information:

5. log4j2 log

Default: error level print log

5.1 introduction cases

Dependency:

<!-- log4j2 Log facade dependency -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.14.1</version>
</dependency>

<!-- log4j2 Log core dependency -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.1</version>
</dependency>

<!-- junit unit testing  -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

Test:

// 1. Use the default log (console log, no configuration file required)
@Test
public void test1() {

    Logger logger = LogManager.getLogger(Log4j2Test.class);

    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
    logger.fatal("fatal information");
}

Log information:

5.2 introduction to configuration

Configuration file configuration: log4j2.xml (it needs to be placed in the resources folder)

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">
    <!-- to configure Appender -->
    <Appenders>
        <Console name="consoleAppender" target="SYSTEM_ERR">

        </Console>
    </Appenders>
    
    <!--to configure logger-->
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="consoleAppender"></AppenderRef>
        </Root>
    </Loggers>
</Configuration>

Test:

// 2. Log using profile
@Test
public void test2() {

    Logger logger = LogManager.getLogger(Log4j2Test.class);

    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");
    logger.fatal("fatal information");
}

Log information:

5.3 integration slf4j log facade

Dependency:

<dependencies>

    <!-- slf4j Log facade dependency -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.32</version>
    </dependency>

    <!-- log4j-slf4j Adapter -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.14.1</version>
    </dependency>

    <!-- log4j2 Log facade dependency -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.14.1</version>
    </dependency>

    <!-- log4j2 Log core dependency -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.14.1</version>
    </dependency>

    <!-- junit unit testing  -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>

</dependencies>

Test:

package com.yanchi;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Slf4jToLog4j2 {

    // Integration slf4j log facade
    @Test
    public void test3(){
        Logger logger = LoggerFactory.getLogger(Slf4jToLog4j2.class);

        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");

    }

}

Log information:

5.4 log file output

Profile:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">

    <!--Global configuration information-->
    <Properties>
        <Property name="logDir">D://test</Property>
    </Properties>

    <!-- to configure Appender -->
    <Appenders>
        <!--console output -->
        <Console name="consoleAppender" target="SYSTEM_ERR">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </Console>

        <!--File output-->
        <File name="fileAppender" fileName="${logDir}//log4j2.log">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </File>

    </Appenders>
    
    <!--to configure logger-->
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="consoleAppender"/>
            <AppenderRef ref="fileAppender"/>
        </Root>
    </Loggers>
</Configuration>

Test:

// 4. Log file output
@Test
public void test4(){
    Logger logger = LoggerFactory.getLogger(Slf4jToLog4j2.class);

    logger.trace("trace information");
    logger.debug("debug information");
    logger.info("info information");
    logger.warn("warn information");
    logger.error("error information");

}

Log information:

5.5. Log splitting

Profile:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>

    <!--Global configuration information-->
    <Properties>
        <Property name="logDir">D://test</Property>
    </Properties>

    <!-- to configure Appender -->
    <Appenders>
        <!--console output -->
        <Console name="consoleAppender" target="SYSTEM_ERR">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </Console>

        <!--File output-->
        <File name="fileAppender" fileName="${logDir}//log4j2.log">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </File>

        <!--
            Split the log file according to the specified rules

            fileName: The name of the log file
            filePattern: Naming rules of log files after splitting
                $${date:yyyy-MM-dd}: Create a folder based on the date of the day

            rol_log-%d{yyyy-MM-dd}-%i.log
                Naming rules for files:%i Indicates the serial number, starting from 0, so that the name of each document will not be repeated
        -->
        <RollingFile name="rollingFile" fileName="${logDir}/rol_log.log" filePattern="${logDir}/$${date:yyyy-MM-dd}/rol_log-%d{yyyy-MM-dd}-%i.log">
            <!--Log message format-->
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>

            <Policies>

                <!--When the system starts, the split rule is triggered to generate a log file-->
                <OnStartupTriggeringPolicy/>

                <!--Split by file size-->
                <SizeBasedTriggeringPolicy size="10kb"/>

                <!--Splitting by time node is a rule filePattern-->
                <TimeBasedTriggeringPolicy/>

            </Policies>

            <!--If the number of files in the same directory exceeds the set value, it will be overwritten according to the time, and the new will overwrite the old rule-->
            <DefaultRolloverStrategy max="30"/>
        </RollingFile>

    </Appenders>
    
    <!--to configure logger-->
    <Loggers>
        <Root level="trace">
<!--            <AppenderRef ref="consoleAppender"/>-->
<!--            <AppenderRef ref="fileAppender"/>-->
            <AppenderRef ref="rollingFile"/>
        </Root>
    </Loggers>
</Configuration>

Test:

// 5. Log split
@Test
public void test5(){
    Logger logger = LoggerFactory.getLogger(Slf4jToLog4j2.class);

    for (int i = 0; i < 2000; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }
}

Log information:

5.6. * asynchronous log

5.6.1. Use AsyncAppender (not recommended)

Add dependency:

<!-- Asynchronous log dependency -->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.4.4</version>
</dependency>

Profile:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>

    <!--Global configuration information-->
    <Properties>
        <Property name="logDir">D://test</Property>
    </Properties>

    <!-- to configure Appender -->
    <Appenders>
        <!--console output -->
        <Console name="consoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </Console>

        <!--File output-->
        <File name="fileAppender" fileName="${logDir}//log4j2.log">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </File>

        <!--
            Split the log file according to the specified rules

            fileName: The name of the log file
            filePattern: Naming rules of log files after splitting
                $${date:yyyy-MM-dd}: Create a folder based on the date of the day

            rol_log-%d{yyyy-MM-dd}-%i.log
                Naming rules for files:%i Indicates the serial number, starting from 0, so that the name of each document will not be repeated
        -->
        <RollingFile name="rollingFile" fileName="${logDir}/rol_log.log" filePattern="${logDir}/$${date:yyyy-MM-dd}/rol_log-%d{yyyy-MM-dd}-%i.log">
            <!--Log message format-->
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>

            <Policies>

                <!--When the system starts, the split rule is triggered to generate a log file-->
                <OnStartupTriggeringPolicy/>

                <!--Split by file size-->
                <SizeBasedTriggeringPolicy size="10kb"/>

                <!--Splitting by time node is a rule filePattern-->
                <TimeBasedTriggeringPolicy/>

            </Policies>

            <!--If the number of files in the same directory exceeds the set value, it will be overwritten according to the time, and the new will overwrite the old rule-->
            <DefaultRolloverStrategy max="30"/>
        </RollingFile>

        <!--5.6.1,Asynchronous log configuration-->
        <Async name="asyncAppender">
            <AppenderRef ref="consoleAppender"/>
        </Async>

    </Appenders>
    
    <!--to configure logger-->
    <Loggers>
        <Root level="trace">
            <!--5.6.1,Asynchronous log configuration-->
            <AppenderRef ref="asyncAppender"/>
<!--            <AppenderRef ref="consoleAppender"/>-->
<!--            <AppenderRef ref="fileAppender"/>-->
<!--            <AppenderRef ref="rollingFile"/>-->
        </Root>
    </Loggers>
</Configuration>

Test:

// 6.1 asynchronous log
@Test
public void test6_1(){
    Logger logger = LoggerFactory.getLogger(Slf4jToLog4j2.class);

    // Log section
    for (int i = 0; i < 50; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }

    // Business logic part
    for (int i = 0; i < 10; i++) {
        System.out.println("----------------------------------------");
    }
}

Log information:

5.6.2. Using asyncloger (recommended)

5.6.2.1. Global asynchrony

All logs are asynchronous logging

You need to add a properties property configuration file under the classpath resources

The file name should be log4j2.component.properties

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

Profile:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>

    <!--Global configuration information-->
    <Properties>
        <Property name="logDir">D://test</Property>
    </Properties>

    <!-- to configure Appender -->
    <Appenders>
        <!--console output -->
        <Console name="consoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </Console>

        <!--File output-->
        <File name="fileAppender" fileName="${logDir}//log4j2.log">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </File>

        <!--
            Split the log file according to the specified rules

            fileName: The name of the log file
            filePattern: Naming rules of log files after splitting
                $${date:yyyy-MM-dd}: Create a folder based on the date of the day

            rol_log-%d{yyyy-MM-dd}-%i.log
                Naming rules for files:%i Indicates the serial number, starting from 0, so that the name of each document will not be repeated
        -->
        <RollingFile name="rollingFile" fileName="${logDir}/rol_log.log" filePattern="${logDir}/$${date:yyyy-MM-dd}/rol_log-%d{yyyy-MM-dd}-%i.log">
            <!--Log message format-->
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>

            <Policies>

                <!--When the system starts, the split rule is triggered to generate a log file-->
                <OnStartupTriggeringPolicy/>

                <!--Split by file size-->
                <SizeBasedTriggeringPolicy size="10kb"/>

                <!--Splitting by time node is a rule filePattern-->
                <TimeBasedTriggeringPolicy/>

            </Policies>

            <!--If the number of files in the same directory exceeds the set value, it will be overwritten according to the time, and the new will overwrite the old rule-->
            <DefaultRolloverStrategy max="30"/>
        </RollingFile>

        <!--5.6.1,Asynchronous log configuration-->
<!--        <Async name="asyncAppender">-->
<!--            <AppenderRef ref="consoleAppender"/>-->
<!--        </Async>-->

    </Appenders>
    
    <!--to configure logger-->
    <Loggers>
        <Root level="trace">
            <!--5.6.1,Asynchronous log configuration-->
<!--            <AppenderRef ref="asyncAppender"/>-->
            <!--5.6.2.1,Global asynchrony-->
            <AppenderRef ref="consoleAppender"/>
<!--            <AppenderRef ref="fileAppender"/>-->
<!--            <AppenderRef ref="rollingFile"/>-->
        </Root>
    </Loggers>
</Configuration>

Test:

// 6.2.1 global asynchrony
@Test
public void test6_2_1(){
    Logger logger = LoggerFactory.getLogger(Slf4jToLog4j2.class);

    // Log section
    for (int i = 0; i < 50; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }

    // Business logic part
    for (int i = 0; i < 10; i++) {
        System.out.println("----------------------------------------");
    }
}

Log information:

5.6.2.2 hybrid asynchronous

Synchronous logs and asynchronous logs can be used in applications at the same time, which is more flexible

Note: Global asynchrony needs to be commented out

Profile:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>

    <!--Global configuration information-->
    <Properties>
        <Property name="logDir">D://test</Property>
    </Properties>

    <!-- to configure Appender -->
    <Appenders>
        <!--console output -->
        <Console name="consoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </Console>

        <!--File output-->
        <File name="fileAppender" fileName="${logDir}//log4j2.log">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </File>

        <!--
            Split the log file according to the specified rules

            fileName: The name of the log file
            filePattern: Naming rules of log files after splitting
                $${date:yyyy-MM-dd}: Create a folder based on the date of the day

            rol_log-%d{yyyy-MM-dd}-%i.log
                Naming rules for files:%i Indicates the serial number, starting from 0, so that the name of each document will not be repeated
        -->
        <RollingFile name="rollingFile" fileName="${logDir}/rol_log.log" filePattern="${logDir}/$${date:yyyy-MM-dd}/rol_log-%d{yyyy-MM-dd}-%i.log">
            <!--Log message format-->
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>

            <Policies>

                <!--When the system starts, the split rule is triggered to generate a log file-->
                <OnStartupTriggeringPolicy/>

                <!--Split by file size-->
                <SizeBasedTriggeringPolicy size="10kb"/>

                <!--Splitting by time node is a rule filePattern-->
                <TimeBasedTriggeringPolicy/>

            </Policies>

            <!--If the number of files in the same directory exceeds the set value, it will be overwritten according to the time, and the new will overwrite the old rule-->
            <DefaultRolloverStrategy max="30"/>
        </RollingFile>

        <!--5.6.1,Asynchronous log configuration-->
<!--        <Async name="asyncAppender">-->
<!--            <AppenderRef ref="consoleAppender"/>-->
<!--        </Async>-->

    </Appenders>
    
    <!--to configure logger-->
    <Loggers>

        <!--
            5.6.2.2 Hybrid asynchronous
                custom logger,Let customize logger Is asynchronous logger

                includeLocation="false"
                It means to remove the line number information in the log record. This line number information greatly affects the efficiency of the log record (this line number is not added in production))
                In severe cases, the logging efficiency may be lower than that of synchronous logging
                additivity="false"
                Indicates no inheritance rootLogger

        -->
        <AsyncLogger name="com.yanchi" level="trace"
                     includeLocation="false" additivity="false">
            <!--Set the output of the console to consoleAppender,Set to asynchronous printing-->
            <AppenderRef ref="consoleAppender"/>

        </AsyncLogger>

        <Root level="trace">
            <!--5.6.1,Asynchronous log configuration-->
<!--            <AppenderRef ref="asyncAppender"/>-->
            <!--5.6.2.2,Hybrid asynchronous-->
            <AppenderRef ref="consoleAppender"/>
<!--            <AppenderRef ref="fileAppender"/>-->
<!--            <AppenderRef ref="rollingFile"/>-->
        </Root>
    </Loggers>
</Configuration>

Test 1:

// 6.2.2 hybrid asynchronous (com.yanchi)
@Test
public void test6_2_2(){
    Logger logger = LoggerFactory.getLogger(Slf4jToLog4j2.class);

    // Log section
    for (int i = 0; i < 50; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }

    // Business logic part
    for (int i = 0; i < 10; i++) {
        System.out.println("----------------------------------------");
    }
}

Log information 1: (asynchronous)

Test 2:

// 6.2.3 hybrid asynchronous (org.slf4j)
@Test
public void test6_2_3(){
    Logger logger = LoggerFactory.getLogger(Logger.class);

    // Log section
    for (int i = 0; i < 50; i++) {
        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }

    // Business logic part
    for (int i = 0; i < 10; i++) {
        System.out.println("----------------------------------------");
    }
}

Log information: (synchronization)

6. SpringBoot log implementation

Default integration: slf4j+logback

6.1 introduction cases

Test:

package com.yanchi;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootLogStudyApplicationTests {

    // 1. Use the default log (console log, no configuration file required)
    @Test
    public void test1() {

        Logger logger = LoggerFactory.getLogger(SpringbootLogStudyApplicationTests.class);

        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }

}

Log information:

6.2. Log implementation using log4j

Test:

package com.yanchi;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootLogStudyApplicationTest2 {

    // 2. Use log4j2 log implementation (observe whether the bridge is available)
    @Test
    public void test2() {

        Logger logger = LogManager.getLogger(SpringbootLogStudyApplicationTest2.class);

        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
        logger.fatal("fatal information");
    }

}

Log information:

6.3. Configuration file output console

Configuration file: (application.properties)

logging.level.com.yanchi=trace
logging.pattern.console=%d{yyyy-MM-dd} [%level] -%m%n

Test:

package com.yanchi;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootLogStudyApplicationTest3 {

    // 3. Implementation using configuration files
    @Test
    public void test3() {

        Logger logger = LoggerFactory.getLogger(SpringbootLogStudyApplicationTests.class);

        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");

    }

}

Log information:

6.4. Configuration file output file

Profile:

logging.level.com.yanchi=trace
logging.pattern.console=%d{yyyy-MM-dd} [%level] -%m%n
# 6.4. Configuration file output file (path)
logging.file.path=D:/test

Test:

package com.yanchi;


import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootLogStudyApplicationTest4 {

    // 4. Output to file using configuration
    @Test
    public void test4() {

        Logger logger = LoggerFactory.getLogger(SpringbootLogStudyApplicationTests.class);

        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
    }

}

Log information:

6.5 log splitting

Advanced features require the use of log corresponding configuration files

Import the logback.xml configured before for configuration

logback.xml:

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <!-- <property/> General properties of the configuration file for easy reference -->
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %c %M %L %thread %m%n"/>
    <!-- Configuration file output path -->
    <property name="logDir" value="D://test"/>

    <!-- configuration file appender -->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <!-- Import file location -->
        <file>${logDir}/logback.log</file>

        <!-- Format output -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!-- Configuring files for split archives appender -->
    <appender name="rollAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- Import file location -->
        <file>${logDir}/roll_logback.log</file>

        <!-- Format output -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>

        <!-- Specify split rules -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">

            <!-- Declare file names in time and compression format gz -->
            <fileNamePattern>${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>

            <!-- Split by file size-->
            <maxFileSize>1kb</maxFileSize>

        </rollingPolicy>
    </appender>

    <!-- Configuration Console  appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">

        <!--
            Indicates the configuration of the log output destination
            Default: System.out Indicates that the log is output in the default font
            set up: System.err Indicates that the log is output in red font
        -->
        <target>
            System.out
        </target>

        <!--
            Configure log output format
            How to manually configure the format
            You can directly import the above general attributes
        -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- Format reference common attribute configuration -->
            <pattern>${pattern}</pattern>
        </encoder>

    </appender>

    <!--
        Loggers
        to configure root logger
        level: Configure log level
    -->
    <root level="ALL">
        <!-- introduce appender -->
        <!--        <appender-ref ref="consoleAppender"/>-->
                <appender-ref ref="rollAppender"/>
    </root>

</configuration>

Test:

package com.yanchi;


import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootLogStudyApplicationTest5 {

    // 5. Configure log splitting using logback.xml
    @Test
    public void test5() {

        Logger logger = LoggerFactory.getLogger(SpringbootLogStudyApplicationTests.class);

        for (int i = 0; i < 1000; i++) {
            logger.trace("trace information");
            logger.debug("debug information");
            logger.info("info information");
            logger.warn("warn information");
            logger.error("error information");
        }
    }

}

Log information:

6.6 integration log4j2

Draining logback log dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <!--Remove the original dependencies by eliminating them logback Reference to-->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!--introduce log4j2 Log dependency for-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Import log4j2 configuration file:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>

    <!--Global configuration information-->
    <Properties>
        <Property name="logDir">D://test</Property>
    </Properties>

    <!-- to configure Appender -->
    <Appenders>
        <!--console output -->
        <Console name="consoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </Console>

        <!--File output-->
        <File name="fileAppender" fileName="${logDir}//log4j2.log">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n"/>
        </File>

    </Appenders>
    
    <!--to configure logger-->
    <Loggers>
        <Root level="info">
            <AppenderRef ref="consoleAppender"/>
        </Root>
    </Loggers>
</Configuration>

Test:

package com.yanchi;


import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootLogStudyApplicationTest6 {

    // 6. Log printing using log4j2.xml configuration
    @Test
    public void test6() {

        Logger logger = LoggerFactory.getLogger(SpringbootLogStudyApplicationTests.class);


        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
        
    }

}

Log information:

package com.yanchi;


import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootLogStudyApplicationTest6 {

    // 5. Log printing using log4j2.xml configuration
    @Test
    public void test5() {

        Logger logger = LoggerFactory.getLogger(SpringbootLogStudyApplicationTests.class);

        logger.trace("trace information");
        logger.debug("debug information");
        logger.info("info information");
        logger.warn("warn information");
        logger.error("error information");
        
    }

}

Log information:

6.7. Using annotations to simplify operations

Import dependency:

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

Test:

package com.yanchi;


import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@Slf4j
class SpringbootLogStudyApplicationTest7 {

    // 7. Using annotations to simplify operations
    @Test
    public void test7() {

        log.trace("trace information");
        log.debug("debug information");
        log.info("info information");
        log.warn("warn information");
        log.error("error information");

    }

}

Log information:

Posted by Strikebf on Mon, 11 Oct 2021 17:32:03 -0700