Java: 动态更新Log4J2日志级别

Log4J的日志级别

下表示Log4J内置的日志级别.

标准级别数字级别
OFF0
FATAL100
ERROR200
WARN300
INFO400
DEBUG500
TRACE600
ALLInteger.MAX_VALUE

java标志
image-2871

使用Spring Boot

完整源码地址: Gitee仓库

例子中使用了Spring Boot,而在Spring Boot中,支持的日志级别为: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF .

在Spring Boot中,配置Log4J2很简单,只需要简单几步就可以完成.

当然,Spring Boot还支持其它日志系统,例如: Commons Logging(Spring Boot默认的日志系统),Logback,Log4J2,Java Util Logging.并且针对Logback,Log4J2,Java Util Logging提供了默认自动配置.

日志级别与颜色映射

在Spring Boot中,提供了日志级别与颜色映射,如下:

级别颜色
FATAL红色
ERROR红色
WARN黄色
INFO绿色
DEBUG绿色
TRACE绿色

源码

完整源码地址: Gitee仓库

如果要在Spring Boot中配置Log4J2,只需要在pom.xml中配置相关依赖即可:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</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>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.8</version>
</dependency>

这里需要排除spring-boot-starter-logging,因为默认的spring-boot-starter-logging和Log4J2会冲突.

在这里引入Lombok是因为可以自动生成Log4J2的实例,简化使用.

引入actuator是因为我们需要动态修改日志级别.

使用:

import lombok.extern.log4j.Log4j2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@SpringBootApplication
@RestController
@Log4j2
public class Log4jlevelupdatedemoApplication {


    @RequestMapping("/")
    public Map<String,String> hello(){
        log.trace("test trace");
        log.debug("test debug");
        log.warn("test warn");
        log.info("test info");
        log.error("test error");
        return Map.of("Hello","Java");
    }

    public static void main(String[] args) {
        SpringApplication.run(Log4jlevelupdatedemoApplication.class, args);
    }

}

需要注意: 每次重启服务器,日志级别都会被重置为默认级别.

操作步骤

1 . 浏览器访问: http://localhost:8080/ ,会在【控制台】输出测试日志:

2019-08-02 10:10:11.489 WARN 15340 — [nio-8080-exec-1] x.s.l.Log4jlevelupdatedemoApplication : test warn
2019-08-02 10:10:11.490 INFO 15340 — [nio-8080-exec-1] x.s.l.Log4jlevelupdatedemoApplication : test info
2019-08-02 10:10:11.490 ERROR 15340 — [nio-8080-exec-1] x.s.l.Log4jlevelupdatedemoApplication : test error

2 . 浏览器访问: http://localhost:8080/actuator/loggers ,可以看到目前的日志级别配置;

3 . 在Postman中新建一个POST请求,地址为: http://localhost:8080/actuator/loggers/ROOT , 参数为: Body -> raw -> JSON(application/json) ,内容为:

TRACE为日志级别,可选值为: TRACE, DEBUG, INFO, WARN, ERROR, FATAL,OFF.

{
“configuredLevel”: “TRACE”
}

请求之后,不会返回任何数据.再次发起[1]请求,之后即可在控制台看到修改后的数据.

实现原理

  1. 请求会抵达 [1]org.springframework.boot.actuate.logging.LoggersEndpoint 该类为loggers端点的处理类;
  2. 调用[1]类的configureLogLevel方法,在此方法中会调用当前日志系统的抽象父类(org.springframework.boot.logging.LoggingSystem),该类有多个子类,其中一个子类为:[2]org.springframework.boot.logging.log4j2.Log4J2LoggingSystem,就会取到该类;
  3. 调用[2]类中的setLogLevel方法,在此方法中,会将我们传递给Spring Boot的日志级别转换为Log4J2对应的日志级别;
  4. 如果配置对象为空的话,则会新建一个配置,反之则直接设置给当前配置;
  5. 最后调用org.apache.logging.log4j.core.LoggerContext的updateLoggers方法刷新配置.

完整源码地址: Gitee仓库

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

*

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据