一、Logback详解

如果对logback不了解,先参照以下三篇了解一下

  1. 【Logback】<configuration>标签详解
  2. 【Logback】<appender>标签详解
  3. 【Logback】<logger>、<root>标签详解

二、Spring Boot自动配置

Spring Boot默认是使用Logback的,并且提供了自动配置,以下对Spring Boot中Logback自动配置Starters的使用说明,基于Spring Boot 2.3.12.RELEASE版本

2.1、控制台输出

默认控制台输出 ERROR 、 WARN 和 INFO 级日志,可以配置来调整

  1. yml配置文件方式
debug: true
# 或者
# trace: true
  1. 启动参数

通过启动参数 --level--debug的方式来控制日志级别

java -jar myapp.jar --debug

源码: org.springframework.boot.context.logging.LoggingApplicationListener#initializeEarlyLoggingLevel

	private LogLevel springBootLogging = null;
	
	private void initializeEarlyLoggingLevel(ConfigurableEnvironment environment) {
		if (this.parseArgs && this.springBootLogging == null) {
			if (isSet(environment, "debug")) {
				this.springBootLogging = LogLevel.DEBUG;
			}
			if (isSet(environment, "trace")) {
				this.springBootLogging = LogLevel.TRACE;
			}
		}
	}

2.2、配置文件名称

默认加载名为:logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy的配置文件

在这里插入图片描述

2.3、配置文件加载顺序

Spring的加载顺序:logback.xml --> application.properties --> logback-spring.xml
注意:日志系统是在Spring上下文之前创建的,因此不能使用@PropertySource配置,建议使用 logback-spring.xml
下文会讲到<springProfile><springProperty>标签和此有关系

在这里插入图片描述

2.4、日志级别设置

语法: logging.level.<logger-name>=<level>

yml配置使用示例:

logging:
  level:
   root: warn  #root设置为warn级别
   org.springframework.web: debug  #name=org.springframework.web的logger设置为debug级别
   org.hibernate: error   #name=org.hibernate的logger设置为debug级别

2.5、日志分组

可以把<logger>分组,通过组名来统一配置<logger>的设置

2.5.1、properties使用示例

# 将org.apache.catalina、org.apache.coyote、org.apache.tomcat三个logger设为tomcat组
logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat
# 将tomcat组的日志级别设置为 TRACE
logging.level.tomcat=TRACE

# 将sql组的日志级别设置为 DEBUG
logging.level.sql=DEBUG

2.5.2、Spring Boot提供的默认分组

2.4、Spring Boot自定义日志配置

