开心一刻

一大早,她就发消息质问我

她:你给我老实交代,昨晚去哪鬼混了?

我:没有,就哥几个喝了点酒

她:那我给你打了那么多视频,为什么不接?

我:不太方便呀

她:我不信,和你哥们儿喝酒有啥不方便接视频的?

她:你肯定有别的女人了!

我:你老公就坐在我旁边,我敢接?

前情回顾

SpringBoot2.7还是任性的,就是不支持Logback1.3,你能奈他何 讲了很多,总结下来就两点

  1. SpringBoot 2.7.x 默认依赖 Logback 1.2.x,不支持 Logback 1.3.x

    如果强行将 Logback 升级到 1.3.x,启动会报异常

    Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:304)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:118)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationStartingEvent(LoggingApplicationListener.java:238)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:220)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:145)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133)
    at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:79)
    at org.springframework.boot.SpringApplicationRunListeners.lambda$starting$0(SpringApplicationRunListeners.java:56)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
    at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:56)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:299)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289)
    at com.qsl.Application.main(Application.java:15)
    Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 17 more

    原因也分析过了

    spring-boot-2.7.18 依赖 org.slf4j.impl.StaticLoggerBinder,而 logback 1.3.x 没有该类

  2. SpringBoot 2.7.x 支持 Logback 1.3.x 也不是没办法,但有一些限制,同时也存在一些未知的风险

    关于未知的风险,相信大家都能理解,为什么了,这就好比从 JDK8 升级到 JDK 11,你们为什么不敢升,一个道理,因为大版本的升级,变动点往往比较多,甚至会移除掉低版本的一些内容,编译期报错还算直观的(我们可以根据报错调整代码),如果是运行期报错那就头疼了,上了生产就算事故了,这锅你敢背吗?
    所以大版本的升级,意味着我们不但要修复编译期的错,还要进行全方位的测试,尽可能的覆盖所有场景,以排除运行期可能存在的任何异常。业务简单还好,如果业务非常庞大,这个全量测试是要花大量时间的,不仅开发会口吐芬芳,测试也会 mmp
    Upgrade to SLF4J 2.0 and Logback 1.4 进行了一些讨论,wilkinsona(Spring Boot 目前 Contributor 榜一)就提到了一些风险点

    里面讨论了很多,Logback 的 Contributor 榜一大哥 ceki 也在里面进行了很多说明与答疑,感兴趣的可以详细看看
    总之就是:通过调整配置,SpringBoot 2.7.x 可以支持 Logback 1.3.x,但风险需要我们自己承担

换个角度想想,我们应该是能理解 Spring Boot 官方的

  1. Logback 不是那么熟,只能通过 Logback 官方说明知道变动点(能保证事无巨细列全了?),若变动点太多,不可能每个点都去核实
  2. Spring Boot 那么庞大,集成了那么多功能,怕是榜一大哥也不能熟记所有细节(我们敢保证对我们负责的项目的所有细节都了如指掌吗),所以也没法评估升级到 Logback 1.3.x 会有哪些点受影响

所以求稳,Spring Boot 2.x.x 不打算集成 Logback 1.3.x
但是,如果我们也任性一回,非要强扭这个瓜,Spring Boot 是不是也不能奈我们何?

霸王硬上弓

参考这个,我们来配置下

  1. 关闭 Spring BootLoggingSystem

    @SpringBootApplication
    public class Application { public static void main(String[] args) {
    System.setProperty("org.springframework.boot.logging.LoggingSystem", "none");
    SpringApplication.run(Application.class, args);
    }
    }
  2. 配置文件用 logback.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <property name="LOG_FILE" value="/logs/spring-boot-2_7_18.log"/>
    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS}|%level|%t|%line|%-40.40logger{39}:%msg%n"/> <!-- 按照每天生成日志文件-->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>${FILE_LOG_PATTERN}</pattern>
    </encoder>
    <file>${LOG_FILE}</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.zip</fileNamePattern>
    <maxHistory>30</maxHistory>
    </rollingPolicy>
    </appender> <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
    <pattern>${FILE_LOG_PATTERN}}</pattern>
    </encoder>
    </appender> <root level="${loglevel:-INFO}">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="FILE" />
    </root>
    </configuration>

启动确实正常了,我们加点简单的业务日志,发现日志也输出正常

