SpringBoot日志框架如何使用

 更新时间:2021年1月26日 19:46  点击:2288

不管是开发过程中调试还是线上问题的定位追踪,日志都发挥着及其重要的作用。平时,我们会用System.out.println()打印一些信息到控制台,我们可以使用该语句输出日志,但是System.out会增加资源的消耗,所以最好使用日志框架打印日志信息。

Java中的日志框架有JCL、Jboss-logging、slf4j、logback、log4j、log4j2等等,其中JCL、Jboss-logging、slf4j属于日志门面(日志的抽象),logback、log4j、log4j2是日志框架的具体实现。阿里巴巴开发规范强制要求使用日志的门面而不要直接使用日志系统的API。

【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架(SLF4J、JCL--Jakarta Commons Logging)中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

日志门面不是日志解决方案,它只服务于各种各样的日志系统,这就允许最终用户在部署应用时可以随意使用其所希望的日志系统。也就是说如果开始使用slf4j+logback记录日志,则项目会按logback的风格打印日志,后期如果我们想更改为log4j风格的输出,则只需将logback替换为log4j即可,不需改变项目中的任何代码。

slf4j+logback也是SpringBoot中默认整合的日志框架。

如何使用

public class LoggerService {
  private static final Logger logger = LoggerFactory.getLogger(LoggerService.class);

  public void printLog() {
      logger.trace("trace日志……");
      logger.debug("debug日志……");
      logger.info("info日志……");
      logger.warn("warn日志……");
      logger.error("error日志……");
  }
}

使用LoggerFactory生成Logger对象,然后调用Logger对象的相应日志级别的方法打印即可。另外,在输出日志时,字符串的拼接要使用占位符替换不要使用append等方法。

【强制】在日志输出时,字符串变量之间的拼接使用占位符的方式。说明:因为 String 字符串的拼接会使用 StringBuilder 的 append()方式,有一定的性能损耗。使用占位符仅是替换动作,可以有效提升性能。正例:logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);

上述代码的运行效果:

2020-12-28 13:32:40.751 INFO 16016 --- [nio-8080-exec-2] c.c.e.e.service.LoggerService           : info日志……
2020-12-28 13:32:40.751 WARN 16016 --- [nio-8080-exec-2] c.c.e.e.service.LoggerService           : warn日志……
2020-12-28 13:32:40.751 ERROR 16016 --- [nio-8080-exec-2] c.c.e.e.service.LoggerService           : error日志……

从运行效果可以看出,SpringBoot默认的日志级别(trace < debug < info < warn < error)是info。

指定配置

SpringBoot日志的默认配置在org\springframework\boot\spring-boot\2.4.1\spring-boot-2.4.1.jar!\org\springframework\boot\logging\logback\defaults.xml文件中,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<!--
Default logback configuration provided for import
-->

<included>
  <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{${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}}"/>
  <property name="CONSOLE_LOG_CHARSET" value="${CONSOLE_LOG_CHARSET:-default}"/>
  <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
  <property name="FILE_LOG_CHARSET" value="${FILE_LOG_CHARSET:-default}"/>

  <logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
  <logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
  <logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
  <logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
  <logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
  <logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
  <logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
  <logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/>
</included>

里面定义了默认的日志输出格式, org\springframework\boot\spring-boot\2.4.1\spring-boot-2.4.1.jar!\org\springframework\boot\logging\logback\base.xml 文件中定义了日志默认级别。如果想要使用自定义的配置,在类路径下放上日志框架自己对应的配置文件即可,如logback对应logback-spring.xml或logback.xml,log4j2对应log4j2-spring.xml或log4j2.xml,这样Springboot便不在使用默认配置。

SpringBoot 官方建议在日志配置中使用 -spring 的配置方式(例如,使用 logback-spring.xml 而不是 logback.xml)。如果使用标准配置位置,Spring 无法完全控制日志初始化。

另外官方文档中有明确提到,JUL(ava Util Logging) 在 FATJAR 场景下存在一些已知的类加载问题,所以要尽量避免在 FATJAR 场景下使用 JUL。

使用这种命名方式日志框架就不会直接加载日志的配置,而改由SpringBoot加载,同时使用SpringBoot的高级Profile功能指定某段配置只在某个环境下生效。

<springProfile name="dev">
 <!-- 激活dev下的配置 -->
</springProfile>

<springProfile name="!production">
 <!-- 激活非production下的配置 -->
</springProfile>

示例

<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">  
 <layout class="ch.qos.logback.classic.PatternLayout">
 <!-- 该输出格式只在dev下生效 -->
 <springProfile name="dev">
  <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level    %logger{50} - %msg%n</pattern>   
 </springProfile>     
 </layout> 
</appender>

logback配置详解

logback完整配置如下

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">  
<!-- 日志文件的地址,windows和Linux下都要写绝对地址 -->
<property name="LOG_HOME" value="/home" />
<!-- 日志输出格式:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符 -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" />

<!--控制台输出 -->
<appender name="CONSOLE_OUT" class="ch.qos.logback.core.ConsoleAppender">
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <!-- 输出格式,直接引用上面定义的property -->
    <pattern>${LOG_PATTERN}</pattern>
    </encoder>
