如何在部署时覆盖Log4j2 Logger的日志级别
我希望Jar包中仅包含一份Log4j2配置文件,启动应用时能覆盖部分设置——比如默认日志级别是warn,调试时改成debug。我知道log4j.configurationFile系统属性,但用起来太繁琐。当前环境是Log4j 2.17.2 + Java 11,仅通过LogManager.getLogger()初始化日志,没有特殊配置。
我的log4j2.properties配置文件如下:
status = debug rootLogger.level = warn rootLogger.appenderRefs = console rootLogger.appenderRef.stdout.ref = STDOUT loggers= dt logger.dt = console logger.dt.name = com.ibm.data_triage logger.dt.appenderRefs = console logger.dt.appenderRef.stdout.ref = STDOUT #logger.dt.level = trace logger.dt.level = info appender.console.type = Console appender.console.name = STDOUT appender.console.layout.type = PatternLayout appender.console.layout.pattern = %d{yyyy-dd HH:mm:ss} %p %l - %m%n
我尝试过以下启动命令覆盖日志级别,但都无效:
java -Dlogger.dt.level=trace
或者
java -Dlog4j.logger.dt.level=trace
我也试过Stack Overflow上AbuNassar的方案,同样没效果。
当我把配置文件中status=debug打开,执行以下命令:
java -Dlog4j.logger.dt.level=trace -Dlog4j2.logger.dt.level=trace -Dlogger.dt.level=trace
Log4j初始化日志显示com.ibm.data_triage的级别还是INFO:
2023-05-11 18:18:59,512 main DEBUG Apache Log4j Core 2.17.2 initializing configuration org.apache.logging.log4j.core.config.properties.PropertiesConfiguration@d95dd310 2023-05-11 18:18:59,514 main DEBUG PluginManager 'Core' found 127 plugins 2023-05-11 18:18:59,515 main DEBUG PluginManager 'Level' found 0 plugins 2023-05-11 18:18:59,518 main DEBUG PluginManager 'Lookup' found 16 plugins 2023-05-11 18:18:59,519 main DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef]. 2023-05-11 18:18:59,529 main DEBUG PluginManager 'TypeConverter' found 26 plugins 2023-05-11 18:18:59,539 main DEBUG createAppenderRef(ref="STDOUT", level="null", Filter=null) 2023-05-11 18:18:59,539 main DEBUG Building Plugin[name=logger, class=org.apache.logging.log4j.core.config.LoggerConfig]. 2023-05-11 18:18:59,550 main DEBUG LoggerConfig$Builder(additivity="null", level="INFO", levelAndRefs="null", name="com.ibm.data_triage", includeLocation="null", ={STDOUT}, ={}, Configuration, Filter=null) 2023-05-11 18:18:59,552 main DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef]. 2023-05-11 18:18:59,553 main DEBUG createAppenderRef(ref="STDOUT", level="null", Filter=null) 2023-05-11 18:18:59,553 main DEBUG Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger]. 2023-05-11 18:18:59,556 main DEBUG LoggerConfig$RootLogger$Builder(additivity="null", level="WARN", levelAndRefs="null", includeLocation="null", ={STDOUT}, ={}, Configuration, Filter=null) 2023-05-11 18:18:59,556 main DEBUG Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin]. 2023-05-11 18:18:59,558 main DEBUG createLoggers(={com.ibm.data_triage, root}) 2023-05-11 18:18:59,559 main DEBUG Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout]. 2023-05-11 18:18:59,561 main DEBUG PatternLayout$Builder(pattern="%d{yyyy-dd HH:mm:ss} %p %l - %m%n", PatternSelector=null, Configuration, Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="null", noConsoleNoAnsi="null", header="null", footer="null") 2023-05-11 18:18:59,561 main DEBUG PluginManager 'Converter' found 45 plugins 2023-05-11 18:18:59,577 main DEBUG Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.ConsoleAppender]. 2023-05-11 18:18:59,581 main DEBUG ConsoleAppender$Builder(target="null", follow="null", direct="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%d{yyyy-dd HH:mm:ss} %p %l - %m%n), name="STDOUT", Configuration, Filter=null, ={}) 2023-05-11 18:18:59,586 main DEBUG Starting OutputStreamManager SYSTEM_OUT.false.false 2023-05-11 18:18:59,587 main DEBUG Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin]. 2023-05-11 18:18:59,588 main DEBUG createAppenders(={STDOUT}) 2023-05-11 18:18:59,589 main DEBUG Configuration org.apache.logging.log4j.core.config.properties.PropertiesConfiguration@d95dd310 initialized 2023-05-11 18:18:59,589 main DEBUG Starting configuration org.apache.logging.log4j.core.config.properties.PropertiesConfiguration@d95dd310 2023-05-11 18:18:59,590 main DEBUG Started configuration org.apache.logging.log4j.core.config.properties.PropertiesConfiguration@d95dd310 OK. 2023-05-11 18:18:59,591 main DEBUG Shutting down OutputStreamManager SYSTEM_OUT.false.false-1 2023-05-11 18:18:59,591 main DEBUG OutputStream closed 2023-05-11 18:18:59,592 main DEBUG Shut down OutputStreamManager SYSTEM_OUT.false.false-1, all resources released: true 2023-05-11 18:18:59,592 main DEBUG Appender DefaultConsole-1 stopped with status true 2023-05-11 18:18:59,593 main DEBUG Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@6fbdbc94 OK 2023-05-11 18:18:59,630 main DEBUG Registering MBean org.apache.logging.log4j2:type=ed8046be 2023-05-11 18:18:59,634 main DEBUG Registering MBean org.apache.logging.log4j2:type=ed8046be,component=StatusLogger 2023-05-11 18:18:59,637 main DEBUG Registering MBean org.apache.logging.log4j2:type=ed8046be,component=ContextSelector 2023-05-11 18:18:59,638 main DEBUG Registering MBean org.apache.logging.log4j2:type=ed8046be,component=Loggers,name= 2023-05-11 18:18:59,639 main DEBUG Registering MBean org.apache.logging.log4j2:type=ed8046be,component=Loggers,name=com.ibm.data_triage 2023-05-11 18:18:59,641 main DEBUG Registering MBean org.apache.logging.log4j2:type=ed8046be,component=Appenders,name=STDOUT 2023-05-11 18:18:59,645 main DEBUG org.apache.logging.log4j.core.util.SystemClock supports precise timestamps. 2023-05-11 18:18:59,646 main DEBUG Reconfiguration complete for context[name=ed8046be] at URI C:\Users\DavidWood\git\data-triage-4j\data-triage-core\target\classes\log4j2.properties (org.apache.logging.log4j.core.LoggerContext@1414d955) with optional ClassLoader: null 2023-05-11 18:18:59,647 main DEBUG Shutdown hook enabled. Registering a new one. 2023-05-11 18:18:59,653 main DEBUG LoggerContext[name=ed8046be, org.apache.logging.log4j.core.LoggerContext@1414d955] started OK.
请问有没有可行的方法实现这个需求?
方法1:在配置文件中使用系统属性占位符
Log4j2支持在配置文件中引用系统属性,你可以把需要动态修改的日志级别改成占位符形式,启动时通过-D参数传入对应值。
修改你的log4j2.properties文件,把日志级别替换成占位符:
# 根日志级别,默认warn,可通过-Droot.level覆盖 rootLogger.level = ${sys:root.level:warn} # com.ibm.data_triage日志级别,默认info,可通过-Ddt.level覆盖 logger.dt.level = ${sys:dt.level:info}
启动时,直接通过系统属性覆盖:
# 仅修改根日志级别为debug java -Droot.level=debug -jar your-app.jar # 修改com.ibm.data_triage级别为trace,根级别保持默认warn java -Ddt.level=trace -jar your-app.jar # 同时修改两个级别 java -Droot.level=debug -Ddt.level=trace -jar your-app.jar
这种方式不需要额外配置,完全基于Log4j2的内置功能,且配置文件只需要一份,符合你的需求。
方法2:使用Log4j2的命令行参数(2.13.0+支持)
从Log4j2 2.13.0开始,支持直接通过命令行参数修改日志级别,不需要修改配置文件。格式为-l <logger-name>=<level>或者--log-level <logger-name>=<level>。
比如:
# 修改根日志级别为debug java -l root=debug -jar your-app.jar # 修改com.ibm.data_triage级别为trace java -l com.ibm.data_triage=trace -jar your-app.jar # 同时修改多个 java -l root=debug -l com.ibm.data_triage=trace -jar your-app.jar
注意:这种方式不需要修改原有配置文件,但需要确保你的Log4j2版本≥2.13.0(你的2.17.2满足要求)。
方法3:使用JMX动态修改(适合运行时调整)
如果需要在应用运行过程中动态修改日志级别,而不是启动时设置,可以通过JMX连接到应用,修改Log4j2的日志配置。
运行应用时确保JMX端口开启:
java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9090 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar your-app.jar
然后使用JConsole或VisualVM连接到对应端口,找到org.apache.logging.log4j2下的MBean,修改指定Logger的级别。
内容的提问来源于stack exchange,提问作者David Wood

