Details
-
Improvement
-
Resolution: Unresolved
-
Critical
-
None
-
1.2.3
-
None
-
Any environment
Description
If we define 3 async appenders:
<appender name="ConsoleInfoAppenderAsync" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>5000</queueSize> <discardingThreshold>0</discardingThreshold> <appender-ref ref="ConsoleInfoAppender" /> <includeCallerData>true</includeCallerData> </appender> <appender name="ConsoleDebugAppenderAsync" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>5000</queueSize> <discardingThreshold>0</discardingThreshold> <appender-ref ref="ConsoleDebugAppender" /> <includeCallerData>true</includeCallerData> </appender> <appender name="ConsoleTraceAppenderAsync" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>5000</queueSize> <discardingThreshold>0</discardingThreshold> <appender-ref ref="ConsoleTraceAppender" /> <includeCallerData>true</includeCallerData> </appender> ...
Then define loggers:
<logger name="some.package" level="DEBUG" additivity="true"> <appender-ref ref="ConsoleDebugAppenderAsync" /> <appender-ref ref="ConsoleInfoAppenderAsync" /> </logger> <root level="INFO"> <appender-ref ref="ConsoleInfoAppenderAsync" /> </root>
And shutdown hook:
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook" />
On application shutdown we will have executed stop for 2 appenders:
ConsoleDebugAppenderAsync ConsoleInfoAppenderAsync
And related threads would be stopped.
But shutdown for third appender will be ignored (or just not executed):
ConsoleTraceAppenderAsync
In result their thread will exist and still working:
AsyncAppender-Worker-ConsoleTraceAppenderAsync
In case of web application deployed to tomcat we will see warning about this:
14-Jun-2019 18:03:43.568 WARNING [Thread-19] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [AsyncAppender-Worker-ConsoleTraceAppenderAsync] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.base@11/jdk.internal.misc.Unsafe.park(Native Method)
java.base@11/java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
java.base@11/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)
java.base@11/java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:417)
ch.qos.logback.core.AsyncAppenderBase$Worker.run(AsyncAppenderBase.java:289)
Would be nice to improve graceful shutdown process for this case.