How to change logger level in log4j2.xml at runtime without restarting tomcat service

Deadly 提交于 2021-01-28 14:03:24

问题


I was using log4j 1.2 earlier and I recently migrated to log4j 2.0 I was using below listener class in log4j 1.2 in web.xml

<listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener> 

This listener class is removed after log4j 2.0 and I want replacement of this listener class which allow me to change logger level at runtime and update without restarting tomcat service in my web application.

I have tried below listener but this is also restarting tomcat while changing configuration in log4j2.xml

 <listener>
        <listener-class>org.apache.logging.log4j.core.web.Log4jContextListener</listener-class>
 </listener>

I am seeing below Exceptions and warnings while changing log4j2.xml and then it restarts tomcat:

WARNING: The web application [demo] appears to have started a thread named [pool-UCCAdminMonitor-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 sun.misc.Unsafe.park(Native Method)
 java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(Unknown Source)
 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
 java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
 java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
 java.lang.Thread.run(Unknown Source)
Jul 14, 2020 8:36:25 AM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads

Exception in thread "Log4j2-TF-10-ConfiguratonFileWatcher-19" java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [META-INF/services/javax.xml.parsers.DocumentBuilderFactory]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
    at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1385)
    at org.apache.catalina.loader.WebappClassLoaderBase.findResources(WebappClassLoaderBase.java:985)
    at org.apache.catalina.loader.WebappClassLoaderBase.getResources(WebappClassLoaderBase.java:1086)
    at java.util.ServiceLoader$LazyIterator.hasNextService(Unknown Source)
    at java.util.ServiceLoader$LazyIterator.hasNext(Unknown Source)
    at java.util.ServiceLoader$1.hasNext(Unknown Source)
    at javax.xml.parsers.FactoryFinder$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.xml.parsers.FactoryFinder.findServiceProvider(Unknown Source)
    at javax.xml.parsers.FactoryFinder.find(Unknown Source)
    at javax.xml.parsers.DocumentBuilderFactory.newInstance(Unknown Source)
    at org.apache.logging.log4j.core.config.xml.XmlConfiguration.newDocumentBuilder(XmlConfiguration.java:183)
    at org.apache.logging.log4j.core.config.xml.XmlConfiguration.<init>(XmlConfiguration.java:89)
    at org.apache.logging.log4j.core.config.xml.XmlConfiguration.reconfigure(XmlConfiguration.java:272)
    at org.apache.logging.log4j.core.LoggerContext.onChange(LoggerContext.java:752)
    at org.apache.logging.log4j.core.util.AbstractWatcher$ReconfigurationRunnable.run(AbstractWatcher.java:92)
    at java.lang.Thread.run(Unknown Source)

INFO: Illegal access: this web application instance has been stopped already. Could not load [org.apache.logging.log4j.core.lookup.JndiLookup]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [org.apache.logging.log4j.core.lookup.JndiLookup]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
    at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1385)
    at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForClassLoading(WebappClassLoaderBase.java:1373)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1226)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188)
    at org.apache.logging.log4j.util.LoaderUtil.loadClass(LoaderUtil.java:167)
    at org.apache.logging.log4j.util.LoaderUtil.newInstanceOf(LoaderUtil.java:209)
    at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOf(LoaderUtil.java:230)
    at org.apache.logging.log4j.core.util.Loader.newCheckedInstanceOf(Loader.java:311)
    at org.apache.logging.log4j.core.lookup.Interpolator.<init>(Interpolator.java:112)
    at org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(AbstractConfiguration.java:129)
    at org.apache.logging.log4j.core.config.xml.XmlConfiguration.<init>(XmlConfiguration.java:76)
    at org.apache.logging.log4j.core.config.xml.XmlConfiguration.reconfigure(XmlConfiguration.java:272)
    at org.apache.logging.log4j.core.LoggerContext.onChange(LoggerContext.java:752)
    at org.apache.logging.log4j.core.util.AbstractWatcher$ReconfigurationRunnable.run(AbstractWatcher.java:92)

回答1:


Log4j 2 doesn't require that you provide your own listener. Instead, just add monitorInterval=nn the the Configuration element of you log4j2.xml where nn is the number of seconds to check the configuration. Log4j will then poll the file at that interval and reload the configuration if it changes.




回答2:


Answering my own question - First need to add below filter and listener in web.xml :

    <listener>
        <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
    </listener>
 
    <filter>
        <filter-name>log4jServletFilter</filter-name>
        <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>log4jServletFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
        <dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
    </filter-mapping>

path of log4j2.xml should be /WEB-INF/log4j2.xml After this while we change logger level it will not restart the tomcat service.



来源:https://stackoverflow.com/questions/62808700/how-to-change-logger-level-in-log4j2-xml-at-runtime-without-restarting-tomcat-se

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!