springboot log management logback

1. Introduction to logback

In springboot, any spring-boot-starter-* will import a spring-boot-starter-logging starter dependency by default. The logback log is integrated by default. You can add log-related configurations in the project’s application.yml, or you can Directly specify the log configuration file for configuration.

2. How to integrate logback

2.1, springboot method

Any spring-boot-starter-* will import a spring-boot-starter-logging starter dependency by default, so as long as the starter is included in the dependencies of the current project, there is no need to introduce it explicitly.

2.2, non-springboot project

The following dependencies need to be introduced into the pom file in the current project:

<!-- A specific implementation of the slf4j log facade -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>

3. Naming convention of log configuration files

The log configuration file loaded by the springboot framework by default is logback-spring.xml. If you need to customize the configuration file name, you need to specify the log configuration file in the current project. The configuration file introduces the configuration as follows:

logging.location=classpath:mylogback.xml # Define in the resources directory

4. Detailed explanation of logback configuration file

4.1. Standards used in logback configuration files

Generally, there is no such information in the logback-spring.xml file. After adding it, you can be prompted when writing the configuration file.

<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns="http://ch.qos.logback/xml/ns/logback"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback
               https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/xsd/logback.xsd" debug="true"> 
4.2. Dynamically loading configuration files
<!-- Add scan tag to configuration tag -->
<configuration scan="true" scanPeriod="10 seconds" debug="false">
scan: When this attribute is set to true, if the configuration file changes, it will be reloaded. The default value is true;
scanPeriod: Sets the time interval for monitoring whether the configuration file is modified. If no time unit is given, the default unit is milliseconds. This property takes effect when scan is true. The default time interval is 1 minute;
debug: When this attribute is set to true, logback internal log information will be printed out and logback running status can be viewed in real time. The default value is false. 
4.3. Reference/custom attribute value
<!-- Configuration properties used to load logback -->
<!-- Use classpath to import files, just write the file name -->
<property resource="logback.properties"/>
<contextName>logback</contextName> <!--Property prefix defined in the properties file -->

<!-- Custom attribute value:
The value of name is the name of the variable, and the value of value is the value defined by the variable. The defined value will be inserted into the logger context.
After defining a variable, you can use "${}" to use the variable. -->
<property name="log.path" value="D:/mylog" />
4.4, appender tag

The appender tag is a child node of configuration and is the component responsible for writing logs; it has two necessary attributes: name and class.

name represents the name of the appender, and class represents the fully qualified class name using the appender type.

There are mainly the following appenders:

<!-- 1. Console output appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
</appender>
<!-- 2. File output appender -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
</appender>
<!-- 3. Appender for rolling record file output -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
</appender>
<!-- 4. Asynchronous output appender -->
<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
</appender>
4.4.1, ConsoleAppender of console output
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
  <!-- Log output format -->
  <!-- In order: time, log level, thread name, log printing class, log body content, newline -->
     <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
  </encoder>
</appender> 
4.4.2, FileAppender output to file
<!--appender for writing files-->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>testFile.log</file> <!--Define log file name-->
    <append>true</append> <!--Whether to append-->
    <encoder>
       <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
    </encoder>
</appender> 
4.4.3. Scroll output to file
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
   <file>test.log</file>

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>
   
   <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
      <fileNamePattern>tests.%i.log.zip</fileNamePattern>
      <minIndex>1</minIndex>
      <maxIndex>3</maxIndex>
   </rollingPolicy>
    
   <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>5MB</maxFileSize>
   </triggeringPolicy>
   <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
   </encoder>
</appender> 
4.4.3.1, RollingPolicy:

1. TimeBasedRollingPolicy: The most commonly used rolling strategy. It formulates the rolling strategy based on time and is responsible for both rolling and starting rolling.

There are the following tags:

1), fileNamePattern: necessary node, including file name and “%d” conversion character, such as: %d{yyyy-MM}. If %d is used directly, the default format is yyyy-MM-dd.

2), maxHistory: Optional node, controls the maximum number of archive files to retain. If the number exceeds, old files will be deleted. Assuming that monthly rolling is set and the value is 6, only the files in the last 6 months will be saved and the old files will be deleted. Note that by deleting old files, directories created for archiving will also be deleted.

3), file: The file subnode of RollingFileAppender is optional. By setting file, you can specify different locations for active files and archive files. The current log is always recorded to the file specified by file (active file ), the name of the active file will not change; if file is not set, the name of the active file will change at intervals based on the value of fileNamePattern.

4), totalSizeCap: The maximum size of the log saved. When this value is exceeded, old log files will be automatically deleted. It must be used together with maxHistory, and maxHistory takes effect first, followed by determining whether totalSizeCap is reached.

5), cleanHistoryOnStart: Default is false. If set to true, old log files will be automatically deleted when the project is started.

2. FixedWindowRollingPolicy: The rolling policy for renaming files according to the fixed window algorithm.

There are the following tags:

1), minIndex:The minimum value of the window index.

2), maxIndex:The maximum value of the window index.

3), fileNamePattern: Must contain %i. For example, assuming the minimum and maximum values are 1 and 2 respectively, and the naming pattern is mylog%i.log, the archive files mylog1.log and mylog2 will be generated. log. You can also specify file compression options, for example, mylog1.log.gz or mylog1.log.zip.