</appender>

<!--文件输出, 每天生成日志文件 -->
<appender name="FILE_OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!--日志文件名-->
    <FileNamePattern>${LOG_HOME}/XXX.log.%d{yyyy-MM-dd}.log</FileNamePattern>
    <!--日志文件保留天数,15天是阿里巴巴开发规范中的最低要求-->
    <MaxHistory>15</MaxHistory>
  </rollingPolicy>
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <!--输出格式,同上-->
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
  </encoder>
  <!--日志文件最大的大小-->
  <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
  <MaxFileSize>10MB</MaxFileSize>
  </triggeringPolicy>
</appender>

<!-- myibatis日志配置 -->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>

<!-- 日志输出级别 -->
<root level="DEBUG">
  <appender-ref ref="CONSOLE_OUT" />
  <appender-ref ref="FILE_OUT"/>
</root>

</configuration>

更换日志框架

SpringBoot中的日志实现默认是logback,假如我们要更换其他日志实现,假如要更换为Log4j2,该怎么做呢?

<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>  

<!-- 引入新实现 -->
<dependency>    
    <groupId>org.springframework.boot</groupId>    
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

总结一下就是分为两步:

移除原日志的实现,根据新使用的日志实现不同需移除的项目也有所不同,如要使用log4j则需移除以下依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
       <exclusion>
         <artifactId>logback-classic</artifactId>
         <groupId>ch.qos.logback</groupId>
       </exclusion>
       <exclusion>
         <artifactId>log4j-over-slf4j</artifactId>
         <groupId>org.slf4j</groupId>
       </exclusion>
    </exclusions>
</dependency>

引入新实现的依赖。

log4j需引入,这是一个适配层的包,其自动依赖了log4j。

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
</dependency>

log4j2需引入。

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

以上就是SpringBoot日志框架如何使用的详细内容,更多关于SpringBoot日志框架的资料请关注猪先飞其它相关文章!

[!--infotagslink--]

相关文章

  • 解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题

    这篇文章主要介绍了解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-28
  • SpringBoot实现excel文件生成和下载

    这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
  • Laravel 调试工具 laravel-debugbar 打印日志消息

    laravel-debugbar 调试工具的教程小编整理了几篇不错的教程,今天我们来看一篇Laravel 调试工具 laravel-debugbar 打印日志消息例子,希望文章对各位有帮助。 其实不...2016-11-25
  • 基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍

    这篇文章主要介绍了基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍 的相关资料,需要的朋友可以参考下...2016-05-14
  • 详解springBoot启动时找不到或无法加载主类解决办法

    这篇文章主要介绍了详解springBoot启动时找不到或无法加载主类解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16
  • SpringBoot集成Redis实现消息队列的方法

    这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
  • 解决Springboot get请求是参数过长的情况

    这篇文章主要介绍了解决Springboot get请求是参数过长的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-17
  • Spring Boot项目@RestController使用重定向redirect方式

    这篇文章主要介绍了Spring Boot项目@RestController使用重定向redirect方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-02
  • CI框架开发新浪微博登录接口源码完整版

    首先来看下流程:流程原理: 1.通过code获得access_token通过授权,并获取用户的信息(包括用户u_id)(这个u_id在后面的第三方登录表里面叫sina_id,那个表是需要自己建的) 2.查询第三方登录表,如果不存在用户sina_id,分2...2014-05-31
  • .net数据库操作框架SqlSugar的简单入门

    这篇文章主要介绍了.net数据库操作框架SqlSugar的简单入门,帮助大家更好的理解和学习使用.net技术,感兴趣的朋友可以了解下...2021-09-22
  • springBoot 项目排除数据库启动方式

    这篇文章主要介绍了springBoot 项目排除数据库启动方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-10
  • 记一次EFCore类型转换错误及解决方案

    这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
  • 对MySQL日志操作的一些基本命令总结

    MySQL日志主要包含:错误日志、查询日志、慢查询日志、事务日志、二进制日志;日志是mysql数据库的重要组成部分。日志文件中记录着mysql数据库运行期间发生的变化;也就是说用来记录mysql数据库的客户端连接状况、SQL语句...2015-11-24
  • Springboot+TCP监听服务器搭建过程图解

    这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-28
  • Powershell 查询 Windows 日志的方法

    这篇文章主要介绍了Powershell 查询 Windows 日志的方法,需要的朋友可以参考下...2020-06-30
  • SpringBoot接口接收json参数解析

    这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
  • 详解SpringBoot之访问静态资源(webapp...)

    这篇文章主要介绍了详解SpringBoot之访问静态资源(webapp...),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-14
  • springboot中使用@Transactional注解事物不生效的坑

    这篇文章主要介绍了springboot中使用@Transactional注解事物不生效的原因,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-26
  • c# 常用框架汇总

    这篇文章主要介绍了c# 常用框架汇总,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-04-24
  • springboot多模块包扫描问题的解决方法

    这篇文章主要介绍了springboot多模块包扫描问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16