简体   繁体   English

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

[英]Is it possible to reload log4j.xml / log4j.properties file dynamically in Tomcat?

The problem is, whenever you change the log4j.properties/log4j.xml, you need to restart the tomcat [ or say any other server ]. 问题是,每当你更改log4j.properties/log4j.xml时,你需要重启tomcat [或者说任何其他服务器]。 Is there any workaround of reloading the log4j configuration? 有没有重新加载log4j配置的解决方法?

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

Is there a way to get log4j to automatically reload a configuration file if it changes? 有没有办法让log4j在配置文件发生变化时自动重新加载?

Yes. 是。 Both the DOMConfigurator and the PropertyConfigurator support automatic reloading through the configureAndWatch method . DOMConfigurator和PropertyConfigurator都支持通过configureAndWatch方法自动重新加载。 See the API documentation for more details. 有关更多详细信息,请参阅API文档

Because the configureAndWatch launches a separate wathdog thread, and because there is no way to stop this thread in log4j 1.2, the configureAndWatch method is unsafe for use in J2EE envrironments where applications are recycled. 因为configureAndWatch启动了一个单独的wathdog线程,并且由于无法在log4j 1.2中停止此线程,所以configureAndWatch方法在应用程序被回收的J2EE环境中使用是不安全的。

Said that, I've successfully used PropertyConfigurator#configureAndWatch method in a Java EE environment (Sun One Web Server, not Tomcat). 说,我已经在Java EE环境(Sun One Web Server,而不是Tomcat)中成功使用了PropertyConfigurator#configureAndWatch方法。

As of log4j 2.x you can reload the config periodically, in this example every 30 seconds: 从log4j 2.x开始,您可以定期重新加载配置,在此示例中每30秒:

<configuration monitorInterval="30">

Please take a look here for more information on log4j 2.x configuration: 有关log4j 2.x配置的更多信息,请查看此处

Update:If you are using lg4j2.xml, the configuration is the only thing you will need for log4j to be managed at runtime 更新:如果您使用的是lg4j2.xml,那么在运行时管理log4j是唯一需要的配置

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

Monitor interval 30 loads the log4j changes every 30 seconds. 监视间隔30每30秒加载log4j更改。

Below solution is if you are on older version of log4j. 以下解决方案是您使用旧版本的log4j。

Yes you can change the log4j level at run time without the need to restart the server provided you are using spring. 是的,您可以在运行时更改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;
 }

}

Then do these changes to applicationContext. 然后对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>

Full code and explanation can be found here 完整的代码和解释可以在这里找到

Changing log4j Level dynamically 动态更改log4j级别

You can write a little initializer code with the following short steps: 您可以使用以下简短步骤编写一些初始化代码:

  • listen for the "BEFORE_START_EVENT", 听“BEFORE_START_EVENT”,
  • when the event happens (once per Tomcat restart), start log4j using the configureAndWatch method 当事件发生时(每次Tomcat重启一次),使用configureAndWatch方法启动log4j
  • also don't forget to install a shutdown hook to cleanup the watcher thread 也不要忘记安装一个关闭钩子来清理观察者线程

See this blog post for details - reload log4j configuration in tomcat 有关详细信息,请参阅此博客文章 - 在tomcat中重新加载log4j配置

They also moved it to github . 他们还把它搬到了github

You can create a strut action or a servlet which reload the properties file. 您可以创建一个strut操作或一个重新加载属性文件的servlet。 So after editing the log4j.properties file, you will need to call the servlet to reload it. 因此,在编辑log4j.properties文件之后,您将需要调用servlet来重新加载它。

For example: 例如:

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的Log4jConfigListener

The Guido Garcia answer is quite on target. Guido Garcia的回答非常明确。

Log4j 1 offers a way of reloading log4j configuration in a non JEE thread safe maner. Log4j 1提供了一种在非JEE线程安全主体中重新加载log4j配置的方法。

So if you are in a JEE continer, you can solve your problem trivially by: 因此,如果您在JEE continer中,您可以通过以下方式轻松解决您的问题:

(A) Create your @Singleton ejb timer to periodically scan your log4j.properties file (A)创建@Singleton ejb计时器以定期扫描log4j.properties文件

(b) Look at the implementaiton of the log4j log watch given by log4j. (b)查看log4j给出的log4j日志监视的实现。 What it does when it is time to relaoad a file is quite simply and conveniently, the following: 当重新加载文件时,它的作用非常简单方便,如下:

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

Just do the same, if the time stamp on you configuration file changes. 如果配置文件上的时间戳发生变化,请执行相同的操作。 That is it. 这就对了。

Another Method is to configure a file watcher using Java File WatcherService as explained below link and reload Log4J configuration on any file Modifications. 另一种方法是使用Java File WatcherService配置文件观察程序,如下所述链接并重新加载任何文件修改上的Log4J配置。

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

Reloading can be done using DOMConfigurator's APIs 可以使用DOMConfigurator的API完成重新加载

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM