preface

Logging is usually not presented as a separate feature during the requirements phase, nor is it seen in detail in the production scenario. However, this does not detract from its important position in any system.

Today, I’ll show you how to configure logging in Spring Boot.

The Spring version of the Boot

The version of Spring Boot on which this article is based is 2.3.4.release.

The level of logging

The common log levels are as follows: TRACE < DEBUG < INFO < WARN < ERROR < FATAL.

What do you make of this log level? Very simply, if the log level in the project is set to INFO, the log information at lower levels will not be visible, that is, TRACE and DEBUG logs will not be displayed.

What are the logging frameworks?

Common logging frameworks are log4j, LogBack, and log4j2.

Log4j is a well-known logging framework that is often used in Spring development, but log4j is officially no longer up to date and performs much worse than Logback and Log4j2.

Logback, another open source logging framework designed by the founders of Log4j, offers over 10 performance improvements over Log4j and a smaller initial memory load. Being the default logging framework for Spring Boot certainly has some advantages.

Log4j2 was released later than Logback, and its performance is higher than that of Logback. However, it is not known that log4J2 is a copy of Logback in many ideas, so even though log4j2 is an official Apache project, Many framework projects, such as Spring, do not mainstream it. Here is entirely the author’s hearsay, not to be taken seriously, a digress only.

There are many logging frameworks, how to choose to adapt to the current project development, of course, not ordinary programmers to consider, but in order to pursue higher, at least should understand, haha.

Spring Boot Logging framework

The default logging framework of Spring Boot is Logback. Since Spring Boot can incorporate it into the default logging system, there must be some considerations, so do not change the actual development process.

In principle, logBack is required, and the following dependencies need to be added, but since it is the default logging framework, there is no need to reintroduce the dependencies.

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

The default log level in Spring Boot isINFO, the startup project log is printed as follows:

As you can see from the figure above, the default elements of the output log are as follows:

  1. Time and date: accurate to the millisecond
  2. Log levels are ERROR, WARN, INFO, DEBUG, and TRACE
  3. The process ID
  4. Delimiter: – Identifies the start of the actual log
  5. Thread name: enclosed in square brackets (may truncate console output)
  6. Logger name: The name of the class that normally uses the source code
  7. Log contents

How is logging used in code?

You certainly need to trace logs in your business, so how do you export logs in your own business? In fact, there are two commonly used ways, the following one.

The first method, which was used a long time ago, simply added the following to the code:

private final Logger logger= LoggerFactory.getLogger(DemoApplicationTests.class);
Copy the code

This approach is obviously weak, if every class to add a low. Don’t worry, Lombok has solved this problem for us.

To use Lombok, add the following dependencies:

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
Copy the code

It is also very simple to use, just need to annotate the class with an annotation @slf4j, as follows:

@Slf4j
class DemoApplicationTests {
  @Test
  public void test(a){
    log.debug("Output DEBUG logs......."); }}Copy the code

How do I customize log levels?

The default logging level in Spring Boot is INFO, but you can customize the logging level as follows:

logging.level.root=DEBUG
Copy the code

Spring Boot also supports package level log level adjustment in the format of logging.level. XXX = XXX.

logging.level.com.example.demo=INFO
Copy the code

The complete configuration is as follows:

logging.level.root=DEBUG
logging.level.com.example.demo=INFO
Copy the code

How to output logs to a file?

Spring Boot logs are output to the console by default, but are not displayed in a production environment, so you need to configure logs to be output to a log file.

Two important configurations are as follows:

  1. logging.file.path: Specifies the path of the log file
  2. logging.file.name: Specifies the name of the log file. The default value isspring.log

Note: The official documentation says that these two attributes cannot be configured at the same time, otherwise they will not take effect, so you only need to configure one.

The output file is logs in the current project path. By default, the generated log file is spring.log, as follows:

logging.file.path=./logs
Copy the code

There are other attributes in the log file, such as the maximum size of the log file, the number of days the log is kept, and so on, which are described below.

How do I customize the log format?

