Personal notes of Spring Boot from 0 to learn 3 - log

1 Overview

As for logging, there are many logging frameworks, and none of them are unified. Among them, the log is also divided into two parts, divided intoLog facadewithLog implementation

  • The log facade is an abstraction layer for logs. What exactly is it? I'm not so sure either
  • Log realization, is the new thing of typing code, the concrete realization thing

Insert picture description here
These are the mainstream frameworks. If you use them, you need to use a log facade, and then use a log to achieve.
Spring, which must be used in conjunction with the two, uses JCL
SpringBoot selects SLF4j and logback;

2. Use of SLF4j

In the future development, the call of the logging method should not directly call the log implementation class, but call the method in the log abstraction layer;
simple SLF4J use

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
    
    
  public static void main(String[] args) {
    
    
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

Logger is the recording class, LoggerFactory.getLogger(类名)and the parameter is the class name of a class, generally类.class

However, what we are using is SLF4Jthat this is just a tool, and what we really want to use islogback

3. Adapter mode

Just understand how to use it. I don’t know it very well. After slf4j is used, it can be converted into jars of other log abstraction layers with slf4j, and then things of other abstraction layers such as JCL can be output. In this way, other computers or other The framework can also use slf4
Insert picture description here

4. Legacy issues

For example, I am using slf4j+logback, but Spring (commons-logging), Hibernate (jboss-logging), MyBatis (a new one), each is different, and a project may introduce more Each frame, in this case, the log used by each frame is different, isn't it cold?
Don’t panic, spring boot solves
Insert picture description herethis picture for us , which means, for example, for example, frame A uses SLF4J, and frame B uses LOG4J. The data between the two cannot be read, then spring boot Import a package, SLF4J-LOG4J.jarthe function of this package is to convert SLF4J to LOG4J, so that other frameworks can also be used

How to unify all logs in the system to slf4j;

1. Exclude other log frameworks in the system first;(Remove other log frames)

2. Replace the original log framework with an intermediate package;(Spring boot is written and used directly)

3. We import other implementations of slf4j(The format uses SLF4J)

5. Spring boot log relationship

In the pom.xmllower, right-Diagrams-Show Dependencies, you can see the relationship between the log with a view of the way
Insert picture description here

6. Log default configuration

  • Spring boot helped us configure the default log, but we can also modify it
  • The log has 5 levels, from low to high respectivelytrace < debug < info < warn < error
  • What does grade mean? That is, if you select a level, the log will record该等级以及该等级之上的记录
  • The default level selected by spring boot is info, which means that logs of info, warn, and error levels can be displayed

1) Give an example

//单元测试
@SpringBootTest
class SpringBootFastApplicationTests {
    
    
	//记录器
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Test
    void contextLoads() {
    
    
        logger.trace("这是trace日志");
        logger.debug("这是debug日志...");
        //SpringBoot默认给我们使用的是info级别的,没有指定级别的就用SpringBoot默认规定的级别;root级别
        logger.info("这是info日志...");
        logger.warn("这是warn日志...");
        logger.error("这是error日志...");
    }
}

Direct output
Insert picture description here

2) Change the log level

application.propertiesAdd parameter
format:logging.level.包名(一般是com.包名)=设置等级

logging.level.com.qiang=trace

Insert picture description here

3) Save the log file

You can export the log into a .log file to
application.propertiesadd parameters.
There are several import parameter formats

  1. Generate log files in the current folder:logging.file.name=文件名.log
  2. Generate log files in the specified path:logging.file.name=绝对路径/文件名.log
  3. Create a folder and log file in the current directory:, generated logging.file.path=spring/login the current folderspring/log/spring.log, The name of the generated .log log is spring.log
  4. Create a folder and log file in the specified directory:logging.file.path=E:/spring/log

4) Output format

The format of the console and save log files are both by default
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

%d means the date and time,
%thread means the thread name,
%-5level: the level is displayed from the left with 5 characters width
%logger{50} means the logger name has a maximum of 50 characters, otherwise it is divided by periods.
%msg: log message,
%n is a newline character

such as

2020-07-13 14:46:26.330 ERROR 12340 — [main] cqsSpringBootFastApplicationTests: This is the error log...

  • The format of the log output on the console:logging.pattern.console= 格式
  • Specify the format of the log output in the file:logging.pattern.file= 格式

Insert picture description here
Saved spring.log file:

