我可以 skip/omit 一个不存在的 log4j2 配置文件回退到现有配置文件吗?

Can I skip/omit a log4j2 configurationFile that doesn't exist to fall back to an existing one?

我是 运行 log4j2 登录 java 应用程序,但设置不是最灵活。我们的应用程序的类路径中有一个现有的 log4j2.xml 配置文件,该文件存在于可执行 jar 中。我可以修改 jar,但不能修改 jar 或外部的内容(我不控制环境)。我想在 jar 之外添加一个 optional 覆盖 log4j2 配置文件。当它存在时它覆盖 log4j2.xml,当它不存在时使用 log4j2.xml。所以我将这个 属性 添加到 log4j2.component.properties 文件中:

log4j.configurationFile=../conf/log4j2-override.xml

当我创建这个可选文件时,它工作得很好。当我不创建这个文件时,log4j2 会打印出找不到文件的错误,然后无法回退到类路径中现有的 log4j2.xml 文件。将特定于类路径的文件添加到配置文件 属性 似乎并不重要。配置文件当然可用,因为如果我完全删除 属性 它会使用 jar 类路径中的配置。

log4j2 似乎在查找文件时出错并停止了自动配置序列而不是继续。如果我选择不这样做,我是否可以选择覆盖默认配置 xml 文件而不要求它存在于 jar 之外?我希望从 jar 文件中指定它,而不是要求根据文件的存在更改调用 jar 的方式。

log4j.configurationFile 属性 允许您指定以逗号分隔的配置源列表,这些配置源将使用合并策略进行合并(有关默认规则,请参阅 DefaultMergeStrategy)。在您的情况下,您可以使用:

log4j.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());
}