【发布时间】:2011-01-08 02:58:18
【问题描述】:
问题是,每当您更改 log4j.properties/log4j.xml 时,您都需要重新启动 tomcat [或说任何其他服务器]。是否有任何重新加载 log4j 配置的解决方法?
【问题讨论】:
问题是,每当您更改 log4j.properties/log4j.xml 时,您都需要重新启动 tomcat [或说任何其他服务器]。是否有任何重新加载 log4j 配置的解决方法?
【问题讨论】:
来自http://logging.apache.org/log4j/1.2/faq.html#3.6
有没有办法让 log4j 到 自动重新加载配置 如果文件发生变化?
是的。 DOMConfigurator 和 PropertyConfigurator 支持自动 通过重新加载 configureAndWatch 方法。请参阅API documentation 了解更多信息 详情。
因为 configureAndWatch 启动 一个单独的 wathdog 线程,并且因为 没有办法阻止这个线程 log4j 1.2,configureAndWatch 方法在 J2EE 中使用是不安全的 应用程序所在的环境 回收。
也就是说,我已经在 Java EE 环境(Sun One Web Server,而不是 Tomcat)中成功使用了 PropertyConfigurator#configureAndWatch 方法。
【讨论】:
您可以通过以下简短步骤编写一些初始化代码:
有关详细信息,请参阅此博客文章 - reload log4j configuration in tomcat
他们还将其移至github。
【讨论】:
您可以创建一个支撑动作或一个重新加载属性文件的 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的Log4jConfigListener
【讨论】:
从 log4j 2.x 开始,您可以定期重新加载配置,在本示例中每 30 秒一次:
<configuration monitorInterval="30">
有关 log4j 2.x 配置的更多信息,请查看here:
【讨论】:
更新:如果您使用的是 lg4j2.xml,配置是您在运行时管理 log4j 唯一需要的东西
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" monitorInterval="30">
<Loggers>
-------
</Loggers>
</Configuration>
监控间隔 30 每 30 秒加载一次 log4j 更改。
如果您使用的是旧版本的 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;
}
}
然后对 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 配置。
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
【讨论】:
Guido Garcia 的回答非常准确。
Log4j 1 提供了一种以非 JEE 线程安全方式重新加载 log4j 配置的方法。
因此,如果您在 JEE 中,您可以通过以下方式轻松解决您的问题:
(A) 创建您的 @Singleton ejb 计时器以定期扫描您的 log4j.properties 文件
(b) 看log4j给出的log4j log watch的实现。 当需要重新加载文件时,它的作用非常简单方便,如下所示:
新PropertyConfigurator().doConfigure(filename,LogManager.getLoggerRepository());
如果您的配置文件上的时间戳发生更改,请执行相同操作。 就是这样。
【讨论】: