一文说透日志框架发展史及springboot日志

萨瓦迪卡20小时前SpringBoot14


日志框架发展史

一位 老程序员A 根据自己工作中对日志的需求,开发并开源了log4j。后被apatch基金会收纳

jdk官方  sun 公司,    开发了一个日志框架  jul  ,也就是   java.util.logging  ;

由于市面上的日志框架非常的混乱,  一个项目  一个模块用   log4j ,   一个模块用 jul , 一个用jboss-logging.

于是jdk官方  开发了 日志门面 JCL ,   jakarta Commons Logging   JCL  ( 不实现日志功能,整合日志的);

老程序员A 发现JCL并不好用, 离开了apatch,   独自开发了日志门面  slf4j .      ( 不实现日志功能,整合日志的 需要用 适配器桥接器

apatch开发了 log4j2  ,其性能比log4j高出好多倍。于是log4j淘汰。

老程序员A   又开发了logback ,  性能比log4j2高出好多倍.

日志实现
日志门面
log4j   淘汰(个人、apatch)
JCL(jdk)
jul    java.util.logging 别的(jdk)官方
SJF4J(个人)
适配器、桥接器
log4j2          (apatch)开源

logback (个人)


log4j的作者觉得jcl不好用,自己写了一个新的接口api,那么就是slf4j。关于slf4j的集成图如下所示:


3e8ba0ff-3644-4b5d-9c99-f25c3f846541.png


Slf4j与其他各种日志组件的桥接说明
jar包名
说明
slf4j-log4j12-1.7.13.jar
Log4j1.2版本的桥接器,你需要将Log4j.jar加入Classpath。
log4j-slf4j-impl.jar
Log4j2版本的桥接器,还需要log4j-api.jar   log4j-core.jar
slf4j-jdk14-1.7.13.jar
java.util.logging的桥接器,Jdk原生日志框架。
slf4j-nop-1.7.13.jar
NOP桥接器,默默丢弃一切日志。
slf4j-simple-1.7.13.jar
一个简单实现的桥接器,该实现输出所有事件到System.err. 只有Info以及高于该级别的消息被打印,在小型应用中它也许是有用的。
slf4j-jcl-1.7.13.jar
Jakarta Commons Logging 的桥接器. 这个桥接器将Slf4j所有日志委派给Jcl。
logback-classic-1.0.13.jar(requires logback-core-1.0.13.jar)
Slf4j的原生实现,Logback直接实现了Slf4j的接口,因此使用Slf4j与Logback的结合使用也意味更小的内存与计算开销

所以最佳组合是slf4j 和logback,因为作者是一个。

那么如果使用slf4j(门面)+Log4j(实现)  :必须加桥接器

引入slf4j依赖:
<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactld>
</dependency>

<dependency)
    <!--添加s1f4j一log4j的桥接器
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
</dependency>
import org.slf4j.Logger;
     // slf4j(门面),不是具体的日志实现获得Logger日志记录器
     //Logger logger = Logger.getLogger(Test.class);
     //而是 门面日志器接受
      Logger logger = LoggerFactory.getLogger(Test.class);
     logger.info("info");


如果是Jul(实现) +JCl(门面)

<!--引入JCL门面依赖-->
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
\\LogFactory
Log log = LogFactory.getLog(Test.class);
log.trace('trace');


这个Log具体的实现类,JCL会在ClassLoader中进行查找。这么做,有三个缺点,缺点一是效率较低,二是容易引发混乱,三是在使用了自定义ClassLoader的程序中,使用JCL会引发内存泄露。

JCL动态查找机制进行日志实例化,执行顺序为:commons-logging.properties---->系统环境变量------->log4j--->jul--->simplelog---->nooplog


将以上两个小组使用的两个个门面统一:只需要添加一个适配器。将jcl或者jul转成slf4j.  添加适配器

   <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>jcl-over-slf4j</artifactId>
         <version></version>
   </dependency>


spring默认整合了:logback日志的集成

74e36c00-3ad1-44ac-b19f-a8a1fdf77804.png

logback跟log4j,跟slf4j都出自同一个作者,所以最佳实现方式就是slf4j+logback
总结:
  1. SpringBoot底层也是使用slf4j+logback的方式进行日志记录

使用了logback与slf4j的桥接器:logback-classic
  1. SpringBoot也把其他的日志都替换成了slf4j;

    1. log4j 适配: log4j-to-slf4j     (将log4j转成slf4)

    2. jul适配:jul-to-slf4j  (将jul转成slf4)

    3. 这两个适配器都是为了适配Spring的默认日志:jcl


SpringBoot日志使用

  • 日志级别

TRACE,DEBUG,INFO,WARN,ERROR,FATAL或OFF,等级依次升高
springboot默认info级别(那么大于info的级别才会起作用)。可设置日志等级
logging:
  level:
    root: "warn"
    org.springframework.web: "debug"
    com.lingling: "error"   //包下日志等级设置
  • 日志格式

2025-12-01 14:01:34.665 TRACE 10072 --- [           main] com.ruoyi.Application            : 跟踪
2025-12-01 14:01:34.665 DEBUG 10072 --- [           main] com.ruoyi.Application            : 调试
2025-12-01 14:01:34.665  INFO 10072 --- [           main] com.ruoyi.Application            : 信息
2025-12-01 14:01:34.665  WARN 10072 --- [           main] com.ruoyi.Application            : 警告
2025-12-01 14:01:34.665 ERROR 10072 --- [           main] com.ruoyi.Application            : 异常
详细介绍
可以使用logging.pattern.console 修改默认的控制的日志格式:
%clr(%d{${LOG_DATEFORMAT_PATTERN:-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}
  • 2025-12-01 14:01:34.665

    • 日期和时间:毫秒精度,易于排序。

    • %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint}

      • %clr  当前内容的颜色   {faint}  

    • (%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}})

      • 括号中就是要显示的内容

    • %d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}

      • ${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}

        • ${value:value2}  springboot的占位符 + null条件的表达式(如果value为null 使用value2)

        • LOG_DATEFORMAT_PATTERN:  系统环境变量中的值, springboot底层会根据对应的配置项将值设置到对应的环境变量中

          • 如:LOG_DATEFORMAT_PATTERN=logging.pattern.dateformat  可以在官网4.7章节中看到对应的关系。或者去源码中看

    • %d{-yyyy-MM-dd HH:mm:ss.SSS}

      • %d   logbak的日期显示方式:

      • {-yyyy-MM-dd HH:mm:ss.SSS}    日期的格式

  • TRACE

    • 日志级别:ERROR,WARN,INFO,DEBUG,或TRACE。

    • %clr(${LOG_LEVEL_PATTERN:-%5p})

    • %clr 颜色  会根据不同的日志级别输出对应的颜色

    • ${LOG_LEVEL_PATTERN:-%5p}

    • %5  代表当前内容所占字符长度

    • p 输出日志事件的级别。

  • 10072

    • 进程ID。

    • %clr(${PID:- }){magenta}

    • %clr   {magenta}

    • ${PID:- }   springboot的占位符 + null条件的表达式(如果value为null 使用value2)

    • PID 是系统环境变量中的进程ID(由系统分配)

  • ---

    • 一个---分离器来区分实际日志消息的开始。

  • [           main]

    • 线程名称:用方括号括起来(对于控制台输出可能会被截断)。

  • com.ruoyi.Application

    • 记录日志的类

  • : 跟踪

    • 日志消息。



  • 文件输出


默认情况下,Spring Boot仅记录到控制台,不写日志文件。如果除了控制台输出外还想写日志文件,则需要设置一个logging.file.namelogging.file.path属性(例如,在中application.properties)。
下表显示了如何logging.*一起使用这些属性:
logging.file.name
logging.file.path
实例
描述
(没有)
(没有)

仅控制台记录。
指定文件名
(没有)
my.log
写入指定的日志文件。
(没有)
具体目录
/var/log
写入spring.log指定的目录。
  • logging.file.name

    • 可以设置文件的名称, 如果没有设置路径会默认在项目的相对路径下(项目的根目录下)

    • 还可以指定路径+文件名:name: D:/sawadika.log

  • logging.file.path

    • 不可以指定文件名称, 必须要指定一个物理文件夹路径,会默认使用spring.log


  • 日志迭代(轮转):比如日志文件超出了设定的大小,归档。并保留天数后可删除

