在log4j2.xml中读取system.properties变量出错求助
问题原因与解决方案
核心问题分析
使用
${sys:logfilename}报错的原因
Log4j2的初始化流程早于你在main方法中设置System.setProperty("logfilename", "a_cool_logname")的时机。当Log4j2解析配置文件时,系统属性logfilename还未被设置,它会直接把${sys:logfilename}当作文件名的一部分。而Windows系统的文件名不允许包含${}这类特殊字符,因此抛出文件名语法错误的异常。${main:-logfilename}无效的原因
Log4j2没有名为main的Lookup类型(Lookup是Log4j2用来解析变量的机制),这个语法完全错误,所以Log4j2会直接使用默认值logfilename作为文件名。
可行解决方案
方案一:确保系统属性在Log4j2初始化前被设置
这是最直接的解决方式,有两种实现途径:
- 通过JVM启动参数传递:在启动程序时添加参数
-Dlogfilename=a_cool_logname,这样Log4j2在启动时就能读取到这个系统属性,配置中的${sys:logfilename}会被正确替换。 - 调整代码执行顺序:把设置系统属性的代码放在所有日志相关代码(比如获取Logger实例、调用日志方法)之前,示例代码如下:
public static void main(String[] args) throws IOException { // 先设置系统属性,再初始化日志 System.setProperty("logfilename", "a_cool_logname"); // 之后再获取Logger或执行其他业务逻辑 org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getLogger(YourMainClass.class); // ...后续代码 }
方案二:给变量设置默认值(可选)
可以在配置文件中给${sys:logfilename}添加默认值,避免因属性未设置导致初始化报错,同时建议给filePattern添加滚动索引(否则每次滚动会覆盖原文件),配置修改如下:
<RollingFile name="RollingFile" fileName="logs/${sys:logfilename:-default_log}.log" filePattern="logs/${sys:logfilename:-default_log}.%i.log"> <!-- 其他配置不变 --> </RollingFile>
内容的提问来源于stack exchange,提问作者Abhi
相关产品推荐
相关产品推荐