Spring 环境变量系统变量(优先级高级Spring环境变量)说明默认
logging.exception-conversion-wordLOG_EXCEPTION_CONVERSION_WORD异常日志转换字%wEx
logging.file.clean-history-on-startLOG_FILE_CLEAN_HISTORY_ON_START启动时清理归档日志false
logging.file.nameLOG_FILE日志文件名称,可以是相对路径或者绝对路径${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}
logging.file.pathLOG_PATH日志文件路径
logging.file.max-sizeLOG_FILE_MAX_SIZE日志文件最大容量(仅对logback有效)10MB
logging.file.max-history归档日志最大保留时间启动时清理归档日志7
logging.file.total-size-capLOG_FILE_TOTAL_SIZE_CAP归档日志总计最大容量0
logging.pattern.consoleCONSOLE_LOG_PATTERN控制台日志格式${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}}
logging.pattern.dateformatLOG_DATEFORMAT_PATTERNAppender日期格式yyyy-MM-dd HH:mm:ss.SSS
logging.pattern.fileFILE_LOG_PATTERN归档日志正则${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}}
logging.pattern.levelLOG_LEVEL_PATTERN日志级别%5p
logging.pattern.rolling-file-nameROLLING_FILE_NAME_PATTERN日志文件分片名称规则${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
PIDPID当前进程

默认值定义位置

  1. org.springframework.boot.logging.logback.DefaultLogbackConfiguration
  2. org\springframework\boot\spring-boot\2.3.12.RELEASE\spring-boot-2.3.12.RELEASE.jar!\org\springframework\boot\logging\logback\base.xml
  3. org\springframework\boot\spring-boot\2.3.12.RELEASE\spring-boot-2.3.12.RELEASE.jar!\org\springframework\boot\logging\logback\defaults.xml
  4. org\springframework\boot\spring-boot\2.3.12.RELEASE\spring-boot-2.3.12.RELEASE.jar!\org\springframework\boot\logging\logback\console-appender.xml
  5. org\springframework\boot\spring-boot\2.3.12.RELEASE\spring-boot-2.3.12.RELEASE.jar!\org\springframework\boot\logging\logback\file-appender.xml

注意:

xml中变量默认值按logback的语法: ${name:-value}
yml或者properties中使用默认值要按spel表达式 ${name:value},没有-

在这里插入图片描述

2.5、Spring Boot扩展xml变量引用标签

源码:org.springframework.boot.logging.logback.SpringBootJoranConfigurator

class SpringBootJoranConfigurator extends JoranConfigurator {

	private LoggingInitializationContext initializationContext;

	SpringBootJoranConfigurator(LoggingInitializationContext initializationContext) {
		this.initializationContext = initializationContext;
	}

	@Override
	public void addInstanceRules(RuleStore rs) {
		super.addInstanceRules(rs);
		Environment environment = this.initializationContext.getEnvironment();
		rs.addRule(new ElementSelector("configuration/springProperty"), new SpringPropertyAction(environment));
		rs.addRule(new ElementSelector("*/springProfile"), new SpringProfileAction(environment));
		rs.addRule(new ElementSelector("*/springProfile/*"), new NOPAction());
	}
}

2.5.1、Profile-specific Configuration使用示例

就是对spring.profiles.active的支持,支持某些配置在指定配置文件激活时才有效
示例:

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

2.5.2、Environment Properties使用示例

支持在logback-spring.xml中通过<springProperty>引用properties或者yml中的环境变量
示例:

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
        defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
    <remoteHost>${fluentHost}</remoteHost>
    ...
</appender>
属性名说明
scope变量范围
name变量名(logback-spring.xml )
sourcespring环境变量中变量名
defaultValue默认值

2.6、自定义异常日志输出

1、Spring Boot 提供了一个对异常日志转换器WhitespaceThrowableProxyConverter来自定义logback的异常处理,实现异常日志前后添加空行。
2、Seata-server的源码对Spring Boot的WhitespaceThrowableProxyConverter又做了增强,添加了 ==> <==配置

2.6.1、Spring Boot

package org.springframework.boot.logging.logback;

import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.core.CoreConstants;

/**
 * {@link ThrowableProxyConverter} that adds some additional whitespace around the stack
 * trace.
 *
 * @author Phillip Webb
 * @since 1.0.0
 */
public class WhitespaceThrowableProxyConverter extends ThrowableProxyConverter {

	@Override
	protected String throwableProxyToString(IThrowableProxy tp) {
		return CoreConstants.LINE_SEPARATOR + super.throwableProxyToString(tp) + CoreConstants.LINE_SEPARATOR;
	}

}

2.6.2、seata server

  1. 期望自定义格式:

==>

异常信息

<==

  1. 代码实现,摘自 seata-server
package com.qbhj.logback.logback;

import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.core.CoreConstants;

/**
 * 摘自 seata-server
 */
public class ExtendedWhitespaceThrowableProxyConverter extends ExtendedThrowableProxyConverter {

    @Override
    protected String throwableProxyToString(IThrowableProxy tp) {
        return "==>" + CoreConstants.LINE_SEPARATOR + super.throwableProxyToString(tp)
                + "<==" + CoreConstants.LINE_SEPARATOR + CoreConstants.LINE_SEPARATOR;
    }
}
  1. 使用
  • xml配置
<!-- The custom conversion rules -->
<conversionRule conversionWord="wEx2" converterClass="com.qbhj.logback.logback.ExtendedWhitespaceThrowableProxyConverter"/>

<!-- 引用,日志格式最后添加了%wEx2 -->
<springProperty name="FILE_LOG_PATTERN" source="logging.pattern.file" 
        defaultValue="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p --- [%30.30t] %-40.40logger{39} : %m%n%wEx2"/>
  • java
    /**
     * 自定义日志格式:异常转换
     */
    @GetMapping("/custom")
    public void customThrowableProxyConverter() {
        RuntimeException runtimeException = new RuntimeException("测试logback 异常!");
        log.error("logback自定义日志格式......", runtimeException);
    }
  1. 效果演示
14:41:29.461  INFO --- [     http-nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
14:41:29.477 ERROR --- [     http-nio-8080-exec-1] c.qbhj.logback.controller.LogController  : logback自定义日志格式......
==>
java.lang.RuntimeException: 测试logback 异常!
    at com.qbhj.logback.controller.LogController.customThrowableProxyConverter(LogController.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

  。。。。。。

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
<==

三、参考资料

https://docs.spring.io/spring-boot/docs/2.3.12.RELEASE/reference/html/spring-boot-features.html#boot-features-logging
https://gitee.com/mirrors/Seata/blob/2.x/server/src/main/java/io/seata/server/logging/logback/ExtendedWhitespaceThrowableProxyConverter.java

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