不管是开发过程中调试还是线上问题的定位追踪,日志都发挥着及其重要的作用。平时,我们会用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 configura<p>本文来源gao!daima.com搞$代!码#网#</p>tion 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>