2024-07-26 16:46:48.609|INFO|http-nio-8080-exec-1|525|o.s.web.servlet.DispatcherServlet       :Initializing Servlet 'dispatcherServlet'
2024-07-26 16:46:48.610|INFO|http-nio-8080-exec-1|547|o.s.web.servlet.DispatcherServlet :Completed initialization in 0 ms
2024-07-26 16:46:48.632|INFO|http-nio-8080-exec-1|23|com.qsl.web.TestWeb :hello接口入参:青石路
2024-07-26 16:46:50.033|INFO|http-nio-8080-exec-3|23|com.qsl.web.TestWeb :hello接口入参:青石路
2024-07-26 16:46:50.612|INFO|http-nio-8080-exec-4|23|com.qsl.web.TestWeb :hello接口入参:青石路
2024-07-26 16:46:51.150|INFO|http-nio-8080-exec-5|23|com.qsl.web.TestWeb :hello接口入参:青石路
2024-07-26 16:46:51.698|INFO|http-nio-8080-exec-6|23|com.qsl.web.TestWeb :hello接口入参:青石路
2024-07-26 16:46:52.203|INFO|http-nio-8080-exec-7|23|com.qsl.web.TestWeb :hello接口入参:青石路

日志文件写入也正常

这不仅解渴,还很甜呀

但不要甜的太早,这仅仅只是一个 demospring-boot-2_7_18,没有业务代码,简单的不能再简单了,你们要是以此来判断甜与不甜,那就大错特错了;应用到项目中,不但要保证能够正常启动,还要保证已有的所有业务能够正常运行,至于计划中的业务,那就将来再说,谁知道明天和意外哪个先来,认真过好当下!
初步尝试,是可行的,所以你们大胆的去试吧,但要做好全方位的业务测试

wilkinsona 提到了,关闭 Spring BootLoggingSystem 后,用的是 Logback 的默认配置,配置文件必须是 logback.xml 而不能是 logback-spring.xml;虽然榜一大哥的话很权威,但我们主打一个任性,就想来试试 logback-spring.xml,会有什么样的结果,直接将 logback.xml 改名成 logback-spring.xml,能启动起来,但有一堆 debug 日志,重点是

日志没有写入文件

wilkinsona 诚不欺我!

原理分析

关闭了 Spring BootLoggingSystem 后,日志相关的全权交给 Logback,而关于 Logback 的配置文件加载,我是写过一篇详解的:从源码来理解slf4j的绑定,以及logback对配置文件的加载,直接跳到总结部分,有这么一段

编译期间,完成slf4j的绑定以及logback配置文件的加载。slf4j会在classpath中寻找org/slf4j/impl/StaticLoggerBinder.class(会在具体的日志框架如log4j、logback等中存在),找到并完成绑定;同时,logback也会在classpath中寻找配置文件,先找logback.configurationFile、没有则找logback.groovy,若logback.groovy也没有,则找logback-test.xml,若logback-test.xml还是没有,则找logback.xml,若连logback.xml也没有,那么说明没有配置logback的配置文件,那么logback则会启用默认的配置(日志信息只会打印在控制台)

虽说 Logback1.1.17,而不是 1.3.14,但对配置文件的加载应该是没变的

大家注意看我的措辞:应该,这样即使变了,你们也不能说我,因为我说的是应该

保险起见,你们应该去看下 1.3.14 的源码!

这也是为什么配置文件是 logback.xml 的时候,日志能正常写入文件,而是 logback-spring.xml 时候,日志不能写入日志文件的原因,因为 Logback 不认 logback-spring.xmlSpring Boot 才认!
至于 Spring Boot LoggingSystem 嘛,等我掌握了再来和你们聊,一定要等我哟

总结

Spring Boot 2.x.x 默认依赖 Logback 1.2.x,不支持 Logback 1.3.x,但是通过设置

System.setProperty("org.springframework.boot.logging.LoggingSystem", "none");

启动时不报错的,再结合 logback.xml,日志是能够正常写入日志文件的;但是保险起见,还是不推荐升级到 Logback 1.3.x

能不动就不要动,改好没绩效,改出问题要背锅,吃力不讨好,又不是不能跑

如果一定要升级,那就做好全量测试,把所有业务场景都覆盖到

SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴的更多相关文章

  1. iPhone8、Note8、Mate10硬上面部识别:是潮流还是无奈

    ​ 对于手机厂商来说,时不时抛出几个全新概念当噱头来引起业界和大众的关注,已经成为了必然套路.其中有很多改变智能手机发展进程的技术--双摄像头.指纹识别.快充等,但也有很多纯粹来凑数,看似新潮却始终没 ...

  2. SpringBoot2.0(三) 文件上传

    SpringBoot中发起文件上传示例: /** * 文件上传 * @param multipartFile * @param path * @return */ @RequestMapping(va ...

  3. SpringBoot2.x设置文件上传文件的大小

    The field file exceeds its maximum permitted size of 1048576 bytes spring: # 设置文件上传文件大小 servlet: mul ...

  4. 【转】成功在AMD主机上用虚拟机安装原版雪豹

    转载地址:http://www.jzh.me/archives/205.html/comment-page-1 一直都很想安装苹果的系统,当雪豹出来的时候就更加想了,但是自己的机器是AMD的,而且还是 ...

  5. Python之路,Day7 - Python基础7 面向对象

    本节内容:   面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法.     引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战> ...

  6. Python之路第一课Day6--随堂笔记(面向对象 )

    本节内容: 1. 面向对象编程介绍 2. 为什么要用面向对象进行开发? 3. 面向对象的特性:封装.继承.多态 4. 类.方法   一.面向过程 VS 面向对象  1. 编程范式 编程是 程序 员 用 ...

  7. EF7 Code First Only-所引发的一些“臆想”

    At TechEd North America we were excited to announce our plans for EF7, and even demo some very early ...

  8. python之面向对象与构造函数

    一.面向对象介绍 不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路, 大多数语言只支持一种编程范式, 当然也有些语言可以同时支持多种编程范式. 两种最重要的编程范式分别是面向过程编程 ...

  9. Java类WebServer及中间件拿webshell方法总结

    0.序 原文名称:Tomcat.Weblogic.JBoss.GlassFish.Resin.Websphere弱口令及拿webshell方法总结 原文from:http://www.hack80.c ...

  10. python走起之第六话

    面向过程 VS 面向对象 编程范式 编程是 程序 员 用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 , 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大 ...

随机推荐

  1. H5图片预览

    官方链接下载示例项目需要注册账号,似乎有点不友好,不想注册账号的可以去gitee上下载示例项目 如果你上来就是把previewImg.js 放在head中可能会出现意想不到的错误,比如下面这样子,遇到 ...

  2. js字符串类型

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  3. react 属性绑定动态值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. kettle从入门到精通 第三十九课 kettle 增量同步(日级)

    1.上一课我们学习了在数据量大的情况下的分页全量同步示例,本次我们一起学习下kettle 增量全量同步.有些业务场景不需要实时数据,比如统计t-1日的销售业绩情况等.   2.kettle增量全量同步 ...

  5. MS SQL SERVER 创建表、索引、添加字段等常用脚本

    创建表: if not exists ( select 1 from sysobjects where id=object_id('PayChannelNm') ) create table [dbo ...

  6. 思迅Pay PC ,WIN7 ,KB3042058

    思迅Pay PC ,WIN7, COM , 串口 . 577,驱动. WIN7 SHA256补丁,KB3033929,https://www.microsoft.com/zh-CN/download/ ...

  7. Scrapy框架(十)--增量式爬虫

    增量式爬虫 - 概念:监测网站数据更新的情况,只会爬取网站最新更新出来的数据. - 分析: - 指定一个起始url - 基于CrawlSpider获取其他页码链接 - 基于Rule将其他页码链接进行请 ...

  8. spring使用jdk17运行出现编码问题

    遇到一个比较奇怪的问题. 这个问题别人也遇到过. https://blog.csdn.net/gao_chuan_g/article/details/115117712 一.情况简介 使用jdk17+ ...

  9. 什么是spring,它能够做什么?

    1.什么是SpringSpring是一个开源框架,它由Rod Johnson创建.它是为了解决企业应用开发的复杂性而创建的. Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情. ...

  10. Linux 内核:设备树(3)把device_node转换成platfrom_device

    Linux 内核:设备树(3)把device_node转换成platfrom_device 背景 在上一节中讲到设备树dtb文件中的各个节点转换成device_node的过程(<dtb转换成de ...