Springboot项目中基于Logback框架自定义日志输出

场景:对Springboot中原有的Logback框架进行封装,通过AOP针对自定义注释进行日志输出,并配置输出的log文件路径,对于某些必要的日志,需要将其信息存储至数据库。

本文主要对Logback框架做一个简单的学习总结,并且记录了自定义配置Logback框架过程中的主要思想和关键步骤代码。

一、Logback介绍

Spring Boot默认使用LogBack日志系统,且默认是将日志打印到控制台上。
Logback是有自己的Maven地址的。

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

但该包通常被spring-boot-starter包含了,因此一般无需自行导入。

1.1 Logback层级

如果一个logger的名字加上一个.作为另一个logger名字的前缀,那么该logger就是另一个logger的祖先。如果一个logger与另一个logger之间没有其它的logger,则该logger就是另一个logger的父级。

举例: 名为的com.example的logger是名为com.example.service的logger的父级。
名为com的logger是名为com.example的logger的父级,是名为com.example.service的logger的祖先

1.2 Logback输出等级

Logback的日志输出等级分为:TRACE, DEBUG, INFO, WARN, ERROR。

如果一个给定的logger没有指定一个日志输出等级,那么它就会继承离它最近的一个祖先的层级。

为了确保所有的logger都有一个日志输出等级,root logger会有一个默认输出等级 — DEBUG。

1.3 Logback初始化流程

以下来自ChatGPT:

在 Spring Boot 中,默认情况下,Logback 在初始化时会读取以下两个配置文件:

logback-spring.xml: 这是主要的 Logback 配置文件,它位于类路径的根目录下。Spring Boot 使用 logback-spring.xml 作为 Logback 的默认配置文件,并且提供了一些额外功能,例如可以在配置文件中使用 Spring的属性占位符 ${} 来引用外部配置文件中的值,以及可以根据不同的环境(如开发、生产等)加载不同的配置。

logback.xml: 如果没有找到 logback-spring.xml 配置文件,Logback 将尝试读取 logback.xml 作为备用配置文件。这个文件也位于类路径的根目录下。但需要注意的是,使用 logback.xml配置文件时,将无法使用 Spring 的属性占位符和环境特定的配置功能。

Spring Boot 推荐使用 logback-spring.xml 作为 Logback 的配置文件,因为它可以更好地集成到 Spring Boot 的环境中,充分利用 Spring Boot 提供的特性和功能。

二、Logback自定义输出配置

在resources下编写logback配置文件logback-base.xml和logback-spring.xml,在初始化时Logback框架即可自动导入配置。

2.1 logback-base.xml

<?xml version="1.0" encoding="UTF-8"?>
<included>
    <contextName>logback</contextName>
    <!-- 
		name的值是变量的名称,value的值时变量定义的值
		定义变量后,可以使“${}”来使用变量
	-->
    <property name="log.path" value="d:\\logs" />

    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule 
              conversionWord="clr" 
              converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule 
              conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    <!--输出到控制台-->
    <appender name="LOG_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--输出到文件-->
    <appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/logback.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>
</included>

2.2 logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--引入其他配置文件-->
    <include resource="logback-base.xml" />
    <!--
    <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
    以及指定<appender>。<logger>仅有一个name属性,
    一个可选的level和一个可选的addtivity属性。
    name:用来指定受此logger约束的某一个包或者具体的某一个类。
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
          如果未设置此属性,那么当前logger将会继承上级的级别。
    addtivity:是否向上级logger传递打印信息。默认是true。
     -->

    <!--开发环境-->
    <springProfile name="dev">
        <logger name="cn.itcast.controller" additivity="false" level="debug">
            <appender-ref ref="LOG_CONSOLE"/>
        </logger>
    </springProfile>
    <!--生产环境-->
    <springProfile name="pro">
        <logger name="cn.itcast.controller" additivity="false" level="info">
            <appender-ref ref="LOG_FILE"/>
        </logger>
    </springProfile>

    <!--
    root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
    level:设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF 默认是DEBUG
    可以包含零个或多个元素,标识这个appender将会添加到这个logger。
    -->
    <root level="info">
        <appender-ref ref="LOG_CONSOLE" />
        <appender-ref ref="LOG_FILE" />
    </root>
</configuration>

三、封装Logger模块

新建一个Logger模块,主要利用AOP和SpringEvent机制来进行自定义日志输出。

3.1 SpringEvent介绍

Spring Event是Spring的事件通知机制,可以将相互耦合的代码解耦,从而方便功能的修改与添加。Spring Event是监听者模式的一个具体实现。