2020-07-13 === [main] === INFO  === c.q.springbootfast.SpringBootFastApplicationTests ==== Starting SpringBootFastApplicationTests on DESKTOP-J69KO73 with PID 1936 (started by master in D:\idea\spring-boot-fast)
2020-07-13 === [main] === DEBUG === c.q.springbootfast.SpringBootFastApplicationTests ==== Running with Spring Boot v2.3.1.RELEASE, Spring v5.2.7.RELEASE
2020-07-13 === [main] === INFO  === c.q.springbootfast.SpringBootFastApplicationTests ==== The following profiles are active: dev
2020-07-13 === [main] === INFO  === o.s.scheduling.concurrent.ThreadPoolTaskExecutor ==== Initializing ExecutorService 'applicationTaskExecutor'
2020-07-13 === [main] === INFO  === c.q.springbootfast.SpringBootFastApplicationTests ==== Started SpringBootFastApplicationTests in 4.15 seconds (JVM running for 6.675)
2020-07-13 === [main] === TRACE === c.q.springbootfast.SpringBootFastApplicationTests ==== 这是trace日志
2020-07-13 === [main] === DEBUG === c.q.springbootfast.SpringBootFastApplicationTests ==== 这是debug日志...
2020-07-13 === [main] === INFO  === c.q.springbootfast.SpringBootFastApplicationTests ==== 这是info日志...
2020-07-13 === [main] === WARN  === c.q.springbootfast.SpringBootFastApplicationTests ==== 这是warn日志...
2020-07-13 === [main] === ERROR === c.q.springbootfast.SpringBootFastApplicationTests ==== 这是error日志...
2020-07-13 === [SpringContextShutdownHook] === INFO  === o.s.scheduling.concurrent.ThreadPoolTaskExecutor ==== Shutting down ExecutorService 'applicationTaskExecutor'

7, designated placement

You can also application.propertiesmodify the log parameters one by one in the file, but like the configuration in the previous chapter, it application.propertiesis configured globally . It is better to separate and configure the configuration things better.

The rules for placing files in each log framework, the files are placed under resource:
Insert picture description here
we use logback for spring boot, let’s take this to explain

Just create it under resources logback.xml, the system will automatically load the log settings inside

However, this way of writing is not recommended, because this cannot start the profile function, which is the thing that performs different assignments in different environments. To
use the profile function, the file name must be logback-spring.xml, for example, write in it

<?xml version="1.0" encoding="UTF-8"?>
<!--
scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<configuration scan="false" scanPeriod="60 seconds" debug="false">
    <!-- 定义日志的根目录 -->
    <property name="LOG_HOME" value="/app/log" />
    <!-- 定义日志文件名称 -->
    <property name="appName" value="atguigu-springboot"></property>
    <!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出 -->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--
        日志输出格式:
			%d表示日期时间,
			%thread表示线程名,
			%-5level:级别从左显示5个字符宽度
			%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
			%msg:日志消息,
			%n是换行符
        -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <springProfile name="dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
            <springProfile name="!dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
        </layout>
    </appender>

    <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
    <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 指定日志文件的名称 -->
        <file>${LOG_HOME}/${appName}.log</file>
        <!--
        当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
        TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
        -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--
            滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动
            %i:当文件大小超过maxFileSize时,按照i进行文件滚动
            -->
            <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <!--
            可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
            且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,
            那些为了归档而创建的目录也会被删除。
            -->
            <MaxHistory>365</MaxHistory>
            <!--
            当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy
            -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 日志输出格式: -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
        </layout>
    </appender>

    <!--
		logger主要用于存放日志对象,也可以定义日志类型、级别
		name:表示匹配的logger类型前缀,也就是包的前半部分
		level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
		additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出,
		false:表示只用当前logger的appender-ref,true:
		表示当前logger的appender-ref和rootLogger的appender-ref都有效
    -->
    <!-- hibernate logger -->
    <logger name="com.atguigu" level="debug" />
    <!-- Spring framework logger -->
    <logger name="org.springframework" level="debug" additivity="false"></logger>



    <!--
    root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,
    要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。
    -->
    <root level="info">
        <appender-ref ref="stdout" />
        <appender-ref ref="appLogAppender" />
    </root>
</configuration>

I can't write xml files. . . But the main thing is to learn a thinking, see here

<layout class="ch.qos.logback.classic.PatternLayout">
    <springProfile name="dev">
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
    </springProfile>
    <springProfile name="!dev">
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
    </springProfile>
</layout>

The meaning here is that when the profile setting environment is dev, the console log will output that format. When the profile setting environment is not dev, the console output log will be in another format.

It was originally like this. When the xml file is not added
Insert picture description here
, the profile environment is set to dev in yml or properties, and it becomes like this.
Insert picture description here
When the setting environment is not dev, it becomes like this.
Insert picture description here

Guess you like

Origin blog.csdn.net/yi742891270/article/details/107425999