“This is the second day of my participation in the First Wenwen Challenge 2022.First challenge in 2022”

One, the introduction

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

Second, the preface

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

LogBack, Slf4j, and Log4j

Slf4j, short for The Simple Logging Facade for Java, is a Simple Logging Facade abstraction framework that itself provides only a log Facade API and a Simple Logging class implementation. It is commonly used in conjunction with Log4j, LogBack, Use Java. Util. Logging. Slf4j as the application layer Log access, the program can dynamically adjust the underlying Log implementation framework according to the actual application scenarios (Log4j/LogBack/JdkLog…) .

LogBack and Log4j are both open source journalizing libraries. LogBack is an improved version of Log4j with more features and performance improvements than Log4j, and SLF4J is naturally supported.

LogBack is officially recommended for use with Slf4j to provide flexibility in replacing the underlying logging framework.

In order to optimize log4J and improve its performance, the Apache Foundation has developed Log4J 2.0, which also incorporates some of the advanced features of Logback.

4. Default log Logback

By default, Spring Boot logs logs using Logback and outputs them to the console at the INFO level. You should already see many info-level logs when running the application and other examples.As can be seen from the figure above, the log output content elements are as follows:

  • Time and date: accurate to the millisecond
  • Log level: ERROR, WARN, INFO, DEBUG or TRACE
  • Logger name: The name of the class that normally uses the source code
  • Delimiter: — identifies the start of the actual log
  • The process ID
  • Thread name: enclosed in square brackets (may truncate console output)
  • Log contents

Five, configuration details

1. Add log dependencies

If spring-boot-starter-logging is added to a Maven dependency:

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

So, our Spring Boot application will automatically use LogBack as the application logging framework, and when Spring Boot starts, By the org. Springframework. Boot. Logging. Logging Application – the Listener initialization and use depending on the situation.

However, in real development we don’t need to add the dependency directly, as you’ll seespring-boot-starterIt containsspring-boot-starter-logging, the dependency is the default Spring Boot logging framework Logback

2. Configuration files

Spring Boot officially recommends that you use a -spring file name for your log configuration (e.g. Logback-spring. XML instead of logback.xml). Spring Boot can add some Spring Boot-specific configuration items to it (mentioned below). Place it under SRC /main/resources.

Configuration file logback-spring.xml


      
<configuration>

    <! -- Log root directory -->
    <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"/>

    <! -- Indicates that "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 code -->
    <property name="LOG_CHARSET" value="UTF-8" />

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

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

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

    <! -- Set the rolling time of logs, indicating that only logs generated in the last 10 days are retained.
    <property name="MAX_HISTORY" value="10"/>

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

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

    <! -- Define the output mode of ALL logs :-->
    <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>

        <! ${MAX_FILE_SIZE} file size = ${MAX_FILE_SIZE}
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            <! -- log file path, new ALL log file name, "I" is a variable -->
            <FileNamePattern>${LOG_DIR}/all_${LOG_PREFIX}%i.log</FileNamePattern>

            <! -- Set the rolling time of logs, indicating that only logs generated in the last 10 days are retained.
            <MaxHistory>${MAX_HISTORY}</MaxHistory>

            <! ${MAX_FILE_SIZE} - ${MAX_FILE_SIZE} - ${MAX_FILE_SIZE}
            <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>

    <! ERROR log output :-->
    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <! Error level log (); 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>

        <! ${MAX_FILE_SIZE} file size = ${MAX_FILE_SIZE}
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

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

            <! -- Set the rolling time of logs, indicating that only logs generated in the last 10 days are retained.
            <MaxHistory>${MAX_HISTORY}</MaxHistory>

            <! ${MAX_FILE_SIZE} - ${MAX_FILE_SIZE} - ${MAX_FILE_SIZE}
            <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 to false, logger content not attached to root, configured to print logs for all classes in the package, level 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}">

        <! ${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 日志输出添加到 logger -->
        <appender-ref ref="FILE_ERROR"/>
    </root>

</configuration>
Copy the code

Configuration file application.yml

server:
  port: 8888  # port

logging:
  path: ./logs/zuozewei
  level:
    root: info # Log levels are classified from low to high as TRACE < DEBUG < INFO < WARN < ERROR < FATAL. If the log level is set to WARN, messages lower than WARN are not printed

Copy the code

Log will create a new folder every day, Japanese file configuration every 50 megabytes, a text file, more than a new write

20181228: All_spring-boot-logback0. log: all_spring-boot-logback1.log: All_spring-boot-logback2. log Folder contents: err_spring-boot-logback0.logCopy the code

6. Multi-environment log output

To define different log outputs according to different environments (prod: production environment, test: test environment, dev: development environment), use the springProfile node in logback-spring. XML to define different log outputs as follows:

The file name is not logback.xml. To use the Spring extension profile support, name it logback-spring.xml

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


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

You can specify a profile when starting a service (if the default is not specified). For example, prod can be specified as follows:

Java - jar XXX. The jar - spring. Profiles. The active = prodCopy the code

Unit testing

I’ve chosen to use the Lombok efficiency plugin here, so just using the @slf4J annotation simplifies writing the private Logger Logger = LoggerFactory.getLogger(this.getClass())

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

	@Test
	public void contextLoads(a) {
		log.info("The output info");
		log.debug("The debug output");
		log.error("The output error"); }}Copy the code

Generated logs:

- | | [] [20181228 22:53:20. 756] | | [INFO] [192.168.1.18] | | [main] [C.Z.L.L ogbackdemoApplicationTests] | - > 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: The default | - | | [] [22:53:21 20181228. 590] | | [INFO] [192.168.1.18] | | [main] [C.Z.L.L ogbackdemoApplicationTests] | -- - > Started LogbackdemoApplicationTests in 1.69 seconds (JVM running for 3.525) | | - [] | | [22:53:21 20181228. 955] [INFO] | | | [192.168.1.18] [the main] [C.Z.L.L ogbackdemoApplicationTests] | - > output info | | - [] | | [22:53:21 20181228. 955] [ERROR] | | | [192.168.1.18] [the main] [C.Z.L.L ogbackdemoApplicationTests] | - > output error |Copy the code

Viii. Project Catalog

Nine,

The Logback logging framework can be configured using logback-spring. XML. It is easy to use logging in your code. Private Logger Logger = LoggerFactory.getLogger(this.getClass()); The @slf4J annotation is required if you use the Lombok efficiency plug-in.

Source code:

  • Github.com/zuozewei/bl…