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

Rak*_*yal 34 java tomcat log4j

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

Gui*_*ido 27

来自http://logging.apache.org/log4j/1.2/faq.html#3.6

有没有办法让log4j在配置文件发生变化时自动重新加载?

是.DOMConfigurator和PropertyConfigurator都支持通过configureAndWatch方法自动重新加载 .有关更多详细信息,请参阅API文档.

因为configureAndWatch启动了一个单独的wathdog线程,并且由于无法在log4j 1.2中停止此线程,所以configureAndWatch方法在应用程序被回收的J2EE环境中使用是不安全的.

说,我已经在Java EE环境(Sun One Web Server,而不是Tomcat)中成功使用了PropertyConfigurator#configureAndWatch方法.

  • 在重新启动或重新部署应用程序几次之前,您可能不会注意到该问题.线程或其他资源泄漏可能最终导致您的应用程序服务器崩溃. (11认同)

Cri*_*ciu 22

从log4j 2.x开始,您可以定期重新加载配置,在此示例中每30秒:

<configuration monitorInterval="30">
Run Code Online (Sandbox Code Playgroud)

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

  • 它只是Log4j 2吗? (4认同)
  • @PeterRader 确实,此属性仅在 log4j 2 中受支持 (2认同)

Kie*_*xon 6

您可以使用以下简短步骤编写一些初始化代码:

  • 听"BEFORE_START_EVENT",
  • 当事件发生时(每次Tomcat重启一次),使用configureAndWatch方法启动log4j
  • 也不要忘记安装一个关闭钩子来清理观察者线程

有关详细信息,请参阅此博客文章 - 在tomcat中重新加载log4j配置

他们还把它搬到了github.

  • 提升您的答案作为解决方案对我来说最有用,但为了改进答案(并坚持SO标准),我建议您在答案本身中添加一些细节.在这里,让我为你编辑答案:) (2认同)

vsi*_*ngh 5

更新:如果您使用的是lg4j2.xml,则配置是在运行时管理log4j所需的唯一操作

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" monitorInterval="30">
  <Loggers>
-------
  </Loggers>
</Configuration>
Run Code Online (Sandbox Code Playgroud)

监视间隔30加载log4j每30秒更改一次。

如果您使用的是较旧版本的log4j,则下面的解决方案是。

是的,您可以在运行时更改log4j级别,而无需使用Spring重启服务器。

public class OptionalLog4jConfigurer extends Log4jConfigurer implements
 InitializingBean {

public static final Long DEFAULT_REFRESH = 30000L;
 private static final Log LOG = LogFactory
 .getLog(OptionalLog4jConfigurer.class);

private String configLocation;
 private Long refreshInterval;

public OptionalLog4jConfigurer(final String configLocation,
 final Long refreshInterval) {
 this.configLocation = configLocation;

if (refreshInterval == null) {
 this.refreshInterval = DEFAULT_REFRESH;
 }
 else {
 this.refreshInterval = refreshInterval;
 }
 }


 public void afterPropertiesSet() throws Exception {
 if (!StringUtils.isEmpty(this.configLocation)) {
 LOG.info("Log4J configuration is being customized.");

this.initLoggingInternal();
 }
 else {
 LOG
 .info("Using default Log4J configuration. No customization requested");
 }
 }

public String getConfigLocation() {
 return this.configLocation;
 }

public Long getRefreshInterval() {
 return this.refreshInterval;
 }

}
Run Code Online (Sandbox Code Playgroud)

然后对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>
Run Code Online (Sandbox Code Playgroud)

完整的代码和说明可以在这里找到

动态更改log4j级别