動(dòng)態(tài)設(shè)置 log4j2 日志的級(jí)別不能落
上篇[ SpringBoot 動(dòng)態(tài)設(shè)置 logback 日志的級(jí)別 ] 說(shuō)了 logback 動(dòng)態(tài)設(shè)置日志級(jí)別。這篇來(lái)說(shuō)下 log4j2 日志框架結(jié)合 SpringBoot 動(dòng)態(tài)設(shè)置日志級(jí)別。因?yàn)?log4j2 日志框架也有非常多的公司采用,畢竟 logback 和 log4j2 是現(xiàn)在用的最多的兩個(gè)日志框架。都不能落對(duì)吧。
0x01:pom.xml 引入依賴(lài)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.olive</groupId>
<artifactId>valid-log4j2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath />
</parent>
<name>valid-demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions><!-- 去掉springboot默認(rèn)配置 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <!-- 引入log4j2依賴(lài) -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
</project>
因?yàn)?SpringBoot 默認(rèn)使用 logback 記錄日志。所以要排查 logback 日志框架 spring-boot-starter-logging,在引入 log4j2 日志框架 spring-boot-starter-log4j2。
0x02:Controller 控制器編寫(xiě)
Controller 基本框架
package com.olive.controller;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoggerController {
private final static Logger logger = LoggerFactory.getLogger(LoggerController.class);
// TODO
}
打印各級(jí)別日志
@RequestMapping("/logger/print")
public Map loggerPrint(){
Map result = new HashMap();
result.put("code", 200);
result.put("msg", "success");
logger.debug("loggerPrint debug>>>>");
logger.info("loggerPrint info>>>>");
logger.warn("loggerPrint warn>>>>");
logger.error("loggerPrint error>>>>");
return result;
}
打印所有日志對(duì)象
@RequestMapping("/logger/printAllLogger")
public Map printAllLogger(){
Map result = new HashMap();
result.put("code", 200);
result.put("msg", "success");
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
Map<String, LoggerConfig> loggerConfigs = config.getLoggers();
System.out.println("printAllLogger begin>>>>>>>>");
loggerConfigs.forEach((name, loggerConfig) -> {
System.out.println("name = " + name);
System.out.println("loggerConfig = " + loggerConfig);
});
System.out.println("printAllLogger end>>>>>>>>");
return result;
}
動(dòng)態(tài)設(shè)置日志對(duì)象的日志級(jí)別
@RequestMapping("/logger/level")
public Map loggerLevelChange(String level){
Map result = new HashMap();
result.put("code", 200);
result.put("msg", "success");
String loggerFactoryClassStr = StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr();
System.out.println("loggerFactoryClassStr>>>>" + loggerFactoryClassStr);
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
switch (level) {
case "debug":
loggerConfig.setLevel(Level.DEBUG);
break;
case "info":
loggerConfig.setLevel(Level.INFO);
break;
case "warn":
loggerConfig.setLevel(Level.WARN);
break;
case "error":
loggerConfig.setLevel(Level.ERROR);
break;
default:
break;
}
ctx.updateLoggers();
return result;
}
0x04:log4j2-spring.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration后面的status,這個(gè)用于設(shè)置log4j2自身內(nèi)部的信息輸出,可以不設(shè)置,當(dāng)設(shè)置成trace時(shí),你會(huì)看到log4j2內(nèi)部各種詳細(xì)輸出-->
<!--monitorInterval:Log4j能夠自動(dòng)檢測(cè)修改配置 文件和重新配置本身,設(shè)置間隔秒數(shù)-->
<configuration monitorInterval="5">
<!--日志級(jí)別以及優(yōu)先級(jí)排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--變量配置-->
<Properties>
<!-- 格式化輸出:%date表示日期,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度 %msg:日志消息,%n是換行符-->
<!-- %logger{36} 表示 Logger 名字最長(zhǎng)36個(gè)字符 -->
<property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
</Properties>
<appenders>
<console name="ConsoleOut" target="SYSTEM_OUT">
<!--輸出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}"/>
<!--控制臺(tái)只輸出level及其以上級(jí)別的信息(onMatch),其他的直接拒絕(onMismatch)-->
<!-- <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> -->
</console>
</appenders>
<loggers>
<root level="debug">
<appender-ref ref="ConsoleOut"/>
</root>
</loggers>
</configuration>
這里只配置了打印到控制臺(tái)的 ROOT logger。
0x05:編寫(xiě)引導(dǎo)類(lèi)
@SpringBootApplication
public class Application
{
public static void main( String[] args )
{
SpringApplication.run(Application.class, args);
}
}
啟動(dòng)服務(wù)
打印各級(jí)別日志

因?yàn)?nbsp;log4j2-spring.xml 配置的級(jí)別是 debug,所以可以在控制臺(tái)看到如下打印
21:08:52.298 [http-nio-8080-exec-1] DEBUG com.olive.controller.LoggerController - loggerPrint debug>>>>
21:08:52.298 [http-nio-8080-exec-1] INFO com.olive.controller.LoggerController - loggerPrint info>>>>
21:08:52.298 [http-nio-8080-exec-1] WARN com.olive.controller.LoggerController - loggerPrint warn>>>>
21:08:52.298 [http-nio-8080-exec-1] ERROR com.olive.controller.LoggerController - loggerPrint error>>>>
打印所有日志對(duì)象

在控制臺(tái)只看見(jiàn)打印了 ROOT logger 對(duì)象。
printAllLogger begin>>>>>>>>
name =
loggerConfig = root
printAllLogger end>>>>>>>>
動(dòng)態(tài)修改日志的級(jí)別

再次調(diào)用 http://127.0.0.1:8080/logger/print 接口打印日志,在控制臺(tái)看到不在打印 debug 級(jí)別日志
21:19:25.756 [http-nio-8080-exec-6] INFO com.olive.controller.LoggerController - loggerPrint info>>>>
21:19:25.756 [http-nio-8080-exec-6] WARN com.olive.controller.LoggerController - loggerPrint warn>>>>
21:19:25.756 [http-nio-8080-exec-6] ERROR com.olive.controller.LoggerController - loggerPrint error>>>>
修改 log4j2-spring.xml 配置
<loggers>
<root level="debug">
<appender-ref ref="Console"/>
</root>
<logger name="org.springframework" level="info" additivity="true">
</logger>
<logger name="org.hibernate" level="warn" additivity="true">
</logger>
</loggers>
重啟服務(wù),再次調(diào)用 http://127.0.0.1:8080/logger/printAllLogger 接口打印日志對(duì)象
printAllLogger begin>>>>>>>>
name =
loggerConfig = root
name = org.springframework
loggerConfig = org.springframework
name = org.hibernate
loggerConfig = org.hibernate
printAllLogger end>>>>>>>>
喜歡,在看
