当前位置: 首页 > news >正文

如何在 Spring Boot 中集成日志框架 SLF4J、Log4j

文章目录

  • 具体步骤
  • 附录

笔者的操作环境:

  • Spring Cloud Alibaba:2022.0.0.0-RC2

  • Spring Cloud:2022.0.0

  • Spring Boot:3.0.2

  • Nacos 2.2.3

  • Maven 3.8.3

  • JDK 17.0.7

  • IntelliJ IDEA 2022.3.1 (Ultimate Edition)

具体步骤

  1. 因为 Spring Boot 已经内置了 Logback,所以需要先将 Logback 移除。移除的方法是在 Spring Boot 依赖包中移除 Logback。

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

    比如就像这样:

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

    【踩坑提醒】

      如何使用了 Maven 多模块,必须在所有依赖 Logback 的依赖包中将 Logback 排除,否则 Spring Boot 启动时会发生如下报错:

    SLF4J: Class path contains multiple SLF4J providers.
    SLF4J: Found provider [ch.qos.logback.classic.spi.LogbackServiceProvider@4f51b3e0]
    SLF4J: Found provider [org.apache.logging.slf4j.SLF4JServiceProvider@4b9e255]
    SLF4J: See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual provider is of type [ch.qos.logback.classic.spi.LogbackServiceProvider@4f51b3e0]
    

    比如,下面这两个 Spring Boot 依赖包中都依赖了 Logback,所以都要排除 Logback。

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
    </dependency>
    
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
    </dependency>
    

    如果想确定自己的 Maven 模块有没有依赖 Logback,可以在 IntelliJ IDEA 中查看。

    在这里插入图片描述

    比方说,下面这种情况就属于同时依赖了 Logback、Log4j2,这样 Spring Boot 就会在启动时报错。

    在这里插入图片描述


  2. 引入与 Spring Boot 适配的 Log4j2 依赖包。

    <!-- 设置 SLF4J 与之绑定的日志包。无需提供 SLF4J 的 JAR 包,因为 Lombok 已经提供了 -->
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId><version>Spring Boot 的版本</version>
    </dependency>
    

    此依赖包的版本与 Spring Boot 是一致的。如果不清楚应该使用什么版本,可以去 Maven 仓库中查询。Maven 仓库官网:https://mvnrepository.com/


    【提示】

      对于不使用 Spring Boot 的项目,使用的是如下经典 Log4j2 依赖配置。使用 Spring Boot 之后,此依赖配置是多余的。

    <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>Log4j2 的版本</version>
    </dependency>
    <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>Log4j2 的版本</version>
    </dependency>
    <!-- 设置 SLF4J 与之绑定的日志包。无需提供 SLF4J 的 JAR 包,因为 Lombok 已经提供了 -->
    <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>Log4j2 的版本</version>
    </dependency>
    

    读者可以自行检查,Spring Boot 适配的 Log4j2 依赖包已经包含了上述经典 Log4j2 依赖配置。

    在这里插入图片描述


  3. 提供 Log4j2 的日志配置文件。

    如果不提供此配置,则 Spring Boot 会提供一个默认配置。通常,默认配置也不是很糟糕,但它有一个严重的问题,它不会将日志输出至文件来备份。因此,不能使用默认配置。

    一个示例的 Log4j2 的日志配置如下,读者可以自行变更为自己喜欢的配置。

    <?xml version="1.0" encoding="UTF-8"?><configuration status="OFF"><Properties><property name="console_log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%t] %l %n %m%n</property><property name="file_log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%t] %C.%M[%L line] %n %m%n</property><property name="every_file_size">20MB</property></Properties><appenders><Console name="Console" target="SYSTEM_OUT"><ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/><PatternLayout pattern="${console_log_pattern}"/></Console><RollingFile name="DEBUG" fileName="./log/log4j2/debug.log"filePattern="./log/log4j2/debug_log_archive/debug-%d{yyyy-MM-dd}-%i.log.zip"><PatternLayout pattern="${file_log_pattern}"/><Policies><SizeBasedTriggeringPolicy size="${every_file_size}"/></Policies><Filters><ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/></Filters></RollingFile><RollingFile name="INFO" fileName="./log/log4j2/info.log"filePattern="./log/log4j2/info_log_archive/info-%d{yyyy-MM-dd}-%i.log.zip"><PatternLayout pattern="${file_log_pattern}"/><Policies><SizeBasedTriggeringPolicy size="${every_file_size}"/></Policies><Filters><ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/></Filters></RollingFile><RollingFile name="WARN" fileName="./log/log4j2/warn.log"filePattern="./log/log4j2/warn_log_archive/warn-%d{yyyy-MM-dd}-%i.log.zip"><PatternLayout pattern="${file_log_pattern}"/><Policies><SizeBasedTriggeringPolicy size="${every_file_size}"/></Policies><Filters><ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/></Filters></RollingFile><RollingFile name="ERROR" fileName="./log/log4j2/error.log"filePattern="./log/log4j2/error_log_archive/error-%d{yyyy-MM-dd}-%i.log.zip"><PatternLayout pattern="${file_log_pattern}"/><Policies><SizeBasedTriggeringPolicy size="${every_file_size}"/></Policies><Filters><ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/></Filters></RollingFile></appenders><loggers><!-- 属性 level 是用于设置最低需要输出的日志输出级别 --><root level="DEBUG"><appender-ref ref="Console"/><appender-ref ref="DEBUG"/><appender-ref ref="INFO"/><appender-ref ref="WARN"/><appender-ref ref="ERROR"/></root></loggers>
    </configuration>
    
  4. Log4j2 的日志配置文件编写完成之后,可以放在 Maven 模块的 resource 目录下,如下图所示。

    在这里插入图片描述

    然后,在 Spring Boot 配置文件(如 application.yml)中使用如下代码引入该配置。

    logging:config: classpath:log4j2.xml
    

    如果 Log4j2 的日志配置文件名为 log4j2.xmllog4j2-spring.xml,且放在 resource 目录下,那就算是不在 Spring Boot 配置文件中引入此 Log4j2 的日志配置,Spring Boot 也会自动读取该 Log4j2 的日志配置。不过,最好还是显式地引入此配置。


    【注意】

      如果使用了 Maven 多模块,则此 Log4j2 的日志配置文件和 Spring Boot 配置文件只能放在 Spring Boot 入口模块中。不要在一种没有程序启动入口的 Maven 库模块中放置此配置文件


  5. 前面已经导入了 Log4j2,现在来考虑 SLF4J。

    SLF4J 是一种门面日志,它只要发现导入了 Log4j2,它就会自动使用它。

    幸运的是,有一个众所周知的插件叫 Lombok,它已经内置了 SLF4J。因此只要使用 Lombok,就可以不需要引入 SLF4J 依赖。

  6. 引入 Lombok 的依赖代码如下。

    <!-- 注意:Lombok 不会在依赖中被继承 -->
    <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>Lombok 的版本</version><scope>provided</scope>
    </dependency>
    
  7. 然后,在需要使用 SLF4J 的类上使用注解 @Slf4j。这样就可以直接在代码中使用 log.xxx(...) 来使用 Log4j2 日志了。

    @Slf4j
    public class UserAvatarController {// ...省略其它内容...public void fun(HttpServletRequest request, HttpServletResponse response) {log.info("fun called");
    }
    