The default log format has been seen in the first figure. Sometimes you need to customize your own log output format so that it is easy to see when troubleshooting logs.

The custom log format has two configurations, the console output format and the log output format in the file, as follows:

  1. logging.pattern.console: Output format of the console
  2. logging.pattern.file: Output format of a log file

For example:

logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n
logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
Copy the code

The meanings of the above configuration codes are as follows:

%d{HH:mm: ss.sss} -- log output time %thread -- log output process name, useful in Web applications and asynchronous task processing %-5level -- log level, and use5Left-aligned %logger- -- log sender's name % MSG -- log message %n -- platform newlineCopy the code

How do I customize log configuration?

According to the Spring Boot official documentation, depending on the logging system, you can use the following log configuration file name to load correctly, as follows:

  1. Logback: logback-spring. XML, logback-spring.groovy, logback. XML, logback.groovy
  2. Properties, log4j-spring. XML, log4j.properties, log4j.xml
  3. Log4j2: Log4j2 – spring XML, Log4j2. XML
  4. JDK (Java Util Logging) : logging.properties

Spring Boot recommends using the -spring file name as your log configuration preference. So just create logback-spring. XML in the SRC /resources folder with the following configuration file:


      
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <! -- Define log directory -->
    <property name="logPath" value="logs"/>
    <! -- Log output format -->
    <property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} %L %M - %msg%xEx%n"/>
    <contextName>logback</contextName>

    <! Output to console ConsoleAppender
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <! Display layout-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${PATTERN}</pattern>
        </layout>
            <! If level is ERROR, the console will only output ERROR logs -->
<! -- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
<! -- <level>ERROR</level>-->
<! -- </filter>-->
    </appender>

    <! -- Normal log file, output to file -->
    <appender name="fileDEBUGLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <! If you only want Info level logs, you will still get Error logs if you only want Info level logs. Because the Error level is high, you can use the following policy to avoid Error logs.
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <! - the filtering Error -- -- >
            <level>Error</level>
            <! -->
            <onMatch>DENY</onMatch>
            <! --> < span style = "color: RGB (51, 51, 51);
            <onMismatch>ACCEPT</onMismatch>
        </filter>

        <! If there is both <File> and <FileNamePattern>, then the current log is <File>, and tomorrow it will automatically rename today's log to today's date. That is, the logs in <File> are from the current day. -->
        <File>${logPath}/log_demo.log</File>
        <! TimeBasedRollingPolicy-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <! File path, which defines how to split logs -- archive logs for each day into a file to prevent logs from filling the disk space -->
            <FileNamePattern>${logPath}/log_demo_%d{yyyy-MM-dd}.log</FileNamePattern>
            <! Save only logs generated in the last 90 days.
            <maxHistory>90</maxHistory>
            <! -- Specifies the maximum size of the log file, at which the old log file will be deleted -->
            <! --<totalSizeCap>1GB</totalSizeCap>-->
        </rollingPolicy>
        <! -- Log output encoding formatting -->
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${PATTERN}</pattern>
        </encoder>
    </appender>

    <! Output ERROR log to the specified file -->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <! ThresholdFilter--> ThresholdFilter-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>Error</level>
        </filter>
        <! If there is both <File> and <FileNamePattern>, then the current log is <File>, and tomorrow it will automatically rename today's log to today's date. That is, the logs in <File> are from the current day. -->
        <File>${logPath}/error.log</File>
        <! TimeBasedRollingPolicy-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <! File path, which defines how to split logs -- archive logs for each day into a file to prevent logs from filling the disk space -->
            <FileNamePattern>${logPath}/error_%d{yyyy-MM-dd}.log</FileNamePattern>
            <! Save only logs generated in the last 90 days.
            <maxHistory>90</maxHistory>
            <! -- Specifies the maximum size of the log file, at which the old log file will be deleted -->
            <! --<totalSizeCap>1GB</totalSizeCap>-->
        </rollingPolicy>
        <! -- Log output encoding formatting -->
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${PATTERN}</pattern>
        </encoder>
    </appender>


    <! -- Specify the basic log output level -->
    <root level="DEBUG">
        <! -- Appender will be appended to this loger-->
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileDEBUGLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>

    <! -- Define the log level of the specified package -->
    <logger name="org.springframework" level="DEBUG"></logger>
    <logger name="org.mybatis" level="DEBUG"></logger>
    <logger name="java.sql.Connection" level="DEBUG"></logger>
    <logger name="java.sql.Statement" level="DEBUG"></logger>
    <logger name="java.sql.PreparedStatement" level="DEBUG"></logger>
    <logger name="io.lettuce.*" level="INFO"></logger>
    <logger name="io.netty.*" level="ERROR"></logger>
    <logger name="com.rabbitmq.*" level="DEBUG"></logger>
    <logger name="org.springframework.amqp.*" level="DEBUG"></logger>
    <logger name="org.springframework.scheduling.*" level="DEBUG"></logger>
    <! -- define com. XXX.. xx.. The log information in the xx package is directly output to the two appenders of fileDEBUGLog and fileErrorLog. The log level is DEBUG-->.
    <logger name="com.xxx.xxx.xx"  additivity="false" level="DEBUG">
        <appender-ref ref="fileDEBUGLog"/>
        <appender-ref ref="fileErrorLog"/>
    </logger>

