springboot+logback学习文档

目录

1、前提说明

  • 默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台。
  • Slf4j(Simple Logging Facade For Java):它是一个针对于各类Java日志框架的统一外观抽象(门面模式)。
  • 日志级别:TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出。

2、引入依赖、将logback配置文件打到classes下

2.1、引入依赖

java 复制代码
<!-- 启动依赖中包含了spring-boot-starter-logging依赖,进而包含了logback相关依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- 引入@Slf4j注解,方便使用log.XXX()方法 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

2.2、将logback配置文件打到classes下

xml 复制代码
<!-- 在 -->
<build>
    <resources>
        <!-- 将resources目录中的配置文件统统打包 -->
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.*</include>
            </includes>
        </resource>
        <!-- 将代码目录中的xml文件一并打包,针对将included标签引入的配置文件放在依赖jar包代码层的情况 -->
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

3、使用说明

3.1、配置文件名称和位置

名称

  • logback-spring.xml
  • logback-spring.groovy
  • logback.xml
  • logback.groovy
  • 自定义文件名

说明1:Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml),命名为logback-spring.xml的日志配置文件,spring boot可以为它添加一些spring boot特有的配置项(下面会提到)。

说明2:在application.properties配置文件里面通过logging.config属性指定自定义的名字,例如 logging.config=classpath:logging-config.xml

位置:

src > main > resources目录下面,例如:

3.2、常规用法

3.2.1、property标签(普通变量)

xml 复制代码
# 语法
<property name="变量名" value="变量值"/>

# 使用范围
在所有logback的xml文件中都可以使用,包括使用include标签引入的文件中;
可以把一个项目中所有位置的logback的xml文件内容理解成一个合体大文件,
所以变量可以在各个文件中随意定义、随意使用,但是注意别重复了。

# 定义示例
<!-- 定义服务名称 -->
<property name="app_name" value="item"/>
<!-- 定义日志输出格式 -->
<property name="log.pattern" value="%date{yyyy-MM-dd HH:mm:ss.SSS} | %-5level | %thread | %logger{56}.%method | %L : %msg%n" />


# 使用示例(即${变量名},此时变量LOG_PATH代表"/opt/log/item")
<!-- 在其他变量中使用 -->
<property name="LOG_PATH" value="/opt/log/${app_name}"/>
<!-- 将日志按照定义的日志输出格式输出到控制台 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>${log.pattern}</pattern>
        <charset>utf-8</charset>
    </encoder>
</appender>

3.2.2、springProperty标签(spring变量)

xml 复制代码
# 语法
<springProperty name="变量名" value="spring配置属性"/>

# 使用范围
在spring环境中使用

# 定义示例
<!-- 定义服务名称 -->
<springProperty name="app_name" source="spring.application.name"/>
<!-- 定义端口 -->
<springProperty name="server_port" source="server.port" />

# 使用示例(即${变量名},此时变量LOG_PATH代表"/opt/log/item")
<!-- 定义日志文件输出路径 -->
<property name="LOG_PATH" value="/opt/log/${app_name}"/>
<!-- 定义日志输出格式 -->
<property name="log.pattern" value="%date{yyyy-MM-dd HH:mm:ss.SSS} | ${app_name} | %-5level | %thread | %logger{56}.%method | %L : %msg%n" />

3.2.3、conversionRule标签(通过代码来自定义数据规则)

xml 复制代码
# 语法(该变量的值指代该类中convert方法的返回值)
<conversionRule conversionWord="变量名" converterClass="ClassicConverter类的子类全路径"/>

# 定义示例
<!-- 获取本地服务的IP,LogIpConfig类的详细代码在下面 ->
<conversionRule conversionWord="app_ip" converterClass="com.atguigu.base.config.LogIpConfig"/>

# 使用示例(即$变量名,此时变量$app_ip代表真实ip)
<!-- 定义日志输出格式 -->
<property name="log.pattern" value="%date{yyyy-MM-dd HH:mm:ss.SSS} | %app_ip | ${app_name} | %-5level | %thread | %logger{56}.%method | %L : %msg%n" />

# 打印结果
2024-12-19 22:54:32.466 | 192.168.1.6 | item | INFO  | main | com.atguigu.item.init.SystemInit.afterPropertiesSet | 29 : 测试......

LogIpConfig:

java 复制代码
import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;

/**
 * 打印ip类
 * @author 明快de玄米61
 * @date   2024/12/9 9:15
 **/
public class LogIpConfig extends ClassicConverter {

    private static final Logger logger = LoggerFactory.getLogger(LogIpConfig .class);

    private static String webIP;
    static {
        try {
            webIP = InetAddress.getLocalHost().getHostAddress();
        } catch (Exception e) {
            logger.error("获取日志Ip异常", e);
            webIP = null;
        }
    }

    @Override
    public String convert(ILoggingEvent event) {
        return webIP;
    }
}

3.2.4、include标签(引入配置文件)

通过include标签可以将依赖jar包中的配置文件引入当前项目,这样所有配置文件内容将组装成一个合体大文件,不过注意被引入文件中标签的书写方式

3.2.5、root标签(定义全局的日志输出情况)

作用:

  1. 定义日志输出级别(日志级别:TRACE < DEBUG < INFO < WARN < ERROR < FATAL
  2. 引入自定义日志输出规则(等会介绍具体输出规则的定义方式)

示例:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    ......
    <!-- 控制打印输出的内容 -->
    <root level="INFO">
        <!-- 打印ERROR级别日志到文件中 -->
        <appender-ref ref="FILE_ERROR"/>

        <!-- 打印WARN级别日志到文件中 -->
        <appender-ref ref="FILE_WARN"/>

        <!-- 打印INFO级别日志到文件中 -->
        <appender-ref ref="FILE_INFO"/>

        <!-- 打印level以及以上级别的日志到控制台中-->
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

3.2.5、logger标签(定义特定包或者类的日志输出情况)

参数说明:

  1. name(必填):指定受此logger约束的某一个包或者具体的某一个类
  2. level(非必填,默认值:继承root标签的level):日志级别
  3. additivity(非必填,默认值:true):是否向上级logger传递打印信息,也就是让上级也去处理该打印结果,当然与上级的level级别无关

作用:

  1. 定义特定包或者类的日志输出级别(日志级别:TRACE < DEBUG < INFO < WARN < ERROR < FATAL
  2. 引入自定义日志输出规则(等会介绍具体输出规则的定义方式)

示例:

logback-msg.xml:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<included>

    <!-- DEBUG日志记录器,日期滚动记录 -->
    <appender name="MSG_PRODUCER_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${LOG_PATH}/mq/producer/log.log</file>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/mq/producer/log-%d{yyyy-MM-dd}_%i.log</fileNamePattern>
            <!-- 除按日志记录之外,还配置了日志文件不能超过20M,若超过20M,日志文件会以索引0开始, 命名日志文件,例如log_error_2020-20-20_0.log -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>20MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <MaxHistory>7</MaxHistory>
        </rollingPolicy>

        <!-- 追加方式记录日志 -->
        <append>true</append>
        <!-- 日志文件的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${log.pattern}</pattern>
            <charset>utf-8</charset>
        </encoder>
    </appender>

    <logger name="com.atguigu.msg" level="DEBUG" additivity="false">
        <appender-ref ref="MSG_PRODUCER_FILE" />
    </logger>

</included>

在上述logback-msg.xml所在的项目msg代码中有这样一行代码:

java 复制代码
log.debug("消息被发送到kafka了");

如果按照logback文件配置情况,将会把日志信息输出到文件中

由于additivity是false,所以日志信息不会向上传递,假设上级日志配置文件中root标签的level是INFO级别,那么这种情况下日志不会输出的

如果additivity是true,或者不设置(默认是true),依然假设上级日志配置文件中root标签的level是INFO级别,并且上级日志配置文件中会将所有日志信息输出到控制台,此时日志将在控制台输出,如下图:

3.2.6、springProfile标签(根据spring环境输出日志)

根据不同环境(prod:生产环境,test:测试环境,dev:开发环境)来定义不同的日志输出,在 logback-spring.xml中使用 springProfile 节点来定义,方法如下:

文件名称不是logback.xml,想使用spring扩展profile支持,要以logback-spring.xml命名

xml 复制代码
<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
    <logger name="com.dudu.controller" level="info" />
</springProfile>
<!-- 生产环境. -->
<springProfile name="prod">
    <logger name="com.dudu.controller" level="ERROR" />
</springProfile>

可以启动服务的时候指定 profile (如不指定使用默认),如指定prod 的方式为:

bash 复制代码
java -jar xxx.jar --spring.profiles.active=prod

3.2.7、appender标签(定义日志输出方式)

3.2.7.1、日志格式

一般情况下,通过pattern标签定义日志输出格式,如下:

xml 复制代码
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} | %-5level | %thread | %logger{56} | %L : %msg%n</pattern>
        <charset>utf-8</charset>
    </encoder>
</appender>

现在来讲解一下上面日志输出格式的含义:

  • %date{yyyy-MM-dd HH:mm:ss.SSS}:年-月-日 时:分:秒 毫秒
  • %-5level:日志级别,一共占用5个字符,并且靠左对齐
  • %thread:线程名称
  • %logger{56}:类全路径名称
  • %L:日志所在代码的行数
  • %msg:日志内容
  • %n:换行符
3.2.7.2、日志输出策略---控制台输出

使用方式:

xml 复制代码
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} | %-5level | %thread | %logger{56} | %L : %msg%n</pattern>
        <charset>utf-8</charset>
    </encoder>
</appender>

输出效果:

java 复制代码
2024-12-23 12:11:43.947 | INFO  | main | com.atguigu.item.init.SystemInit.afterPropertiesSet | 18 : 测试......

对应输出日志代码,如下所示:

解释:

  • name:自己取的名字,可以在root标签或者logger标签下面的appender-ref标签中引用
  • class:使用ch.qos.logback.core.ConsoleAppender类可以将日志内容输出到控制台
  • encoder.pattern:日志内容输出格式,在上一章节讲过了
  • encoder.charset:字符编码
3.2.7.3、日志输出策略---文件滚动输出

下面介绍"基于时间和日志文件大小来进行日志滚动输出到文件"

java 复制代码
<!-- DEBUG日志记录器,日期滚动记录 -->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 正在记录的日志文件的路径及文件名 -->
    <file>${LOG_PATH}/log_error.log</file>
    
    <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!-- 备份记录的日志文件的路径及文件名,其中%d{yyyy-MM-dd}代表年-月-日(区分不同日期),而%i代表序号(用来区分同一天的不同文件) -->
        <fileNamePattern>${LOG_PATH}/error/error-%d{yyyy-MM-dd}_%i.log</fileNamePattern>
        <!-- 单个日志文件最大数据量,例如下面代表日志文件不能超过20M,若超过20M,日志文件会以索引0开始来命名日志文件,例如log_error_2020-20-20_0.log -->
        <maxFileSize>20MB</maxFileSize>
        <!-- 日志文件最大容量 -->
        <totalSizeCap>10GB</totalSizeCap>
        <!--日志文件保留天数-->
        <MaxHistory>7</MaxHistory>
    </rollingPolicy>

    <!-- 以追加方式记录日志 -->
    <append>true</append>
    
    <!-- 日志格式 -->
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <!-- 日志输出格式 -->
        <pattern>${log.pattern}</pattern>
        <charset>utf-8</charset>
    </encoder>
    
    <!-- 根据日志级别过滤;此日志文件只记录error级别的 -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
</appender>

其实没有太多可以解释的,在示例中已经注释清晰了,最顶级的appenderclass就是ch.qos.logback.core.rolling.RollingFileAppender,代表滚动输出到文件中,下面介绍一下内部的标签:

  • file:记录实时日志输出文件路径
  • rollingPolicy:定义日志文件备份策略
  • append:定义日志追加方式
  • encoder:定义日志输出格式
  • filter:根据日志级别过滤,控制日志输出级别
3.2.7.4、日志输出策略---异步输出(非必须,默认是同步输出)

logback提供了大量的Appender将日志输出到指定的位置。如ConsoleAppender用于同步地将日志输出到控制台,FileAppender用于同步地将日志输出到指定日志文件,SocketAppender用于同步地将日志通过套接字发送到指定服务器。他们都有一个共同点:同步。

那么如何修改日志配置文件将日志输出改为异步呢?logback提供了一个Appender的异步实现类:AsyncAppender。使用方法也非常简单,同样也是通过在配置文件中添加<appender>标签声明AsyncAppender,然后通过引用属性引用一个同步Appender即可,如下所示:

java 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <!-- 日志输出格式 -->
    <property name="log.pattern"
              value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)"/>

    <!-- 同步输出到控制台 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 异步输出 -->
    <appender name="async-console" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 引用同步,将其包装为异步 -->
        <appender-ref ref="console" />
    </appender>

    <!-- 采用异步输出 -->
    <root level="INFO">
        <appender-ref ref="async-console" />
    </root>
    
</configuration>

虽然示例中是控制台输出,但是也支持配合文件输出使用

为什么给同步Appender包装一层AsyncAppender就可以实现异步输出呢?

AsyncAppender内部维护了一个阻塞队列ArrayBlockingQueuelogback将我们打印日志的代码log.info("第一条日志")封装为一个事件Event,每当我们需要打印一行日志时,logback会将该事件放在阻塞队列中,然后再通过多线程的形式从该阻塞队列中获取一个事件执行。

阻塞队列可以保证日志的输出是有序的,多线程保证日志的输出是异步的。

4、代码用法

  1. 在类上添加@Slf4j注解
  2. 通过静态常量log来调用info、warn、error等方法,例如:log.info("测试......");

5、使用案例

链接: https://pan.baidu.com/s/1eH1ZcaVdqKQuLp7hIq-cgA?pwd=3vd7

提取码: 3vd7

6、参考博客

相关推荐
wm104327 分钟前
java web springboot
java·spring boot·后端
路在脚下@8 小时前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
啦啦右一8 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
森屿Serien8 小时前
Spring Boot常用注解
java·spring boot·后端
苹果醋39 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
荆州克莱11 小时前
mysql中局部变量_MySQL中变量的总结
spring boot·spring·spring cloud·css3·技术
武昌库里写JAVA12 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_192849990612 小时前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
Q_192849990612 小时前
基于Spring Boot的营销项目系统
spring boot
路在脚下@14 小时前
Spring Boot @Conditional注解
java·spring boot·spring