附录

  • Log4j2

    • Log4j2 的开源地址:https://github.com/apache/logging-log4j2

    • Log4j2 官方文档:https://logging.apache.org/log4j/2.x/manual/index.html

  • SLF4J

    • SLF4J 官网:https://www.slf4j.org/

    • SLF4J 官方文档:https://www.slf4j.org/docs.html

http://www.lryc.cn/news/117356.html

相关文章:

  • 如何在Linux布置nginx(附带Nginx基本操作步骤)
  • Xcode升级导致关联库报错
  • 利用docker run --rm 命令实现使用宿主机中没有的命令
  • 中级课程——XSS
  • win10+Vmware+ubuntu18 mosquitto调试记录
  • Java EE 突击 9 - Spring Boot 日志文件
  • 篇十六:命令模式:封装请求
  • Android 系统框架
  • 【Hystrix技术指南】(3)超时机制的原理和实现
  • MySQL: Failed to Connect to MySQL at XXXX:3306 with user root
  • 《大型网站技术架构设计》第二篇 架构-性能
  • 谷歌推出AI模型机器人RT2 将文本和图像输出为机器人动作
  • 常见的服务器安全管理漏洞
  • JavaScript高级:探索作用域链的神秘面纱
  • mysql数据库如何转移到oracle
  • nnU-Net 终极指南
  • ubuntu 安装 python
  • 【腾讯云 Cloud studio 实战训练营】云端 IDE 构建移动端H5
  • Kubernetes 之 Kubeadm 搭建
  • Qt应用开发(基础篇)——堆栈窗口 QStackedWidget
  • 浅谈测试开发岗位
  • 典型移动APP安全风险提醒
  • 多平台发布文章-项目总结
  • 什么是IoC?什么是Spring IoC?什么是DI?
  • 分布式任务调度平台XXL-JOB学习笔记-helloworld运行
  • 维护工程师提升设备管理水平的5个技巧
  • 解码大众全新数字高尔夫8汽车CAN FD行驶功能电气架构
  • 什么是DDL、MDL?
  • 【sonar】安装sonarQube免费社区版9.9【Linux】【docker】
  • MySQL基本语法总结