</configuration>

Copy the code

If you don’t want to use the name recommended by Spring Boot, you can customize it by specifying the name of the configuration file as follows:

logging.config=classpath:logging-config.xml
Copy the code

What do you mean, a bunch of configurations? Don’t worry. Here are the details.

The configuration node

This is a root node with the following attributes:

  1. scan: When this property is set to true, the configuration file will be reloaded if it changes. The default value is true.
  2. scanPeriod: Sets the interval for monitoring whether the configuration file has been modified. If no time unit is given, the default unit is milliseconds. This attribute takes effect when scan is true. The default interval is 1 minute.
  3. debug: When this attribute is set to true, internal logBack logs are displayed to view the running status of logback in real time. The default value is false.

The root node

This is a required node that specifies the base log level, with only one level attribute, the default being DEBUG. This node can contain zero or more elements, and the child node is appender-ref, which marks the appender appender that will be added to the logger.

ContextName node

Identifies a context name. Default is default and is not generally used

Property nodes

Tags a context variable with attributes like name and value that can be retrieved using ${} after the variable is defined.

Appender node

It is used to format the log output node with two attributes, name and class. Class specifies which output policy is used, usually console output policy and file output policy.

This node is important, because a normal log file needs to define three appenders: console output, normal log file output, and exception log file output.

This node has several important child nodes, as follows:

  1. filter: Log output interceptor, there is no special custom generally use the system can, but if you want to separate logs, such as ERROR level log output to a file, will be removedERRORLevel logs are output to another file, at which point interception is requiredERRORLog level.
  2. encoderThe: and pattern nodes are used to specify the output log format and encoding mode.
  3. fileThe: node specifies the output location of the log file. It can be an absolute path or a relative path
  4. rollingPolicy: log rollback policy, here we use TimeBasedRollingPolicy, there is a subnode fileNamePattern, necessary node, can be used to set the specified time of the log archive.
  5. maxHistory: Optional node: controls the maximum number of archived files that can be retained. If the number exceeds 30, old files will be deleted. For example, if the value is set to 30, old logs will be deleted after 30 days
  6. totalSizeCap: Optional node to specify the maximum size of log files, such as 3GB, at which old logs will be deleted

The logger node

Optional node to specify the log output level of the package, which will override root’s output level. This node has several important properties:

  1. name: Specifies the package name
  2. level: Optional, log level
  3. addtivity: Optional. The default value is true. If the logger information is transmitted to the upper layer, the root node will define log printing. If set to false, upload will not be performed, in which case you need to define oneappender-ref The node will output.

conclusion

Spring Boot log selection and how to customize log configuration is introduced here, if you feel that you have gained, you might as well click a concern, share a wave, will be the biggest encouragement to the author!!