> 文章列表 > 使用代码动态进行 Log4j2 的日志配置

使用代码动态进行 Log4j2 的日志配置

使用代码动态进行 Log4j2 的日志配置

文章目录

  • 小结
  • Log4j 2 XML 文件配置
  • 程序加载log4j2.xml配置文件
  • 使用代码动态进行 Log4j2 的日志配置
  • 测试
  • 参考

小结

本文记录如何使用代码动态进行 Log4j2 的日志配置。

Log4j 2 XML 文件配置

使用Log4j 2 XML 文件配置比较简单,大家都能耳熟能详,这里仅提供我使用的一个示例。注意:<Loggers>一定要配好,否则相应的日志文件无法送达指定目的地。如果没有配置<Root>,log4j2会动生成一个。

<?xml version="1.0" encoding="UTF-8"?>
<!--Log output priority: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<Configuration status="WARN"><Properties><Property name="basePath">logs</Property></Properties><Appenders><!-- 输出到Console --><console name="Console" target="SYSTEM_OUT"><PatternLayout pattern=%d %p %c{1.} [%t] %m%n"/></console><!-- 输出到滚动更新文件 --><RollingFile name="testAppender"fileName="logs/application.log"filePattern="logs/application.log.%d{MMddyyyy}"><PatternLayout><pattern>%-5level %d{yyyy-MM-dd HH:mm:ss,SSS} [%t] - %msg%n</pattern></PatternLayout><!-- 日志大小达到1MB就生成新的日志文件,按以前的格式命名旧日志文件--><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true"/><SizeBasedTriggeringPolicy size="1MB"/></Policies><!-- 最多存档100个文件--><DefaultRolloverStrategy max="100"/></RollingFile></Appenders><!-- 指示相应的类的日志发送到不同的目的地--><Loggers><Root level="error" additivity="false"><AppenderRef ref="Console"/></Root><Logger name="aa.bb.cc.dd" level="debug" additivity="false"> <AppenderRef ref="Console" level="debug"/><AppenderRef ref="testAppender" level="debug"/></Logger>    <Logger name="ee.ff.gg.hh" level="debug" additivity="false"> <AppenderRef ref="Console" level="debug"/><AppenderRef ref="testAppender" level="debug"/></Logger></Loggers>
</Configuration>

程序加载log4j2.xml配置文件

程序加载log4j2.xml配置文件有好几种方法,以下是比较简单实现的一种供参考:

import org.apache.logging.log4j.core.LoggerContext;LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
File file = new File("path/to/a/different/log4j2.xml");// this will force a reconfiguration
context.setConfigLocation(file.toURI());

使用代码动态进行 Log4j2 的日志配置

废话不多说,直接上代码,以下代码基本上实现了与以上·log4j2.xml·配置文件同样的效果:

 final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);final Configuration config = ctx.getConfiguration();final PatternLayout layout = PatternLayout.newBuilder().withCharset(Charset.forName("UTF-8")).withConfiguration(config).withPattern("%d %p %c{1.} [%t] %m%n).build();final Appender appender = ConsoleAppender.newBuilder().withName("Console").withImmediateFlush(true).withLayout(layout).build();appender.start();config.addAppender(appender);final TriggeringPolicy policy1 = TimeBasedTriggeringPolicy.newBuilder().withModulate(true).withInterval(1).build();final TriggeringPolicy policy2 = SizeBasedTriggeringPolicy.createPolicy("1MB");Appender testAppender = RollingFileAppender.newBuilder().withName("testAppender").withImmediateFlush(true).withFileName("logs/application.log").withFilePattern("log/application.log.%d{MMddyyyy}").withLayout(layout).withPolicy(policy1).withPolicy(policy2).build();testAppender.start();config.addAppender(testAppender);AppenderRef ref1 = AppenderRef.createAppenderRef("Console", null, null);AppenderRef ref2 = AppenderRef.createAppenderRef("testAppender", null, null);AppenderRef[] refs = new AppenderRef[]{ref1, ref2};LoggerConfig loggerConfig1 = LoggerConfig.createLogger(false, Level.DEBUG, "aa.bb.cc.dd","true", refs, null, config, null);LoggerConfig loggerConfig2 = LoggerConfig.createLogger(false, Level.DEBUG, "ee.ff.gg.hh","true", refs, null, config, null);loggerConfig1.addAppender(appender, null, null);loggerConfig1.addAppender(testAppender, null, null);loggerConfig2.addAppender(appender, null, null);loggerConfig2.addAppender(testAppender, null, null);config.addLogger("aa.bb.cc.dd", loggerConfig1);config.addLogger("ee.ff.gg.hh", loggerConfig2);ctx.updateLoggers();

测试

测试以下代码:

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
...
省略
...
private static final Logger log = LogManager.getLogger(testApplication.class);log.debug("This is debug");
log.warn("This is warning");
log.info("This is info");
log.trace("This is trace");
log.error("This is error");
log.fatal("This is fatal");

有以下输出,也就是除了trace没有输出外,其它的都输出了,因为日志级别设定为了Debug, 同时输出到Console和在默认目录logs下的application.log日志文件

5528 [main] DEBUG aa.bb.cc.dd.testApplication [] - This is debug
5539 [main] WARN  caa.bb.cc.dd.testApplication [] - This is warning
5539 [main] INFO  aa.bb.cc.dd.testApplication [] - This is info
11257 [main] ERROR aa.bb.cc.dd.testApplication [] - This is error
11257 [main] FATAL aa.bb.cc.dd.testApplication [] - This is fatal

参考

Log4j-apache.org: Migrating from Log4j 1.x to 2.x
Log4j-apache.org: Programmatic Configuration
stackoverflow: Log4J 1.2 PropertyConfigurator -> Log4J2
Log4j-apache.org: XML configuration
Log4j-apache.org: Layouts
https://logging.apache.org/log4j/2.x/log4j-core/Class LoggerConfig
juejin.cn: Log4j2.xml 配置文件详解
toutiao.io: 天呐!一个简单的统一日志格式我踩了多少坑
CSDN: log4j2使用filter过滤日志
stackoverflow: Loading log4j2.xml or properties configuration file during runtime by specifying path  
How to load log4j2 xml file programmatically ?
gitee: log4j2
Log4j2 - 动态生成Appender
使用代码更新 Log4j2 的日志配置
jishuin: 动态设置 log4j2 日志的级别不能落
log4j2 不使用配置文件,动态生成logger对象
CSDN: Log4j2代码方式配置实现线程级动态控制
stackoverflow: Loading log4j2.xml or properties configuration file during runtime by specifying path
How to usenewBuildermethodinorg.apache.logging.log4j.core.appender.ConsoleAppender