Asynchronous 混合同步/异步日志记录log4j不工作
我试图分析和实现混合同步和异步日志记录。我正在使用SpringBoot应用程序和DisruptorAPI。我的log4j配置:Asynchronous 混合同步/异步日志记录log4j不工作,asynchronous,logging,synchronization,log4j2,mixed,Asynchronous,Logging,Synchronization,Log4j2,Mixed,我试图分析和实现混合同步和异步日志记录。我正在使用SpringBoot应用程序和DisruptorAPI。我的log4j配置: <?xml version="1.0" encoding="UTF-8"?> <Configuration status="debug"> <Appenders> <Console name="Console-Appender" target
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>>
</PatternLayout>
</Console>
</Appenders>
<Loggers>
<AsyncLogger name="com.example.logging" level="debug">
<AppenderRef ref="Console-Appender"/>
</AsyncLogger>
<Root level="info">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
[%-5level]%d{yyyy-MM-dd HH:MM:ss.SSS}[%t]%c{1}-%msg%n
>
演示类1:
package com.example.logging;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@SpringBootApplication
public class DemoApplication2 {
static Logger logger = LogManager.getLogger(DemoApplication2.class);
public static void main(String[] args) {
SpringApplication.run(DemoApplication2.class, args);
long startTime = System.currentTimeMillis();
for(int i = 0; i < 2000; i++) {
logger.debug("Async : " + i);
}
System.out.println("time taken:: " + (System.currentTimeMillis() - startTime));
}
}
package com.example.logging;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.autoconfigure.springboot应用程序;
导入org.apache.logging.log4j.Logger;
导入org.apache.logging.log4j.LogManager;
@SpringBoot应用程序
公共类DemoApplication2{
静态记录器Logger=LogManager.getLogger(DemoApplication2.class);
公共静态void main(字符串[]args){
run(DemoApplication2.class,args);
long startTime=System.currentTimeMillis();
对于(int i=0;i<2000;i++){
调试(“异步:+i”);
}
System.out.println(“所用时间::”+(System.currentTimeMillis()-startTime));
}
}
使用上面的代码,我希望“System.out”应该在所有“debug”语句的日志记录之前打印出来,因为我在“debug”级别使用异步日志记录。因此,将首先记录几个调试器日志(例如,几个100或150),然后打印SOP,然后记录其余调试器日志。但是,当我运行我的应用程序时,所有的调试器语句都会首先记录,然后SOP会打印出预期的结果。
此外,如果在“asynclogger”(
)中使用additivity=“false”,则可以看到预期的上述结果。现在我有第二个演示课:
package com.example.logging;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@SpringBootApplication
public class DemoApplication3 {
static Logger logger = LogManager.getLogger(DemoApplication3.class);
public static void main(String[] args) {
SpringApplication.run(DemoApplication3.class, args);
long startTime = System.currentTimeMillis();
for(int i = 0; i < 2000; i++) {
logger.info("Sync : " + i);
}
System.out.println("time taken:: " + (System.currentTimeMillis() - startTime));
}
}
package com.example.logging;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.autoconfigure.springboot应用程序;
导入org.apache.logging.log4j.Logger;
导入org.apache.logging.log4j.LogManager;
@SpringBoot应用程序
公共类DemoApplication3{
静态记录器Logger=LogManager.getLogger(DemoApplication3.class);
公共静态void main(字符串[]args){
run(DemoApplication3.class,args);
long startTime=System.currentTimeMillis();
对于(int i=0;i<2000;i++){
logger.info(“同步:+i”);
}
System.out.println(“所用时间::”+(System.currentTimeMillis()-startTime));
}
}
现在在上面的课程中,我希望所有的同步日志都是先记录的,SOP应该在所有的信息日志之后打印出来。但如果将“additivity=”false“添加到我的配置中,那么所有日志都是异步的
最后,我无法同时配置同步和异步日志记录。请提供帮助和建议。我不确定您认为您正在测试什么 启用可添加性时,日志事件将被复制并放置到中断器的环形缓冲区中,在该缓冲区中它将路由到另一个线程上的控制台附加程序。将复制的事件放置到缓冲区中后,事件将传递到根日志记录器并路由到同一线程中的控制台附加程序。因为异步日志记录器和同步记录器正在做同样的事情,它们将在大约相同的时间内完成。因此,我不太确定为什么您认为在发出System.out调用时会留下任何东西 当您仅使用异步记录器时,主线程除了在队列中放置事件之外什么都不做,因此它将更快地响应,并且很可能在写入所有日志事件之前出现System.out消息
我怀疑您忽略了一条非常重要的信息。当事件路由到记录器时,会检查记录器关联的LoggerConfig上指定的级别。当additivity为true时,事件不会路由到父记录器(没有)。它被路由到LoggerConfig的父LoggerConfig。LoggerConfig调用isFiltered(事件),它只检查LoggerConfig上配置的筛选器。因此,即使您具有level=“info“在根记录器上,通过AsyncLogger发送给它的调试事件仍将被记录。您必须向RootLogger添加一个ThresholdFilter来防止这种情况。这真是太完美了!当我将“ThresholdFilter”添加到“”记录器(见下文)时,我可以看到预期的结果。非常感谢!