Learning Spring Boot: (4) Application Log

foreword

Application logs are a very important part of a system. Later, whether it is development or online, logs play a crucial role. This time the Logbacklogging framework is used.

text

Spring Boot uses Commons Logging for 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 console or file output log content.

Default log Logback

  • SLF4J - Simple Logging Facade For Java, it is a unified Facade abstraction for various Java logging frameworks. There are many Java logging frameworks - commonly used are java.util.logging, log4j, logback, commons-logging, Spring framework uses Jakarta Commons Logging API (JCL). While SLF4J defines a unified logging abstraction interface, the real logging implementation is determined at runtime - it provides bindings for various logging frameworks.

  • Logback is a new generation of logging framework developed by the author of the log4j framework. It is more efficient, can adapt to many operating environments, and naturally supports SLF4J.

By default, Spring Boot will use Logback to log and output to the console with INFO level. You should have seen a lot of INFO level logs when running the application and other examples.
springboot4-1.png

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
* Process ID
* Separator: ---identifies the start of the actual log
* Thread name: Square brackets (may truncate console output)
* Logger name: usually the class name of the source code
* Log content

add log dependency

If spring-boot-starter-logging is added to the maven dependency:

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

Then, our Spring Boot application will automatically use logback as the application logging framework. When Spring Boot starts, it will be initialized and used by org.springframework.boot.logging.Logging-Application-Listener according to the situation.

However, in actual development, we do not need to add this dependency directly. You will find that spring-boot-starter contains spring-boot-starter-logging, which is Spring Boot's default logging framework logback.

That is, we do not need additional configuration.

Default configuration property support

Spring Boot provides us with a lot of default logging configurations, so as long as spring-boot-starter-logging is added to the classpath of the current application as a dependency, it will work "out of the box".
The following describes several log-related properties that can be configured in application.properties.

console output

The log level is divided into TRACE < DEBUG < INFO < WARN < ERROR < FATAL from low to high. If it is set to WARN, the information below WARN will not be output.
By default, Spring Boot configures ERROR, WARN, and INFO-level logs to be output to the console. You can also enable "debug" mode (recommended when developing) by enabling your application --debug flag, either:

--debugAdd a flag after running the command , such as: $ java -jar springTest.jar --debug
in application.propertiesthe configuration debug=true, when this property is set to true, the core Logger (including embedded container, hibernate, spring) will output more content, but the log of your own application will not output as DEBUG level.

file output

By default, Spring Boot outputs logs to the console and does not write to log files. If you want to write log files other than console output, you need to set logging.file or logging.path properties in application.properties.

  • logging.file , the setting file, which can be an absolute path or a relative path. Such as: logging.file=my.log
  • logging.path , set the directory, the spring.log file will be created in this directory, and the log content will be written, such as: logging.path=/var/log
    If only logging.file is configured, a spring.log file will be generated in the current path of the project xxx.log log file.
    If only logging.path is configured, a log file is generated in the /var/log folder as spring.log

    Note: The two cannot be used at the same time. If they are used at the same time, only logging.file will take effect


By default, when the size of the log file reaches 10MB, it will be split once, and a new log file will be generated. The default level is: ERROR, WARN, INFO

level control

All supported logging systems can set the logging level in the Spring environment (e.g. in application.properties) in the format: 'logging.level.*=LEVEL'
  • logging.level : log level control prefix, * is the package name or Logger name
  • LEVEL : Options TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
    Example:

  • logging.level.com.dudu=DEBUG: com.duduAll classes under the package are output at DEBUG level

  • logging.level.root=WARN: root logs are output at WARN level

Custom log configuration

Since the logging service is generally initialized before the ApplicationContext is created, it does not have to be controlled by Spring's configuration file. Therefore, log control and management can still be well supported through system properties and traditional Spring Boot external configuration files.

Depending on the log system, you can organize the configuration file names according to the following rules, and they will be loaded correctly:
* Logback: logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
* Log4j: log4j-spring .properties, log4j-spring.xml, log4j.properties, log4j.xml
* Log4j2: log4j2-spring.xml, log4j2.xml
* JDK (Java Util Logging): logging.properties

Spring Boot officially recommends using the file name with -spring as your log configuration (such as using logback-spring.xml instead of logback.xml), and the log configuration file named logback-spring.xml. Spring boot can be It adds some spring boot-specific configuration items (mentioned below).

The above is the default naming rule, and it src/main/resourcescan be placed below.

logback.xml

basic configuration

If you want to have full control over the logging configuration, but don't want to use it logback.xmlas a Logbackconfiguration name, you can specify a custom name in the application.propertiesconfiguration file through properties:logging.config

logging.config=classpath:logging-config.xml

Although it is generally not necessary to change the profile name, this feature can be useful if you want to use different
logging .

Let's take a look at a common logback-spring.xml example

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>logback</contextName>
    <property name="log.path" value="/Users/tengjun/Documents/log" />
    <!--输出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
       <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>-->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}.%M:%L - %msg%n</pattern>
        </encoder>
    </appender>

    <!--输出到文件-->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/logback.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}.%M:%L - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="file" />
    </root>

    <!-- logback为java中的包 -->
    <logger name="com.dudu.controller"/>
    <!--logback.LogbackDemo:类的全路径 -->
    <logger name="com.dudu.controller.LearnController" level="WARN" additivity="false">
        <appender-ref ref="console"/>
    </logger>
</configuration>

attribute analysis

root node