监听者模式包含了监听者Listener、事件Event、事件发布者EventPublish,过程就是EventPublish发布一个事件,被监听者捕获到,然后执行事件相应的方法。

3.2 模块开发步骤

1、定义日志操作事件类SysLogEvent。

2、定义@SysLog注解,用于在Controller的方法上标注当前方法需要进行操作日志的保存处理。

3、定义切面类SysLogAspect。

4、在切面类SysLogAspect中定义切点,拦截Controller中添加@SysLog注解的方法。

5、在切面类SysLogAspect中定义前置通知,在前置通知方法recordLog中收集操作日志相关信息封装为OptLogDTO对象并保存到ThreadLocal中。

6、在切面类SysLogAspect中定义后置通知,在后置通知方法doAfterReturning中通过ThreadLocal 获取OptLogDTO并继续设置其他的操作信息到OptLogDTO。

7、在切面类SysLogAspect的后置通知方法doAfterReturning中发布事件SysLogEvent。

8、定义监听器SysLogListener,监听日志发布事件SysLogEvent,这里用的Consumer有点类似于策略模式。

代码中Consumer接口的作用是允许开发人员传递一个行为或操作,对给定的输入对象进行处理。它可以用于各种场景,例如集合的遍历、数据的转换、事件处理等。通过定义一个Consumer 对象,可以将一段逻辑或操作封装起来,并在需要的时候传递给其他方法或函数。

/**
 * 异步监听日志事件
 */
@Slf4j
@AllArgsConstructor
public class SysLogListener {
    private Consumer<OptLogDTO> consumer;

    @Async
    @Order
    @EventListener(SysLogEvent.class)
    public void saveSysLog(SysLogEvent event) {
        OptLogDTO optLog = (OptLogDTO) event.getSource();
        //BaseContextHandler.setDatabase(database);
        consumer.accept(optLog);
    }
}

9、定义配置类LogAutoConfiguration,用于自动配置切面SysLogAspect对象。

四、自定义Logger模块使用

该模块为具体的业务模块,具体使用过程如下:

4.1 创建logback配置文件logback-base.xml和logback-spring.xml

4.2 创建LogService,自定义对日志的操作流程

@Service
@Slf4j
public class LogService {
    //将日志信息保存到数据库
    public void saveLog(OptLogDTO optLogDTO){
        //此处只是将日志信息进行输出,实际项目中可以将日志信息保存到数据库
        log.debug("保存日志信息:" + optLogDTO);
    }
}

4.3 创建配置类,将SysLogListener事件监听器注入框架,并配置了LogService处理日志。这里LogService作为Consumer的策略实现。

/*
*日志配置类
*/

@Configuration
public class LogAutoConfiguration {
    //自动配置日志监听器组件
    @Bean
    @ConditionalOnMissingBean
    public SysLogListener sysLogListener(LogService logService){
        return new SysLogListener(optLogDTO -> logService.saveLog(optLogDTO));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot,我们可以使用logback作为默认的日志框架来记录日志。如果需要添加自定义日志,我们可以按照以下步骤进行操作: 1. 添加依赖 在`pom.xml`添加如下依赖: ```xml <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> ``` 2. 添加日志配置文件 在`src/main/resources`下添加`logback.xml`文件,内容如下: ```xml <?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <logger name="com.example" level="DEBUG"/> <root level="INFO"> <appender-ref ref="console"/> </root> </configuration> ``` 这里的配置文件格式是logback的标准格式,可以根据需要进行修改。其: - `appender`定义了日志输出的方式和格式,这里我们定义了一个名为`console`的控制台输出; - `logger`定义了日志记录器,这里我们定义了一个名为`com.example`的日志记录器,并设置了日志级别为DEBUG; - `root`定义了日志输出的根级别,这里设置为INFO。 3. 在代码使用自定义日志 在代码使用自定义日志非常简单,只需要使用`org.slf4j.Logger`接口即可。例如: ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyService { private static final Logger logger = LoggerFactory.getLogger(MyService.class); public void doSomething() { logger.debug("Debug message"); logger.info("Info message"); logger.warn("Warn message"); logger.error("Error message"); } } ``` 这里我们使用`LoggerFactory.getLogger()`方法获取了一个名为`MyService`的日志记录器,然后可以使用`debug()`、`info()`、`warn()`、`error()`等方法记录不同级别的日志。 通过以上步骤,我们就可以在Spring Boot添加自定义日志了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值