我正在 java 应用程序中运行 log4j2 日志记录,但设置不太灵活。我们的应用程序的类路径中有一个现有的
log4j2.xml
配置文件,该文件存在于可执行 jar 中。我可以修改 jar,但不能修改它的名称或外部的内容(我不控制环境)。我想在 jar 之外添加一个可选覆盖 log4j2 配置文件。当它存在时,它会覆盖 log4j2.xml,当它不存在时,会使用 log4j2.xml。所以我将此属性添加到 log4j2.component.properties
文件中:
log4j.configurationFile=../conf/log4j2-override.xml
当我创建这个可选文件时,它工作得很好。当我不创建此文件时,log4j2 会打印一条错误,指出找不到该文件,然后无法回退到类路径中现有的
log4j2.xml
文件。如果我将类路径特定的文件添加到configurationFile 属性似乎并不重要。配置文件当然可用,因为如果我完全删除该属性,它会使用 jar 类路径中的配置。
log4j2 似乎在查找文件时出错并停止自动配置序列而不是继续。如果我选择不这样做,我是否可以选择覆盖默认配置 xml 文件,而不要求它出现在 jar 之外?我希望从 jar 文件中指定这一点,而不是要求根据文件的存在来更改调用 jar 的方式。
log4j2.configurationFile
属性允许您指定以逗号分隔的配置源列表,这些配置源将使用合并策略进行合并(有关默认规则,请参阅DefaultMergeStrategy
)。根据您的情况,您可以使用:
log4j2.configurationFile=classpath:log4j2.xml,../conf/log4j2-override.cml
丢失的文件将被忽略,并向状态记录器发送警告。
Log4j 2.13.x 受到错误 LOG4J2-2901 的影响,如果文件丢失,该错误会停止配置过程。因此请确保使用最新版本。
Piotr 的答案解决了自动配置序列不起作用的直接原因,但它仍然打印了对我的用例不起作用的警告消息。因此,这里有一种替代方法来处理我对环境的限制(限制对 jar 文件本身的修改并且没有控制台输出)。
基本上只是在代码本身中有条件地设置记录器配置文件。我有一个 application.properties 文件,不幸的是它没有加载到 spring 配置中,所以我真的必须手动执行此操作。您可以有条件地从标准外部 spring application.properties 文件中指定
log4j.configurationFile
属性,甚至不使用此代码。
import java.io.File;
import org.apache.logging.log4j.core.LoggerContext;
Properties props = new EncryptableProperties(encryptor);
if (props.getProperty("log4j.configurationFile") != null) {
LoggerContext loggerContext = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
File file = new File(props.getProperty("log4j.configurationFile"));
loggerContext.setConfigLocation(file.toURI());
}