log4j2异步日志首选asynclogger,基于lmax disruptor无锁队列,性能远超asyncappender;启用方式为配置log4j2.component.properties指定asyncloggercontextselector,或设置configuration的async="true"并确保logger未禁用异步。

Log4j2 配置异步日志主要靠 AsyncAppender 或更推荐的 异步 Logger(AsyncLogger),后者性能更高、开销更低,是 Log4j2 官方主推的方式。
启用异步 Logger(推荐)
Log4j2 的异步 Logger 基于 LMAX Disruptor 高性能队列,默认不依赖额外线程池,吞吐量远高于 AsyncAppender。启用方式很简单:
- 确保 classpath 下有
log4j-core和disruptor(Log4j2 2.17+ 已内置 disruptor,无需单独引入) - 在
log4j2.xml根节点添加属性: - 或者更明确地启用异步 Logger:
并确保 Logger 定义中未显式指定additivity="false"或async="false" - 所有
<logger></logger>和<root></root>默认就是异步的(只要全局 async="true" 且没禁用)
使用 AsyncAppender(兼容旧方式)
适合需要精细控制异步行为(如指定线程池、绑定特定 Appender)的场景,但性能略低:
- 先定义一个普通 Appender(比如 ConsoleAppender 或 RollingFileAppender)
- 再用
<asyncappender></asyncappender>包裹它:
-
includeLocation="false"建议关闭(获取行号等位置信息较耗时) - 在 Logger 中引用:
<appenderref ref="AsyncConsole"></appenderref>
关键注意事项
异步日志虽快,但有些行为和同步不同,需留意:
- 日志内容快照:异步 Logger 会在调用时刻拷贝日志参数(如对象 toString()),之后修改对象不影响已入队日志
-
异常堆栈可能截断:若开启
includeLocation="true",异步模式下无法准确获取调用类/行号,建议关闭或改用AsyncAppender + includeLocation="true"(仅对部分 Appender 有效) -
JVM 关闭时日志丢失风险:确保程序正常 shutdown(调用
LogManager.shutdown()),避免直接 kill 进程导致队列中日志未刷出 - 不要混用同步与异步 Logger:尤其避免在同一个 Logger 层级同时引用同步 Appender 和 AsyncAppender,逻辑易混乱
简单验证是否生效
启动应用后,查看日志输出中是否包含类似 AsyncLogger 或 AsyncAppender 的初始化信息;也可在高并发打印日志时观察线程名 —— 异步 Logger 日志通常由 AsyncAppender-1、disruptor-event-handler 等线程输出,而非业务线程名。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











