Java EE 应用程序中的外部 Log4J2 配置

External Log4J2 configuration in Java EE application

我正在开发 Java EE 项目,该项目的配置文件位于 resources 文件夹中。 Web项目使用Maven组装成一个war文件并部署到Tomcat.

然后我开始做一些维护,并尝试将在某种程度上成功的配置外部化。

如果您想知道在我编辑代码之前它是如何投入生产的,请看这里:

// x stands for `application.conf` or  `en.properties` depending on where in the code the file is being 
getClass().getClassLoader().getResourceAsStream(x)

我已将 resources 下的每个文件移动到 /CATALINA_BASE/conf/myProject 并且我正在从代码中的这些路径读取。 (对我来说这不是一个好习惯)

这是我的版本:

// x stands for `application.conf` or  `en.properties` depending on where in the code the file is being read
new File(System.getProperty("catalina.base") + "/conf/myProject/x")

这显然工作正常,但该项目还有一个 log4j2.properties 文件,该文件是在我外部化配置之前自动从类路径中读取的,因此我无法从中读取。

我尝试在 web.xml 中设置一个参数,如下所示(不确定这样做是否正确)

<web-app>
...
    <context-param>
<!--        also tried with log4jConfigLocation-->
        <param-name>log4Configuration</param-name>
        <param-value>file:${catalina.base}/conf/myProject/log42.properties</param-value>
    </context-param>
...
</web-app>

应用程序启动时的错误输出:

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'org.apache.logging.log4j.simplelog.StatusLogger.level' to TRACE to show Log4j2 internal initialization logging.

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".

SLF4J: Defaulting to no-operation (NOP) logger implementation

如有任何建议,我们将不胜感激。

更新: 服务器上的 tomcat 运行 正在为其他几个应用程序提供服务,因此设置 VM 参数对我来说不是一个选项,因为其他项目可能在它们的类路径中有它们的 log4j 配置,而 VM 参数可能会破坏这些配置。

您应该转到 Catalina.properties 并将 conf/myProject 目录添加到类路径中。然后你可以只在类路径的根目录下查找文件。您可以通过将 web.xml 中的配置更改为文件名来为该目录中的每个 Web 应用程序创建日志记录配置 - 即 log4j2-appname.xml.

另一种可行的替代方法是将文件 url 从 file: 更改为 file://.

顺便说一句 - 我的雇主有这样的应用程序 运行 - 一个 tomcat 中有多个应用程序。随着时间的推移,它引起了各种各样的问题,确实是一个坏主意。

如果有人遇到这个问题,我已经找到了解决方案。

深入研究 org.apache.logging.log4j:log4j-core:2.8.2 的源文件后,我看到 ConfigurationFactory class 调用了 PropertiesUtil.getProperties(),其中有一行如下:

private static final PropertiesUtil LOG4J_PROPERTIES = new PropertiesUtil("log4j2.component.properties");

因此我在src/main/resources/下创建了一个log4j2.component.properties文件,里面只有一行属性:

log4j.configurationFile=myCustomPath/log4j2.properties

由于我们无法使用 logging.config 属性 在 Java EE 应用程序中设置配置路径,这与 Spring 项目不同,因此添加此特定文件解决了我外部化 log4j 的问题配置。

希望这个回答对其他人也有帮助。