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

问题描述 投票:0回答:8

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

java tomcat log4j
8个回答
31
投票

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

有没有办法让log4j 自动重新加载配置 如果发生变化,请归档?

是的。 DOMConfigurator 和 PropertyConfigurator支持自动 重新加载通过 configureAndWatch 方法。请参阅API文档了解更多信息 详细信息。

因为configureAndWatch启动了 一个单独的 watchdog 线程,并且因为 没有办法停止这个线程 log4j 1.2,configureAndWatch 方法在 J2EE 中使用不安全 应用程序所处的环境 回收。

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


27
投票

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

<configuration monitorInterval="30">

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


6
投票

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

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

详情请参阅此博文 - 在 tomcat 中重新加载 log4j 配置

他们还将其移至 github


5
投票

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

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" monitorInterval="30">
  <Loggers>
-------
  </Loggers>
</Configuration>

监控间隔 30 每 30 秒加载 log4j 变化一次。

如果您使用旧版本的 log4j,则以下解决方案适用。

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

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;
 }

}

然后对 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>

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

动态更改 log4j 级别


4
投票

您可以创建一个 strut 操作或一个 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");
    */

    }
}

3
投票

另一种方法是在 web.xml

 中配置 Spring Framework 的 
Log4jConfigListener


1
投票

Guido Garcia 的回答非常准确。

Log4j 1 提供了一种以非 JEE 线程安全方式重新加载 log4j 配置的方法。

因此,如果您处于 JEE 容器中,您可以通过以下方式轻松解决您的问题:

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

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

PropertyConfigurator().doConfigure(filename,LogManager.getLoggerRepository());

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


0
投票

另一种方法是使用 Java File WatcherService 配置文件观察器,如下链接所述,并在任何文件修改上重新加载 Log4J 配置。

https://dzone.com/articles/how-watch-file-system-changes

可以使用 DOMConfigurator 的 API 完成重新加载

https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/DOMConfigurator.html

© www.soinside.com 2019 - 2024. All rights reserved.