动态重新加载运行在tomcat中的grails应用程序的log4j.properties

时间:2013-12-04 16:19:41

标签: tomcat grails logging log4j

我有一个grails应用程序,部署到tomcat,正在使用log4j。我希望能够在tomcat中更新/webapps/WEB-INF/classes/log4j.properties,然后让应用程序动态拾取更改而无需重新启动。我没有运气找到一个好方法来做到这一点。我发现的是:

我可以将文件检索为流:

Thread.currentThread().getContextClassLoader().getResourceAsStream("log4j.properties")

不幸的是,这是在启动时加载的类,我不确定是否/如何强制它从实际文件更新。如果有效,我可以阅读每个属性并使用:

Logger.rootLogger.loggerRepository.getLogger(<key>).level = <new log level>

我见过关于LogManager.resetConfiguration()的事情,但这似乎也没有帮助。

此外,这是我在resources.groovy

中设置log4j的方法
beans = {
    // Setting up external configuration for log4j
    log4jConfigurer(org.springframework.beans.factory.config.MethodInvokingFactoryBean) {
        targetClass = "org.springframework.util.Log4jConfigurer"
        targetMethod = "initLogging"
        arguments = ["classpath:log4j.properties"]
    }
}

我对使用configureAndWatch方法不感兴趣,因为我读过它的漏洞。

我看到有可用于log4j的XML和JSON属性,我只是使用普通的* .properties文件,我不确定这是否是问题的一部分。

任何提示都将非常感谢,提前感谢!

1 个答案:

答案 0 :(得分:0)

以下是我为解决此问题所做的工作,它需要setUseCaches(false),以确保文件的缓存版本(来自类加载器)未被使用。

def fileInputStream = null
// The method below is used to ensure that the file is read from disk every time, rather than using the previously loaded file from the ClassLoader
def classLoader = Thread.currentThread().getContextClassLoader()
def resource = classLoader.getResource("log4j.properties")
def connection = resource.openConnection()
connection.setUseCaches(false)
// Warning: do not read or log the fileInputStream, because it will close the connection
fileInputStream = (FileInputStream)connection.getInputStream().in
// Use the Properties object to prevent errors on comments (#)
def props = new Properties()
props.load(fileInputStream)
def config = new ConfigSlurper().parse(props)

然后我可以使用:

来引用记录器属性
config.log4j.logger.each {
    Logger.rootLogger.loggerRepository.getLogger(it.key).level = Level.toLevel(it.value)
}

您还可以进行检查以查看现有日志级别是什么,并提供输出以指出哪些日志记录实际已更改。