One article to get the use of the log framework in SpringBoot

Spring Boot's encapsulation of the logging framework

We know that in terms of logs, SpringBoot uses SLF4J+LogBack by default. Let's take a look at the log implementation framework LogBack it uses. In the DefaultLogbackConfiguration class, the file log format is defined as follows:

// DefaultLogbackConfiguration.java

private static final String FILE_LOG_PATTERN = "%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} "
		+ "${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}";

An example log output is as follows:

2023-07-10 21:42:58.925  INFO 7000 --- [           main] com.zyb.MyApplication                    : No active profile set, falling back to default profiles: default
2023-07-10 21:42:59.473  INFO 7000 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-07-10 21:42:59.479  INFO 7000 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]

File log format explanation:

  • %d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} Date and time: millisecond precision.
  • ${LOG_LEVEL_PATTERN:-%5p}Log level: ERROR, WARN, INFO, DEBUG, or TRACE.
  • ${PID:- }process ID.
  • ---Delimiter: Used to distinguish the start of the actual log content.
  • [%t]Thread name: in square brackets (may truncate console output).
  • %-40.40logger{39}Logger name: This is usually the source class name (often abbreviated).
  • %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}log content.

At the same time, logging.custom settings are allowed through configuration items. for example:

custom log format

  • logging.pattern.file: The log format of the file.
  • logging.pattern.console: The log format of the console.
  • logging.pattern.dateformat: date and time.
  • logging.pattern.level: log level.
  • logging.pattern.pid: Process ID.
  • logging.exception-conversion-word: Conversion word used when logging exceptions

custom log file

  • logging.file.max-history: The maximum number of days of archiving for log files to keep.
  • logging.file.max-size: The maximum size of the log file.
  • logging.file: Log file name.
  • logging.path: Log file path.

custom log level

logging.level.*: log level, logging.level.<logger-name>=<level>set by using . for example:

logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

The main thing is that we can logging.configdefine the configuration file address used by the logging framework. Because according to different log implementation frameworks, Spring Boot loads configuration files according to the following "agreement rules":

  • Logback: corresponding to logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy configuration files.
  • Log4j2: corresponding to log4j2-spring.xml, log4j2.xml configuration files.
  • JUL: Corresponds to the logging.properties configuration file.

The configuration file name here may be different depending on the version of SpringBoot. For example, in SpringBoot2.5.0, logback-spring.xml does not work, but logback.xml is feasible.

Although logging.there are many custom configuration items, in general, we only use logging.level.*configuration items to set the log levels of different Loggers. In other words, our main configuration is still written in the configuration file.

Currently, Spring Boot has built-in two log-related Starters:

  • spring-boot-starter-logging: Use a combination of SLF4J + Logback.
  • spring-boot-starter-log4j2: Use a combination of SLF4J + Log4j2.

Next, let's get started with Spring Boot's integrated log function, using the combination of SLF4J + Logback. Key features include:

  • The console prints logs.
  • Console color output.
  • The log file prints the log.
  • Custom log levels.

SLF4J + Logback Quick Start

rely:

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

spring-boot-starter-web includes spring-boot-starter, and spring-boot-starter already includes spring-boot-starter-logging

configuration file

In application.yml, add log-related configurations, as follows:

spring:
  application:
    name: just_do_it # 应用名

logging:
  # 日志文件配置
  file:
#    path: /Users/yunai/logs/ # 日志文件路径。
    name: ./logs/${
    
    spring.application.name}.log # 日志文件名。
    max-history: 7 # 日志文件要保留的归档的最大天数。默认为 7 天。
    max-size: 10MB # 日志文件的最大大小。默认为 10MB 。

  # 日志级别
  level:
    com:
      zyb:
        controller:
          LoggerController: DEBUG

Explain this configuration file:

logging.file.*Under the configuration item, set the Spring Boot log file

By default, Spring Boot logs will only be printed to the console. So it needs to be set through the logging.file.path or logging.file.name configuration item. However, it should be noted that the two are optional and do not work together.

  • logging.file.name : The full path name of the log file. It can be a relative path or an absolute path. Here, we set it to "/Users/yunai/logs/${spring.application.name}.log", the absolute path.
  • logging.file.path : Log file directory. The spring.log log file will be created in this directory. For example: /Users/yunai/logs/.
  • When both of the above are configured, the logging.file.name configuration item shall prevail.

②In logging.level.*the configuration item, set a custom log level.

The log levels defined by Spring Boot are TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF.

By default, the log level INFO for console and log files. That is, logs at the INFO, WARN, and ERROR levels will be recorded in the console and log files.