如果使用的是Logback,可以使用application.propertiesapplication.yaml文件微调日志轮播设置。对于所有其他日志记录系统,您需要直接自己配置轮转设置(例如,如果使用Log4J2,则可以添加log4j.xml文件)。
名称
描述
logging.logback.rollingpolicy.file-name-pattern
归档的文件名
logging.logback.rollingpolicy.clean-history-on-start
如果应在应用程序启动时进行日志归档清理。
logging.logback.rollingpolicy.max-file-size
归档前日志文件的最大大小。
logging.logback.rollingpolicy.total-size-cap
删除日志档案之前可以使用的最大大小。
logging.logback.rollingpolicy.max-history
保留日志存档的天数(默认为7)


如果想要使用logback的高级功能,比如:发送文件、存入数据库等。就必须单独使用logBack的配置文件 比如:logback.xml.也就是自定义配置文件
注意:
  • 如果使用自定义日志配置文件, 会使用springboot中全局配置文件里的logging相关配置失效。

  • 结合SpringBoot提供Profile来控制日志的生效

    • 注意:如果要使用 springProfile ,一定要将日志配置文件的文件名改成logback-spring.xml,  因为 logback.xml 会在Springboot容器加载前先被logback给加载到, 那么由于logback无法解析springProfile 将会报错:

    • ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

<configuration>
      <!--还可以引用SpringBoot全局配置文件中的配置项-->
    <springProperty scope="context" name="dateformat" source="logging.pattern.dateformat" defaultValue="yyyy-MM-dd HH:mm:ss.SS"
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 使用springProfile激活dev的配置 -->
            <springProfile name="dev">
                <pattern>%d{${dateformat}}} [%thread] %-5level %logger{100} ======= %msg%n</pattern>
            </springProfile>
            <!-- 如果不是dev 走这里 -->
            <springProfile name="!dev">
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{100} ++++++ %msg%n</pattern>
            </springProfile>
    
        </encoder>
    </appender>
</configuration>
  • 切换日志框架

  • 将 logback切换成log4j2

  1. 将logback的场景启动器排除(slf4j只能运行有1个桥接器.)

  2. 添加log4j2的场景启动器

  3. 添加log4j2的配置文件

<dependencies>
    <dependency>
        <!--starter-web里面自动添加starter-logging 也就是logback的依赖-->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <!--排除starter-logging 也就是logback的依赖-->
            <exclusion>
                <artifactId>spring-boot-starter-logging</artifactId>
                <groupId>org.springframework.boot</groupId>
            </exclusion>
        </exclusions>
    </dependency>

    <!--Log4j2的场景启动器-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
</dependencies>
  • 将 logback切换成log4j  

  1. 要将logback 与slf4j的桥接器排除

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>logback-classic</artifactId>
            <groupId>ch.qos.logback</groupId>
        </exclusion>
    </exclusions>
</dependency>
  1. 添加log4j的桥接器

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
</dependency>
  1. 添加log4j的配置文件

log4j.properties
#trace<debug<info<warn<error<fatal
log4j.rootLogger=trace, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n


    本文原创,转载必追究版权。

    分享给朋友:

    相关文章

    linux系统宝塔发布Springboot项目

    linux系统宝塔发布Springboot项目

    一.首先解析一个域名 指向服务器地址。在宝塔控制面板中,点击 添加站点,这里用的是域名,未绑定域名的同学也可以使用服务器的公网 ip。添加站点后 会自动在 /www/wwwroot/  目录...

    酸爽!IDEA 中这么玩 MyBatis,让编码速度飞起!

    酸爽!IDEA 中这么玩 MyBatis,让编码速度飞起!

    1. 搭建 MyBatis Generator 插件环境a. 添加插件依赖 pom.xmlb. 配置文件 generatorConfig.xmlc. 数据库配置文件 jdbc.propertiesd....

    thymeleaf 判断select 下拉框 赋值并选中

    下拉框赋值选中:   <div class="form-group">     &nb...

    springboot框架 后台获取微信小程序用户的openid

    小程序端app.js中:// 登录     wx.login({       succ...

    idea 如何运行vue项目

    idea 如何运行vue项目

    这里以RuoYi-Vue项目为例,开源地址1.环境准备JDK >= 1.8 (推荐1.8版本) Mysql >= 5.7.0 ...

    java实现根据ip定位地理位置(调用百度接口)

    这里用的是若依的springboot框架,框架里自带的获取地理位置接口是调用的淘宝的,已经不可用。于是找到哦百度接口实现。调用百度接口:http://api.map.baidu.com/locatio...

    发表评论

    访客

    ◎欢迎参与讨论,请在这里发表您的看法和观点。