在打印日志时,为了提高当前线程的执行效率,一般会将需要打印的内容交由专门的日志线程进行打印,比如Logback中会使用AsyncAppender。
AsyncAppender配置说明
目录
1.队列容量配置
Logback使用BlockingQueue存放业务线程的打印内容,AsyncAppender会从此队列中取内容。队列默认大小为256,可使用参数如下进行配置。
<appender name="asyncAppLog" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>500</queueSize>
<appender-ref ref="appLog" />
</appender>
2.队列剩余容量的不同行为
默认情况下,当队列剩余容量小于总容量的20%时,日志级别<=INFO的内容将不会打印,只会打印WARN、ERROR级别的内容。可以设置如下参数改变默认配置:
<appender name="asyncAppLog" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>500</queueSize>
<appender-ref ref="appLog" />
</appender>
默认情况下,discardingThreshold 的值为:discardingThreshold = queueSize / 5
比如,queueSize=500,则discardingThreshold 的取值范围: 0 <= discardingThreshold <= 500。
discardingThreshold =0时,表示剩余容量在小于0%的时候,日志级别<=INFO的内容才不会打印;但剩余容量最少也只会等于0%,不会小于0%,所以在此情况下所有日志级别都会打印。
discardingThreshold =500时,表示剩余容量在小于100%的时候,日志级别<=INFO的内容不会打印;所以此情况下只会打印WARN、ERROR级别的内容。
3.队列满时会阻塞
当队列满了时,会阻塞业务线程,此时异步处理会变成同步等待;只有队列有可用容量时,业务线程才从阻塞状态恢复。
4.应用停止时清理队列
当LoggerContext
停止时,由于队列中还会有没有打印的日志内容,因此需要等待一段时间,等待队列处理完毕。配置参数如下:
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook">
<delay>1000</delay>
</shutdownHook>
单位是ms。如果队列较大,队列内容较多,可以将此值设置的较大。如果超过此时间队列中的日志还没有处理完毕,则队列中的日志将抛弃。
5.LoggerContext
停止方式
1)使用代码实现
在应用停止做收尾处理的时候添加如下代码:
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.stop();
2)在logback.xml中配置
此时会在JVM上注册一个Hook,当JVM停止时,会调用loggerContext.stop();
<shutdownHook />
3)在web容器环境
1.1.10以上版本提供了LogbackServletContainerInitializer,它已在logback-classic.jar中如下路径进行了配置,web容器会自动加载。当web容器停止时,也会自动loggerContext.stop();
/META-INF/services/javax.servlet.ServletContainerInitializer
参考文档