在运行时重新加载tomcat日志?

时间:2013-02-28 16:56:59

标签: tomcat tomcat7 java.util.logging

我们目前正在使用Tomcat 7,其中使用-Djava.util.logging.config.file指定单个日志配置,使用带-Djava.util.logging.manager =“org.apache.juli.ClassLoaderLogManager”的默认ClassLoaderLogManager。这适用于一次性启动配置。

我们有几个servlet和其他代码在servlet上下文之外运行。我们在一个完全控制的专用tomcat服务器上运行,我们希望所有代码都使用相同的日志配置。我们使用java.util.logging API进行日志记录。这意味着LogManager.getLogManager()。getLogger(name)需要工作,而Logger.isLoggable(Level)需要工作。

ClassLoaderLogManager似乎与我们的情况相反:允许servlet指定单独的日志设置。我们希望在一个地方控制所有日志。但是,我们希望获得其他JULI好处,例如改进的FileHandler。

现在的问题是:如何在运行时从文件重新加载这些设置而无需重新加载应用程序?

我尝试了什么:

  • LogManager.getLogManger.readConfiguration():在ClassLoaderLogManager中产生有效的NOOP,因为Thread.currentThread.getContextClassLoader()不是系统类加载器。
  • 显式设置Thread.setContextClassLoader(ClassLoader.getSystemClassLoader()),然后调用上面的内容。这确实读取了配置文件(在调试器中逐步执行),但它没有将更改传播到包含的ClassLoaders中的现有记录器。从未在现有记录器上调用Logger.setLevel()。
  • 在这些调用之前调用reset()似乎没有任何改变。
  • JMX似乎只公开单个ClassLoader的记录器(可能是系统ClassLoader)

2 个答案:

答案 0 :(得分:2)

我找到了一个解决方案。使用默认的java.util.logging.LogManager替换启动脚本中的日志管理器,或者只是删除命令行参数会导致使用常规LogManager。当调用readConfiguration()时,此LogManager将完全重新加载所有ClassLoader中所有Logger的配置,这正是我需要的行为。

但这确实涉及修改tomcat启动脚本。如果有人能够在没有这样做的情况下找到更好的解决方案,那就太好了,否则我会接受这个答案。

答案 1 :(得分:0)

如果您未与Tomcat JULI结婚,您可能需要考虑使用Logback,因为IMHO是唯一能够在运行时可靠地处理日志配置重新加载的。

我自己没有这样做,但是有人写了一个指南:Logging with SLF4J and Logback in Tomcat and TomEE基本上使用了一堆桥罐。<​​/ p>

您可能会考虑的另一件事就是使用每个Web应用程序使用Logback进行日志记录,并忽略Tomcat的JULI日志(这就是我所做的)。

CAVEAT http://www.slf4j.org/legacy.html#jul-to-slf4j ...因此请永远不要直接使用JUL .... Guava和Tomcat在我的$ hit列表中使用JUL。