如何从JNDI加载log4j2配置文件

3

我正在将一些网站应用从Log4j 1.12迁移到Log4j2。由于公司政策,我们的log4j.xml文件位置在应用服务器中配置为URL,并且应用程序必须使用JNDI获取它们。 我们实现了一个ServletContextListener,通过这种方式初始化了log4j基础设施:

public void contextInitialized(ServletContextEvent servletContextEvent) {
    ...
    urlLogConfig = (URL) context.lookup("java:comp/env/"+logLocation);
    ...
    //urlLogConfig -> file:///somepath/log4j.xml
    DOMConfigurator.configureAndWatch(urlLogConfig.getPath());
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
    ServletContext servletContext = servletContextEvent.getServletContext();
    servletContext.log("Log4jConfigurationListener - Shutting down log4j");
    LogManager.shutdown();
}

然而,由于log4j2 API的更改,这种方法不再可用。Log4j2提供了lo4j2-web.jar模块,使用Log4jServletContainerInitializer来初始化库。这最终会调用Log4jWebInitializerImpl.getConfigURI(),负责获取配置文件的URI。
是否有任何方法可以自定义Log4jWebInitializerImpl的行为,使其从JNDI名称解析xml文件?
1个回答

0

可以用类似这样的方式:

...
import org.apache.logging.log4j.core.config.Configurator;
...

    private LoggerContext loggerContext;

    public void contextInitialized(ServletContextEvent servletContextEvent) {
       ...
       urlLogConfig = (URL) context.lookup("java:comp/env/"+logLocation);
       ...
       //urlLogConfig -> file:///somepath/log4j.xml
       ServletContext servletContext = servletContextEvent.getServletContext();
       String contextName = servletContext.getServletContextName();
       Classloader classloader = this.getClass().getClassloader();
       loggerContext = Configurator.initialize(contextName, classloader, urlLogConfig.toURI());
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();
        servletContext.log("Log4jConfigurationListener - Shutting down log4j");
        if (loggerContext != null) 
             Configurator.shutdown(loggerContext);
    }

嗨,史蒂夫,你的解决方案还不错。但是我有点担心这里所说的 https://logging.apache.org/log4j/2.x/manual/webapp.html “Log4j资源无法通过正常手段清理。在Web应用程序部署时必须“启动”Log4j,在Web应用程序取消部署时必须“关闭”Log4j。” 你确定你提出的方案能够在Web环境中正确地清理所有内容吗? - codependent
以上解决方案未使用log4j2 webapp包。`Configurator.shutdown(loggerContext)应清理自己初始化的资源。 - Steve C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接