1.现在看到网上很多的方法说是在springboot启动时,配置如下环境变量:
我个人没有验证这种方法,但是我认为这个设置是不生效的,原因如下:
在springboot启动时,我们在console中可以看到日志的加载是优先于项目启动的,在springboot的main方法执行前,日志已经初始化完成了
所以完成主流的说法,我认为是错的
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector")
我来说说我的方法:
1.添加disruptor的以来
2. 在resources下加入log4j2.component.properties
文件
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
这样log4j2的异步就ok了
至于验证 :
可以打断点AsyncLoggerContext这个类的 **start()**方法,如果进入的是 这个方法就表示日志异步输出,否则就是进入了LoggerContext类中的start方法。
至于上面的配置原理,可以看源码 AsyncLoggerContextSelector类
public class AsyncLoggerContextSelector extends ClassLoaderContextSelector {
/**
* Returns {@code true} if the user specified this selector as the Log4jContextSelector, to make all loggers
* asynchronous.
*
* @return {@code true} if all loggers are asynchronous, {@code false} otherwise.
*/
public static boolean isSelected() {
return AsyncLoggerContextSelector.class.getName().equals(
PropertiesUtil.getProperties().getStringProperty(Constants.LOG4J_CONTEXT_SELECTOR));
}
@Override
protected LoggerContext createContext(final String name, final URI configLocation) {
return new AsyncLoggerContext(name, null, configLocation);
}
@Override
protected String toContextMapKey(final ClassLoader loader) {
// LOG4J2-666 ensure unique name across separate instances created by webapp classloaders
return "AsyncContext@" + Integer.toHexString(System.identityHashCode(loader));
}
@Override
protected String defaultContextName() {
return "DefaultAsyncContext@" + Thread.currentThread().getName();
}
}