You can customize the log level corresponding to the Logger by using the logging.level.<logger-name>= configuration item. Here, we set the log level of the Logger named "cn.iocoder.springboot.lab37.loggingdemo.controller" to DEBUG.

If our console supports ANSI, we can use color output to improve readability. Through the spring.output.ansi.enabled configuration item, set the state of the ANSI function, there are three options:

  • ALWAYS : Enables the output of ANSI colors.
  • NEVER : Disables the output of ANSI colors.
  • DETECT: Automatically detect whether the console supports ANSI functions. Enable if supported, otherwise disable. By default, the option DETECT is used.

By default, Spring Boot has already configured the log format for color output, and we don't need to customize it, so we won't introduce it here. We only need to know the mapping relationship of different log levels corresponding to different colors:
insert image description here

Next, we write a Controller to test:

@RestController
@RequestMapping("/log")
public class LoggerController {
    
    

    private Logger logger = LoggerFactory.getLogger(getClass());

    @GetMapping("/debug")
    public void debug() {
    
    
        logger.debug("debug");
    }

    @GetMapping("/info")
    public void info() {
    
    
        logger.info("info");
    }

    @GetMapping("/error")
    public void error() {
    
    
        logger.error("error");
    }
}

insert image description here

Our file output log also has:
insert image description here

debug mode

By default, Spring Boot will only record logs at the ERROR, WARN and INFO levels. Maybe sometimes when we fail to start Spring Boot, we need to start Spring Boot debugging mode:

  • Let the core Logger (embedded container, Hibernate and Spring Boot, etc.) print DEBUG level logs to facilitate troubleshooting
  • Other Loggers in the application still maintain the original log level.

Currently, there are two ways to enable the debug mode of a Spring Boot application:

  • Enable it by adding the --debug flag to the startup parameters. For example say $java -jar myapp.jar --debug.
  • Enable it through the debug = true configuration item in the configuration file.
spring:
  application:
    name: just_do_it # 应用名

logging:
  # 日志文件配置
  file:
    name: ./logs/${
    
    spring.application.name}.log # 日志文件名。
    max-history: 7 # 日志文件要保留的归档的最大天数。默认为 7 天。
    max-size: 10MB # 日志文件的最大大小。默认为 10MB 。

# 调试模式
debug: true

Logback extensions

Spring Boot additionally provides two extensions of Logback's XML tags.

① Expansion 1: <springProfile /> tag

Through the <springProfile /> tag, set the configuration of Logback in the tag, which needs to conform to the specified Spring Profile to take effect.

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

② Expansion 2: <springProperty /> tag

Through the <springProperty /> tag, configuration items can be read from the Spring Boot configuration file. Examples are as follows:

<!-- 从 Spring Boot 配置文件中,读取 spring.application.name 应用名 -->
<springProperty name="applicationName" scope="context" source="spring.application.name" />
<!-- 日志文件的路径 -->
<property name="LOG_FILE" value="/Users/yunai/logs/${applicationName}.log"/>

Next we will demonstrate

The dependency remains unchanged, and only one application name configuration is reserved in application.yml:

spring:
  application:
    name: just_do_it

Then start writing our log configuration file;

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

<configuration>

    <!-- <1> -->
    <!-- 引入 Spring Boot 默认的 logback XML 配置文件  -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <!-- <2.1> -->
    <!-- 控制台 Appender -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志的格式化 -->
        <encoder>
            <!--直接使用的默认格式-->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 2.2 -->
    <!-- 从 Spring Boot 配置文件中,读取 spring.application.name 应用名 -->
    <springProperty name="applicationName" scope="context" source="spring.application.name" />
    <!-- 日志文件的路径 -->
    <property name="LOG_FILE" value="/Users/yunai/logs/${applicationName}.log"/><!-- 滚动日志文件 Appender -->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--指定了日志文件的输出路径-->
        <file>${LOG_FILE}</file>
        <!--滚动策略,基于时间 + 大小的分包策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--通过指定压缩文件名称,来确定分割文件方式-->
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
            <maxFileSize>10MB</maxFileSize>
        </rollingPolicy>
        <!-- 日志的格式化 -->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 3.1 -->
    <!-- 测试环境,独有的配置 -->
    <springProfile name="dev">
        <!-- 设置 Appender -->
        <root level="INFO">
            <appender-ref ref="console"/>
        </root>

        <!-- 设置 "cn.iocoder.springboot.lab37.loggingdemo" 的 Logger 的日志级别为 DEBUG -->
        <logger name="cn.iocoder.springboot.lab37.loggingdemo" level="DEBUG"/>
    </springProfile>

    <!-- 3.2 -->
    <!-- 生产环境,独有的配置 -->
    <springProfile name="prod">
        <!-- 设置 Appender -->
        <root level="INFO">
            <appender-ref ref="console"/>
            <appender-ref ref="file"/>
        </root>
    </springProfile>