<configuration>The attributes contained in the root node :
* scan: When this attribute is set to true, the configuration file will be reloaded if it changes, the default value is true.
* scanPeriod: Set the time interval for monitoring whether the configuration file is modified. If the time unit is not given, the default unit is milliseconds. This property takes effect when scan is true. The default time interval is 1 minute.
* debug: When this property is set to true, the internal log information of logback will be printed out, and the running status of logback will be viewed in real time. The default value is false.

**Child nodes of the root node:
There are 2 attributes and 3 child nodes below, which are **:
* Set the context name <contextName>
Each logger is associated with the logger context, and the default context name is "default". However, it can be set to other names to distinguish records from different applications. Once set and cannot be modified, the log context name can be printed via %contextName.

<contextName>logback</contextName>
  • Set variable A label
    used to define the value of a variable. There are two attributes, name and 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.

child node one<appender>

The appender is used to format the log output node, there are two attributes nameand class, class is used to specify which output strategy, commonly used are console output strategy and file output strategy.

Console output ConsoleAppender:
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>ERROR</level>
    </filter>
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}.%M:%L - %msg%n</pattern>
    </encoder>
</appender>

<encoder>Indicates to encode the log:
* %d{HH: mm:ss.SSS} - log output time
* %thread - the process name of the log output, which is useful in web applications and asynchronous task processing
* %-5level- - log level, and use 5 characters to align left
* %logger{36} - the name of the log exporter
* %msg - the log message
* %n - the newline for the platform

ThresholdFilter is an interceptor defined by the system. For example, we use ThresholdFilter to filter out logs below the ERROR level and not output them to the file. If you don't remember to comment it out, otherwise you will find that there is no log in the console~

Output to file RollingFileAppender

Another common log output is to a file. As the application runs longer and longer, the log will grow more and more. It is not a good way to output them to the same file. RollingFileAppenderFor split file log:

<!--输出到文件-->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>${log.path}/logback.%d{yyyy-MM-dd}.log</fileNamePattern>
        <maxHistory>30</maxHistory>
        <totalSizeCap>1GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}.%M:%L - %msg%n</pattern>
    </encoder>
</appender>

The important thing is the definition of rollingPolicy. In the above example, ${log.path}/logback.%d{yyyy-MM-dd}.log defines the segmentation method of the log - archive the log of each day into a file , 30 means to keep only the last 30 days of logs to prevent the logs from filling up the entire disk space. In the same way, you can use %d{yyyy-MM-dd_HH-mm} to define an accurate log segmentation method. 1GB is used to specify the upper limit of the log file size. For example, if it is set to 1GB, then when this value is reached, the old log will be deleted.

Supplement: If you want to put the log directly under the current project, just remove ${log.path}/.

The problem of logback daily generation and size generation conflict can be found in this answer: Portal

child node two

The root node is a mandatory node, used to specify the most basic log output level, and has only one level attribute.

level: used to set the print level, case-insensitive: TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF, cannot be set to INHERITED or the synonym NULL.
Default is DEBUG.
Can contain zero or more elements that identify the appender that will be added to this logger.

<root level="debug">
    <appender-ref ref="console" />
    <appender-ref ref="file" />
</root>

child node three

Used to set the log printing level and designation of a package or a specific class. There is only a name attribute, an optional level and an optional addtivity attribute.

  • name: used to specify a package or a specific class that is constrained by this logger.
  • level: used to set the print level, case-insensitive: TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF, and a special value INHERITED or the synonym NULL, which represents the level of the mandatory execution of the superior. If this property is not set, the current logger will inherit the level of the superior.
  • addtivity: Whether to pass printing information to the superior logger. Default is true.

Note: When using mybatis, the sql statement will be printed only under debug, and here we only configure info, so if you want to view the sql statement, there are the following two operations:
* The first one will print sql if you change it to this , but then there will be a lot of other messages in the log.
* The second is to configure the debug mode for the directory under dao separately. The code is as follows, so that the configuration sql statement will print, and the others are still at the normal info level:

<logger name="com.dudu.dao" level="DEBUG" additivity="false">
    <appender-ref ref="console" />
</logger>

Multi-environment log output

According to different environments (prod: production environment, test: test environment, dev: development environment) to define different log output, use the springProfile node to define in logback-spring.xml, the method is as follows:

The file name is not logback.xml. If you want to use spring extension profile support, you should name it logback-spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <logger name="org.springframework.web" level="INFO"/>
    <logger name="org.springboot.sample" level="TRACE" />

    <!-- 开发、测试环境,多个用逗号隔开 -->
    <springProfile name="dev,test">
        <logger name="org.springframework.web" level="INFO"/>
        <logger name="org.springboot.sample" level="INFO" />
        <logger name="com.wuwii" level="DEBUG" additivity="false" />
    </springProfile>

    <!-- 生产环境 -->
    <springProfile name="pro">
        <logger name="org.springframework.web" level="ERROR"/>
        <logger name="org.springboot.sample" level="ERROR" />
        <logger name="com.wuwii" level="ERROR" additivity="false" />
    </springProfile>

</configuration>

You can specify the profile when starting the service (if not specified, use the default), for example, the way to specify prod is:
java -jar xxx.jar –spring.profiles.active=prod

format color

Note that Spring Boot output logs to the console have different colors according to the log level, and the logback official also gave an explanation:
https://logback.qos.ch/manual/layouts.html#coloring

I configured one like this:

        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %highlight(%-5level) %cyan(%logger{36}).%M:%L - %msg%n</pattern>
        </encoder>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325632944&siteId=291194637