Logging framework Logback for Java interface testing

1, Introduction

For a mature interface testing framework, log management is essential. In the development and debugging phase, logs can help us locate problems faster; During the operation and maintenance of the test, the log system can help us record most of the abnormal information. Usually, many test frameworks collect log information to monitor and warn the interface test status in real time.

2, Foreword

Spring Boot uses common logging in all internal logs, but the default configuration also provides support for common logs, such as Java Util Logging, Log4J, Log4J2 and Logback. Each Logger can be configured to use the console or file to output log content.

3, Relationship between LogBack, Slf4j and Log4j

Slf4j is the abbreviation of The Simple Logging Facade for Java. It is a simple logging facade abstract framework. It only provides Log Facade API and a simple Log class implementation. It is usually combined with Log4j, LogBack, Java util. Logging is used. When slf4j is used as the Log access of the application layer, the program can dynamically adjust the underlying Log implementation framework (Log4j/LogBack/JdkLog...) according to the actual application scenario.

LogBack and Log4j are both open source journal tool libraries. LogBack is an improved version of Log4j. It has more features than Log4j. At the same time, it also brings great performance improvement. At the same time, it naturally supports SLF4J.

LogBack is officially recommended to be used with Slf4j, which can flexibly replace the underlying logging framework.

TIPS: in order to optimize log4j and improve its performance, the Apache foundation has started to develop log4j 2.0, which also draws on and absorbs some advanced features of logback.

4, Default log Logback

By default, Spring Boot will use Logback to record logs and output them to the console at the INFO level. You should have seen a lot of INFO level logs when running applications and other examples.

As can be seen from the above figure, the log output content elements are as follows:

  • Time and date: accurate to milliseconds
  • Log level: ERROR, WARN, INFO, DEBUG or TRACE
  • Logger Name: the class name of the source code is usually used
  • Separator: -- identifies the beginning of the actual log
  • Process ID
  • Thread Name: enclosed in square brackets (console output may be truncated)
  • Log content

5, Configuration details

1. Add log dependency

If spring boot starter logging is added to maven dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>
Copy code

Then, our Spring Boot application will automatically use logback as the application log framework. When Spring Boot is started, it will be started by org springframework. boot. logging. Logging application listener is initialized and used as appropriate.

However, in actual development, we do not need to add this dependency directly. You will find that Spring Boot starter includes Spring Boot starter logging, which is the default logging framework logback of Spring Boot

2. Configuration file

spring boot officials recommend preferentially using the file name with spring as your log configuration (for example, use logback-spring.xml instead of logback.xml), and name it logback-spring.xml XML log configuration file. spring boot can add some spring boot specific configuration items to it (mentioned below). And put it under src/main/resources.

Configuration file logback spring xml

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

    <!-- Log root-->
    <springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="./logs/spring-boot-logback"/>

    <!-- log level -->
    <springProperty scope="context" name="LOG_ROOT_LEVEL" source="logging.level.root" defaultValue="DEBUG"/>

    <!--  Identify this"STDOUT" Will be added to this logger -->
    <springProperty scope="context" name="STDOUT" source="log.stdout" defaultValue="STDOUT"/>

    <!-- Log file name-->
    <property name="LOG_PREFIX" value="spring-boot-logback" />

    <!-- Log file encoding-->
    <property name="LOG_CHARSET" value="UTF-8" />

    <!-- log file path+date-->
    <property name="LOG_DIR" value="${LOG_HOME}/%d{yyyyMMdd}" />

    <!--Format log-->
    <property name="LOG_MSG" value="- | [%X{requestUUID}] | [%d{yyyyMMdd HH:mm:ss.SSS}] | [%level] | [${HOSTNAME}] | [%thread] | [%logger{36}] | --> %msg|%n "/>

    <!--File size, default 10 MB-->
    <property name="MAX_FILE_SIZE" value="50MB" />

    <!-- Configure the rolling time of logs, which means that only the logs of the last 10 days are retained-->
    <property name="MAX_HISTORY" value="10"/>

    <!--Output to console-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- Output log content formatting-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${LOG_MSG}</pattern>
        </layout>
    </appender>

    <!--output to a file-->
    <appender name="0" class="ch.qos.logback.core.rolling.RollingFileAppender">
    </appender>

    <!-- definition ALL Log output mode:-->
    <appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--Log file path, log file name-->
        <File>${LOG_HOME}/all_${LOG_PREFIX}.log</File>

        <!-- Set the scrolling policy. The log size of the day exceeds ${MAX_FILE_SIZE} When the file size is, the new content is written to the new file. The default is 10 MB -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            <!--Log file path, new ALL Log file name“ i " It's a variable -->
            <FileNamePattern>${LOG_DIR}/all_${LOG_PREFIX}%i.log</FileNamePattern>

            <!-- Configure the rolling time of logs, which means that only the logs of the last 10 days are retained-->
            <MaxHistory>${MAX_HISTORY}</MaxHistory>

            <!--The log size for the day exceeds ${MAX_FILE_SIZE} When the file size is, the new content is written to the new file. The default is 10 MB-->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>

        </rollingPolicy>

        <!-- Output log content formatting-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${LOG_MSG}</pattern>
        </layout>
    </appender>

    <!-- definition ERROR Log output mode:-->
    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- The following is the configuration output only error Level log -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <OnMismatch>DENY</OnMismatch>
            <OnMatch>ACCEPT</OnMatch>
        </filter>
        <!--Log file path, log file name-->
        <File>${LOG_HOME}/err_${LOG_PREFIX}.log</File>

        <!-- Set the scrolling policy. The log size of the day exceeds ${MAX_FILE_SIZE} When the file size is, the new content is written to the new file. The default is 10 MB -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            <!--Log file path, new ERR Log file name“ i " It's a variable -->
            <FileNamePattern>${LOG_DIR}/err_${LOG_PREFIX}%i.log</FileNamePattern>

            <!-- Configure the rolling time of logs, which means that only the logs of the last 10 days are retained-->
            <MaxHistory>${MAX_HISTORY}</MaxHistory>

            <!--The log size for the day exceeds ${MAX_FILE_SIZE} When the file size is, the new content is written to the new file. The default is 10 MB-->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>

        <!-- Format the output log content-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_MSG}</Pattern>
        </layout>
    </appender>

    <!-- additivity Set as false,be logger Content not attached to root ,Configure to configure the printing of logs of all classes under the package. The level is ERROR-->

    <logger name="org.springframework"     level="ERROR" />
    <logger name="org.apache.commons"      level="ERROR" />
    <logger name="org.apache.zookeeper"    level="ERROR"  />
    <logger name="com.alibaba.dubbo.monitor" level="ERROR"/>
    <logger name="com.alibaba.dubbo.remoting" level="ERROR" />

    <!-- ${LOG_ROOT_LEVEL} log level -->
    <root level="${LOG_ROOT_LEVEL}">

        <!-- Identify this"${STDOUT}"Will be added to this logger -->
        <appender-ref ref="${STDOUT}"/>

        <!-- FILE_ALL Add log output to logger -->
        <appender-ref ref="FILE_ALL"/>

        <!-- FILE_ERROR Add log output to logger -->
        <appender-ref ref="FILE_ERROR"/>
    </root>