4.4.3.2, TriggeringPolicy:

1. SizeBasedTriggeringPolicy: Check the size of the currently active file. If it exceeds the specified size, the RollingFileAppender will be notified to trigger the rolling of the currently active file.

There are the following sub-tags:

maxFileSize: This is the size of the active file, the default is 10MB;

4.4.3.3, Filter

1. LevelFilter: Level filter, filtering based on log level. If the log levelis equal to the configuration level, the filter accepts or rejects logs based on onMath and onMismatch;

Has the following child nodes:
level: Set filtering level;

onMatch: Used to configure operations that meet filter conditions, DENY, NEUTRAL, ACCEPT;

onMismatch: Used to configure operations that do not meet the filter conditions, DENY, NEUTRAL, ACCEPT.

2. ThresholdFilter: Threshold filter, which filters out logs below the specified threshold. When the log level is equal to or higher than the critical value, the filter returns NEUTRAL; when the log level is lower than the critical value, the log will be rejected with only one level child node.

4.5, logger tag

Used to set the log printing level of a certain package or a specific class, and specify the appender; there is only one name attribute, an optional level and an optional addtivity attribute.

name: is used to specify a package or a specific class that is subject to this logger;

level: is used to set the printing level, case-independent, and has a specific value INHERITED or the synonym NULL, which represents the enforcement of the superior level. If this property is not set, the current logger will inherit the level of its superior.

additivity: Whether to pass printing information to the superior logger, the default is true.

<Logger name="org.springframework" level="info" additivity="false">
   <AppenderRef ref="Console"/>
</Logger>
4.6, root tag

The root tag is a required node and is used to specify the most basic log output level. There is only one level attribute, which defaults to debug and can contain zero or more elements. Identifies the appenders that will be added to this logger.

root represents the log of the root node in the current project. If a project name is com.test.demo, there are several loggers: root -> com -> com.test -> com.test.demo.

<root level="info">
   <appender-ref ref="CONSOLE" />
   <appender-ref ref="DEBUG_FILE" />
   <appender-ref ref="INFO_FILE" />
   <appender-ref ref="WARN_FILE" />
   <appender-ref ref="ERROR_FILE" />
</root>

5. Complete logback-spring.xml file

<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns="http://ch.qos.logback/xml/ns/logback"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback
               https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/xsd/logback.xsd" debug="true"
               scan="true" scanPeriod="10 seconds">
    <!--scan: When this property is set to true, if the configuration file changes, it will be reloaded. The default value is true.
scanPeriod: Sets the time interval for monitoring whether the configuration file is modified. If no time unit is given, the default unit is milliseconds. This property takes effect when scan is true. The default time interval is 1 minute. -->
    <!-- Configuration properties used to load logback -->
<!-- Use classpath to import files, just write the file name -->
<property resource="logback.properties"/>
    <contextName>logback</contextName>
<!-- The value of name is the name of the variable, and the value of value is the value defined by the variable. The defined value will be inserted into the logger context. After defining a variable, you can use "${}" to use the variable. -->
    <property name="log.path" value="D:/mylog" />
      <!-- Color log format -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-% 5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([ .15t]){faint} %clr(%-40.40logger{39}){ cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    <!-- Specify the location of log output -->
    <appender name="STDOUT"
              class="ch.qos.logback.core.ConsoleAppender">
        <!--<encoder>: Format the log: first, convert the log information into a byte array, and second, write the byte array to the output stream. -->
        <encoder>
            <!-- Log output format -->
            <!-- In order: time, log level, thread name, log printing class, log body content, newline -->
            <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
        </encoder>
        <!--This log appender is for development use. Only the lowest level is configured. The log level output by the console is log information greater than or equal to this level-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>info</level>
        </filter>
        <!-- This log file only records debug level -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--appender for writing files-->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>testFile.log</file>
        <append>true</append> <!--Whether to append-->
        <encoder>
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
   </appender>
    
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>test.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
          <fileNamePattern>tests.%i.log.zip</fileNamePattern>
          <minIndex>1</minIndex>
          <maxIndex>3</maxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
          <maxFileSize>5MB</maxFileSize>
        </triggeringPolicy>
        <encoder>
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
   </appender>


    <!-- Set the global log level. The log levels in order are: DEBUG, INFO, WARN, ERROR -->
    <!-- Specifying any log level will only print logs of the current level and subsequent levels. -->
    <root level="DEBUG">
        <!-- Specify the appender for printing logs, here the appender configured earlier is referenced through "STDOUT" -->
        <appender-ref ref="STDOUT" />
    </root>
    <!-- Specify local log levels according to special needs -->
    <logger name="com.test.mapper" level="DEBUG"/>
</configuration>

Summary: Springboot integrates the logback logging framework by default and uses the sl4j log facade. The above usage and configuration of logback are sufficient for the project.

I am a self-taught computer technology from scratch. I have some experience in operation and maintenance, back-end, various middleware technologies, big data, etc. I would like to obtain Self-study summary materials (pdf version) or hope to share the experience with others. To study, Follow the WeChat public account: Old Little Boy. You can get it by replying to the corresponding Technical Name/Technical Point in the background. (My learning purpose: once you learn it, share it for free)