Use of Java logging framework (slf4j, Logback)

Get into the habit of writing together! This is the 12th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

introduction

SpringBoot provides a default configuration file base.xml for Logback, which defines the default journal output level as INFO.

    ERROR(40, "ERROR"),
    WARN(30, "WARN"),
    INFO(20, "INFO"),
    DEBUG(10, "DEBUG"),
    TRACE(0, "TRACE");
复制代码

insert image description here

Use of I Logback

insert image description here

Slf4J, the Simple Logging Facade for Java, is not a specific logging solution, it only serves a variety of logging systems. Slf4J is a simple facade for logging systems that allows end users to deploy their applications with the logging system they desire.

SLF4J is more like re-encapsulating these logging frameworks, providing a common interface for users to call. No matter how the underlying framework changes, you only need to replace the dependencies, and you do not need to change the project one by one. Where to call the method of the original logging system .

Logback is Spring Boot's built-in log processing framework. You will find that spring-boot-starter includes spring-boot-starter-logging, which is the default log framework of Spring Boot, logback. Official documentation: logback.qos.ch/manual/

1.1 Facade Mode

slf4j is a typical application of facade mode. The core of facade mode is外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用。 insert image description here

The usage of slf4j is the same sentence all the year round "Logger logger = LoggerFactory.getLogger(Object.class);". It can be seen that here is the specific implementation of a Logger interface provided by slf4j through LoggerFactory.

We can use mvn import lombokand use annotations to make it easier to use slf4j.

  1. POJO's getter/setter/toString; exception handling; I/O stream closing operation, etc. These boilerplate codes have no technical content and affect the beauty of the code, so Lombok came into being.

  2. IDEA 2020最后一个版本发布了,已经内置了Lombok插件,SpringBoot 2.1.x之后的版本也在Starter中内置了Lombok依赖

1.2 slf4j的应用举例

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

//1、新版spring-boot-starter-test不再集成junit,而是junit-jupiter,不再使用@RunWith()注解。
//@RunWIth(SpringRunner.class)
@SpringBootTest
public class LoggerTest {
private final Logger logger = LoggerFactory.getLogger(LoggerTest.class);

@Test
    public void test1() {

    logger.debug("debug...");

    logger.info("info..."); //系统的默认日记级别
    logger.error("error...");



}




}

复制代码

1.3 application.properties

配置文件所在目录不同优先级也不同,如下图1~4优先级从高到低

insert image description here

  1. 当前项目根目录的config下
  2. 当前项目根目录下
  3. resource目录的config目录下
  4. resource目录下
  5. 在使用 spring.config.location 指定外部配置文件时,需要此份配置文件需全量满足当前工程运行时所需,因为它不会去与 resources 目录下的配置文件去做 merge 操作。

application.properties和application.yml作用是一致的,spring boot项目中同时存在application.properties和application.yml文件时,两个文件都有效,但是application.properties的优先级会比application.yml高。

要么用application.properties 要么用 application.yml,不要都用使自己混乱

yaml不同于 properties 文件的无序,yaml 配置有序。

可设置spring.config.name环境变量指定配置文件名称。

1.4 启用“调试”模式

方式一: 在application.properties中配置debug=true,该属性置为true的时候,核心Logger(包含嵌入式容器、hibernate、spring)会输出更多内容,但是你自己应用的日志并不会输出为DEBUG级别。

方式二:在编译设置中开启 insert image description here

默认情况下,Spring Boot将日志输出到控制台,不会写到日志文件。我们可以在application.properties或application.yml配置,但是只能配置简单的场景,保存路径、日志格式等,复杂的场景(区分 info 和 error 的日志、每天产生一个日志文件等)满足不了,只能自定义配置。

1.5 自定义logback的配置文件

按如下规则组织配置文件名,就能被正确加载: 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

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <property name = "ENCODER_PATTERN" value = "%d{MM-dd  HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n"/>
    <!-- 控制台日志:输出全部日志到控制台 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 控制输出流对象,默认System.out 改为System.err-->
        <target>System.err</target>
        <!-- 日志消息格式配置-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- root Logger 配置-->
    <root level="info">
        <appender-ref ref="console"/>
    </root>
</configuration>
复制代码

fileInfoLog和fileErrorLog

    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %msg%n
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>/Users/mac/Desktop/log/tomcat/test/info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>


    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>
                %msg%n
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>/Users/mac/Desktop/log/tomcat/test/error.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>


    <!-- root Logger 配置-->
    <root level="info">
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileErrorLog"/>

    </root>
复制代码

查阅正在改变的日志文件: tail -f error.2022-04-09.log

II SpringBoot内置插件的使用(jackson和lombok)

idea2021.2.2 已经捆绑安装jackson和lombok插件

insert image description here

2.1 lombok

Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。

projectlombok.org/features/al…

  1. 添加maven,如果不指定版本号,会提示找不到最新版本1.18.22,我们可以指定版本之后,再重新加载。
<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>

复制代码

如果不想每次都写private final Logger logger = LoggerFactory.getLogger(当前类名.class); 可以用注解@Slf4j

@Slf4j
    public void test1() {

    log.debug("debug...");

    log.info("info..."); //系统的默认日记级别
    log.error("error...");



}
复制代码

注解@Data作用在类上,会为类的所有属性自动生成setter/getter、equals、hasCode、toString方法。

@Builder在创建对象时具有链式赋值的特点。

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Student {

复制代码

2.2 jackson

SpringBoot内置了jackson来实现JSON的序列化和反序列化。

jackson使用ObjectMapper类将POJO对象序列化为JSON字符串,也能将JSON字符串反序列化为POJO对象。 insert image description here

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

        String str = mapper.writeValueAsString(stu);
        Student stu = mapper.readValue(str,Student.class);

复制代码

jackson包含很多注解,用于个性化序列化和反序列化操作。

  1. @JsonProperty(alias),作用在属性上,为属性指定别名。
  2. @JsonIgnore,作用在属性上,用此注解来忽略属性。
  3. @JsonIgnoreProperties({propertyName1,propertyName2}),作用在类上,表示忽略一组属性。
  4. @JsonFormat(pattern=""),用于格式化日期。

For example @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss"), format the time as "year-month-day hour:minute:second".

    @JsonIgnore
    private String gender;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonProperty("bd")
    private Date birthday;

复制代码

see also

The shell script completes the extraction of the log file

idea, shortcut keys for quick search:command+o

Guess you like

Origin juejin.im/post/7085531183148187684