</configuration>
Copy code

Configuration file application yml

server:
  port: 8888  # Port number

logging:
  path: ./logs/zuozewei
  level:
    root: info #The log level from low to high is trace < debug < info < WARN < error < fatal. If it is set to WARN, information lower than WARN will not be output

Copy code

The log will create a new folder every day. For every 50 megabytes of Japanese file configuration, one text file will be written, more than one will be written

Folder: 20181228
 Folder contents: all_spring-boot-logback0.log 
Folder contents: all_spring-boot-logback1.log
 Folder contents: all_spring-boot-logback2.log

Folder contents: err_spring-boot-logback0.log
 Copy code

6, Multi environment log output

Different log outputs are defined according to different environments (prod: production environment, test: test environment, dev: development environment) The springProfile node is used in XML to define, as follows:

The file name is not logback XML. To use spring to extend the profile support, use logback spring XML naming

<!-- Effective production environment -->
	<springProfile name="prod">
		<root level="error">
			<appender-ref ref="STDOUT" />
			<appender-ref ref="FILE" />
		</root>
	</springProfile>


	<!-- The test and development environment log level is INFO/And record the log file -->
	<springProfile name="dev,test">
		<!-- Log output level -->
		<root level="INFO">
			<appender-ref ref="STDOUT" />
			<appender-ref ref="FILE" />
		</root>
	</springProfile>
Copy code

You can specify the profile when starting the service (if not, use the default). For example, the method of specifying prod is:

java -jar xxx.jar –spring.profiles.active=prod
 Copy code

7, Unit test

Here I choose to use lombok efficiency plug-in, so I only need @ Slf4j annotation to simplify private logger = loggerfactory Getlogger (this. Getclass())

RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class LogbackdemoApplicationTests {

	@Test
	public void contextLoads() {
		log.info("output info");
		log.debug("output debug");
		log.error("output error");
	}

}
Copy code

Generated logs:

- | [] | [20181228 22:53:20.756] | [INFO] | [192.168.1.18] | [main] | [c.z.l.LogbackdemoApplicationTests] | --> Starting LogbackdemoApplicationTests on 192.168.1.18 with PID 82507 (started by apple in /Users/apple/Downloads/Springboot-logback-demo)|
- | [] | [20181228 22:53:20.762] | [INFO] | [192.168.1.18] | [main] | [c.z.l.LogbackdemoApplicationTests] | --> No active profile set, falling back to default profiles: default|
- | [] | [20181228 22:53:21.590] | [INFO] | [192.168.1.18] | [main] | [c.z.l.LogbackdemoApplicationTests] | --> Started LogbackdemoApplicationTests in 1.69 seconds (JVM running for 3.525)|
- | [] | [20181228 22:53:21.955] | [INFO] | [192.168.1.18] | [main] | [c.z.l.LogbackdemoApplicationTests] | --> output info|
- | [] | [20181228 22:53:21.955] | [ERROR] | [192.168.1.18] | [main] | [c.z.l.LogbackdemoApplicationTests] | --> output error|
Copy code

8, Project catalogue

9, Summary

So far, I have finally introduced the Logback logging framework. It is recommended to use custom Logback spring XML, and it is also very simple to use logs in the code. Add private logger logger = loggerfactory in the class getLogger(this.getClass()); If you use lombok efficiency plug-in, you need @Slf4j annotation.


Author: zuozewei
Link: https://juejin.cn/post/7055936538093289485
 

Keywords: Java Back-end Programmer architecture

Added by duk on Mon, 24 Jan 2022 10:01:57 +0200