本文不是科普文,主要是一些LogBack和Springboot默认使用LogBack情况下遇到的一些问题以及对应解决方案

日志级别

日志级别从低到高分为:

TRACE < DEBUG < INFO  < WARN < ERROR < FATAL

LogBack会按照高于或等于当前配置的级别进行输出;例如日志级别设置为 WARN ,则低于 WARN 的信息都不会输出。

SpringBoot中的默认使用

  1. Spring Boot中默认日志输出级别为INFO,因此只有ERROR、WARN和INFO级别的日志会输出到控制台

LogBack日志级别优先级

LogBack默认使用最小子级的日志级别,比如下面配置案例中,如果是com.lin.controller中的日志,则会按照error级别进行控制输出,如果是com.lin以外的日志内容,则按照info级别控制输出

logging:  
  level:  
    root: info  
    com.lin.controller: error  
    com.lin: debug

注意,如果设置root为debug,对于项目中实际日志不需要的且没有被限制输出的情况下,他们的debug日志也会被打印出来,例如:

image.png
对于一个正常的大型项目来讲,强烈建议不要设置root为debug。

自定义日志输出

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <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="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}}"/>

    <!-- 输出到控制台 -->
    <appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </layout>
    </appender>

    <!-- 异步输出 -->
    <appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>8</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>256</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="CONSOLE-LOG"/>
    </appender>

    <!-- 指定最基础的日志输出级别 -->
    <root level="info">
        <appender-ref ref="ASYNC-INFO" />
    </root>
</configuration>

注意事项

如果是自己自定义配置了日志输出,同时想要指定某些包下的日志级别调整,则尽量使用additivity="false",例如:

<logger name="com.lin.controller" level="debug" additivity="false">
	<appender-ref ref="CONSOLE-LOG" />
</logger>

additivity的作用在于当前logger是否使用上级logeer(一般是root logger)配置的appender进行输出。

  • false:表示只用当前logger的appender-ref。
  • true:表示当前logger的appender-ref和rootLogger的appender-ref都有效。这个是默认值。 如果当前logger设置了日志级别,但是没有设置additivity,则可能输出两次,此时需要使用additivity="false"

日志过滤

<turboFilter class="org.lin.boot.ctrl.log.LogFilter"/>
public class LogFilter extends TurboFilter {
	@Override  
	public FilterReply decide(Marker marker, ch.qos.logback.classic.Logger logger, Level level, String format, Object[] params, Throwable t) {  
		// 重写限制规则
	    return FilterReply.NEUTRAL;  
	}
}

配置加载优先级

Logback默认支持的配置文件:

@Override
protected String[] getStandardConfigLocations() {
    return new String[] { "logback-test.groovy", "logback-test.xml", "logback.groovy",
          "logback.xml" };
}

Springboot支持的配置文件:

protected String[] getSpringConfigLocations() {
    String[] locations = getStandardConfigLocations();
    for (int i = 0; i < locations.length; i++) {
       String extension = StringUtils.getFilenameExtension(locations[i]);
       locations[i] = locations[i].substring(0,
             locations[i].length() - extension.length() - 1) + "-spring."
             + extension;
    }
    return locations;
}

优先级为Logback默认配置>默认配置的前缀“-spring”.xml

logback-test.xml > logback.groovy > logback.xml > logback-spring.groovy > logback-spring.xml

原理

 logback 的初始化步骤:

  1. logback 会在类路径下寻找名为 logback-test.xml 的文件。
  2. 如果没有找到,logback 会继续寻找名为 logback.groovy 的文件。
  3. 如果没有找到,logback 会继续寻找名为 logback.xml 的文件。
  4. 如果没有找到,将会通过 JDK 提供的 ServiceLoader 工具在类路径下寻找文件 META-INFO/services/ch.qos.logback.classic.spi.Configurator,该文件的内容为实现了 Configurator 接口的实现类的全限定类名。
  5. 如果以上都没有成功,logback 会通过 BasicConfigurator 为自己进行配置,并且日志将会全部在控制台打印出来。

Springboot在上述第3步后添加步骤:如果尝试寻找名为logback.groovylogback-spring.xml的文件