</configuration>

If you are not very familiar with the LogBack configuration file, you can read my last article:
Understanding the Java Logging Framework in One Article

Then we write a startup class:

@SpringBootApplication

public class MyApplication  {
    
    

    private static final Logger LOGGER = LoggerFactory.getLogger(MyApplication.class);

    public static void main(String[] args) {
    
    

        SpringApplication.run(MyApplication.class,args);

        LOGGER.debug("在开发环境下可以看到");
    }
}

Through IDEA's Active profiles option, set the profile of the started Spring Boot application. As shown in the figure below:
insert image description here
the running results are as follows:
insert image description here

And if it is in a production environment, we cannot see this sentence.

SLF4J + Log4J2

Import dependencies:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<!--排除logback-->
		<exclusion>
			<artifactId>spring-boot-starter-logging</artifactId>
			<groupId>org.springframework.boot</groupId>
		</exclusion>
	</exclusions>
</dependency>
<!-- 添加log4j2 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

In application.yml, just add the configuration of the application name, as follows:

spring:
  application:
    name: just_do_it

Then we add Log4j2 configuration in log4j2-spring.xml, as follows:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="PID">????</Property>
        <Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
        <Property name="LOG_LEVEL_PATTERN">%5p</Property>
        <Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
        <!-- 1.1 -->
        <Property name="FILE_LOG_BASE_PATH">/Users/yunai/logs</Property>
        <Property name="APPLICATION_NAME">demo-application</Property>

        <!-- 1.2 -->
        <!-- 控制台的日志格式 -->
        <Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
        <!-- 1.3 -->
        <!-- 日志文件的日志格式 -->
        <Property name="FILE_LOG_PATTERN">%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} ${sys:PID} --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
    </Properties>

    <Appenders>
        <!-- 2.1 -->
        <!-- 控制台的 Appender -->
        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}" />
        </Console>

        <!-- 2.2 -->
        <!-- 日志文件的 Appender -->
        <RollingFile name="File" fileName="${FILE_LOG_BASE_PATH}/${sys:APPLICATION_NAME}"
                     filePattern="${FILE_LOG_BASE_PATH}/${sys:APPLICATION_NAME}-%d{yyyy-MM-dd-HH}-%i.log.gz">
            <!-- 日志的格式化 -->
            <PatternLayout>
                <Pattern>${sys:FILE_LOG_PATTERN}</Pattern>
            </PatternLayout>
            <!--滚动策略,基于时间 + 大小的分包策略 -->
            <Policies>
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
        </RollingFile>
    </Appenders>

    <Loggers>
        <!-- 3.1 -->
        <!-- 常用组件的 Logger 的日志级别 -->
        <Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
        <Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
        <Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
        <logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
        <Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
        <Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
        <Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
        <logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>

        <!-- 3.2 -->
        <!-- 自定义的 Logger 的日志级别 -->
        <logger name="com.zyb" level="debug"/>

        <!-- 3.3 -->
        <!-- 设置 Appender ,同时 ROOT 的日志级别为 INFO -->
        <Root level="info">
            <AppenderRef ref="Console" />
            <AppenderRef ref="File" />
        </Root>
    </Loggers>
</Configuration>

If you are not very familiar with the configuration file of log4j2, you can also read my previous article: One
article to understand the Java log framework

  • Refer to Spring Boot's default log4j2 XML configuration file log4j2-file.xml for modification .
  • At <1.1>, define the base path and file name of the log file. Because Spring Boot does not provide the Log4j2 extension, it cannot directly read the Spring Boot configuration file like "7. Logback extension", so here we can only define it directly.
  • At <1.2>, the log format of the console is defined.
  • At <1.3>, the log format of the log file is defined.
  • At <2.1>, configure the Appender of the console.
  • At <2.2>, configure the Appender of the log file.
  • At <3.1>, set the log level of the Logger of common components.
  • < 3.2>, the log level of the custom Logger. Here, we set the log level of the Logger named "cn.iocoder.springboot.lab37.loggingdemo" to DEBUG.
  • At <3.3>, set the Root Appender as the console and log files, and the log level as INFO.

The test method is the same as the previous example, so I won't go into details here.

Guess you like

Origin blog.csdn.net/zyb18507175502/article/details/131647909