Java 是否可以在Tomcat中动态重新加载log4j.xml/log4j.properties文件?

Java 是否可以在Tomcat中动态重新加载log4j.xml/log4j.properties文件?,java,tomcat,log4j,Java,Tomcat,Log4j,问题是,无论何时更改log4j.properties/log4j.xml,都需要重新启动tomcat[或者说任何其他服务器]。是否有重新加载log4j配置的解决方法?来自 有没有办法让log4j 自动重新加载配置 文件是否更改 对。DOMConfigurator和 属性配置程序支持自动 通过 配置和监视方法。有关更多信息,请参阅 细节 因为configureAndWatch启动了 一个单独的wathdog线程,因为 没有办法阻止此线程进入 log4j 1.2,配置和监视 方法在J2EE中使用是不

问题是,无论何时更改log4j.properties/log4j.xml,都需要重新启动tomcat[或者说任何其他服务器]。是否有重新加载log4j配置的解决方法?

来自

有没有办法让log4j 自动重新加载配置 文件是否更改

对。DOMConfigurator和 属性配置程序支持自动 通过 配置和监视方法。有关更多信息,请参阅 细节

因为configureAndWatch启动了 一个单独的wathdog线程,因为 没有办法阻止此线程进入 log4j 1.2,配置和监视 方法在J2EE中使用是不安全的 应用程序所在的环境 回收的


如上所述,我已经在Java EE环境(Sun One Web服务器,而不是Tomcat)中成功地使用了PropertyConfigurator#configureAndWatch方法。

您可以通过以下简短步骤编写一些初始化器代码:

  • 收听“启动事件前”
  • 当事件发生时(每次Tomcat重启一次),使用configureAndWatch方法启动log4j
  • 另外,不要忘记安装一个关闭钩子来清理watcher线程
有关详细信息,请参阅此博客帖子-


他们还将其移动到了。

您可以创建一个struct操作或一个servlet来重新加载属性文件。因此,在编辑log4j.properties文件之后,您需要调用servlet来重新加载它

例如:

public class Log4JServlet extends HttpServlet{
  private static final long serialVersionUID = 1L;
  protected static Logger log = Logger.getLogger(Log4JTestServlet.class);

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("Reload Log4J prop file");
    String path = "C:\\GlassFishESBv22\\glassfish\\domains\\domain1\\config\\log4j.properties";
    PropertyConfigurator.configure(path);

    /*
    log.debug("debug message");
    log.info("info message");
    log.warn("warn message");
    log.error("error message");
    log.fatal("fatal message");
    */

    }
}

另一种方法是在
web.xml

中配置Spring Framework,从log4j 2.x开始,您可以定期重新加载配置,在本例中,每30秒一次:

<configuration monitorInterval="30">


请查看有关log4j 2.x配置的更多信息:

更新:如果您使用的是lg4j2.xml,那么在运行时管理log4j只需要配置即可

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" monitorInterval="30">
  <Loggers>
-------
  </Loggers>
</Configuration>
然后对applicationContext执行这些更改

<bean id="optionalLog4jInitialization"  class="com.skg.jetm.OptionalLog4jConfigurer">
<constructor-arg index="0" type="java.lang.String"  value="${log4j.configuration}" />
<constructor-arg index="1" type="java.lang.Long" value="100" />
 </bean>

完整的代码和解释可以在这里找到


另一种方法是使用Java file WatcherService配置文件监视程序,如下所述,在任何文件修改时链接并重新加载Log4J配置

可以使用DOMConfigurator的API进行重新加载


吉多·加西亚的回答非常准确

log4j1提供了一种在非JEE线程安全的maner中重新加载Log4j配置的方法

因此,如果您在JEE continer中,您可以通过以下方式轻松解决您的问题:

(A) 创建@Singleton ejb计时器以定期扫描log4j.properties文件

(b) 看看log4j给出的log4j日志监视的实现。 当需要重新加载文件时,它所做的工作非常简单和方便,如下所示:

新建
PropertyConfigurator().doConfigure(文件名,LogManager.getLoggerRepository())

如果配置文件上的时间戳发生更改,请执行相同的操作。
就是这样。

在应用程序重新启动或重新部署几次之前,您可能不会注意到问题。线程或其他资源泄漏可能会导致您的应用程序服务器停机。将您的答案提升为解决方案对我来说最有用,但为了改进答案(并维护SO标准),我建议您在答案中添加一些细节。在这里,让我为您编辑一下答案:)@PeterRader事实上,这个属性只在log4j中受支持,但是配置应该是大写的,因为它的log4j2在生产中没有帮助。从文档中,“警告:假定扩展了WAR文件”是一种干净的方法。
<bean id="optionalLog4jInitialization"  class="com.skg.jetm.OptionalLog4jConfigurer">
<constructor-arg index="0" type="java.lang.String"  value="${log4j.configuration}" />
<constructor-arg index="1" type="java.lang.Long" value="100" />
 </bean>