一尘不染

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

tomcat

当前,我们正在使用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的其他好处,例如改进的FileHandlers。

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

我尝试过的

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

阅读 271

收藏
2020-06-16

共1个答案

一尘不染

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

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

2020-06-16