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、参考博客

相关推荐
KK溜了溜了1 小时前
JAVA-springboot log日志
java·spring boot·logback
我命由我123452 小时前
Spring Boot 项目集成 Redis 问题:RedisTemplate 多余空格问题
java·开发语言·spring boot·redis·后端·java-ee·intellij-idea
面朝大海,春不暖,花不开2 小时前
Spring Boot消息系统开发指南
java·spring boot·后端
hshpy2 小时前
setting up Activiti BPMN Workflow Engine with Spring Boot
数据库·spring boot·后端
jay神2 小时前
基于Springboot的宠物领养系统
java·spring boot·后端·宠物·软件设计与开发
不知几秋3 小时前
Spring Boot
java·前端·spring boot
howard20054 小时前
5.4.2 Spring Boot整合Redis
spring boot·整合redis
TracyCoder1234 小时前
接口限频算法:漏桶算法、令牌桶算法、滑动窗口算法
spring boot·spring·限流
饮长安千年月4 小时前
JavaSec-SpringBoot框架
java·spring boot·后端·计算机网络·安全·web安全·网络安全
考虑考虑5 小时前
Jpa中的@ManyToMany实现增删
spring boot·后端·spring