作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我执行以下代码时,日志事件仅记录一次。我正在使用 log4j2 记录器。但是当我使用 java.util.logger
时,所有 3 个日志事件均已成功发布。
public class TestLoggingMDC
{
public static void main( String[] args ) throws InterruptedException
{
System.setProperty( "log4j.configurationFile", "log4j2.xml" );//set path here to log4j2 config file
ExecutorService executor = Executors.newFixedThreadPool( 3 );
TestLoggingMDC testLoggingMDC = new TestLoggingMDC();
for ( int i = 0; i < 3; i++ )
{
Runnable runnableTask = testLoggingMDC::calculate;
executor.execute( runnableTask );
}
executor.awaitTermination( 5, TimeUnit.SECONDS );
}
public void calculate()
{
//java.util.logging.Logger.getLogger( "testMDC" ).info( "total is ..." );//this works. log 3 time
LogManager.getLogger( ).info( "total is ..." );//this does not
}
}
当我同步计算方法 public synchronized voidcalculate()
或获取类锁时,如下所示,它会按预期工作。
public void calculate()
{
synchronized ( LogManager.class )
{
LogManager.getLogger().info( "total is ..." );
}
}
log4j2是线程安全的,但似乎LogManager.getLogger()
不是线程安全的?或者我错过了什么?
请注意,我尝试在没有 ExecutorService
的情况下执行线程(使用 java.lang.Thread
),结果是相同的。
log4j2 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss,SSS} [%t] %-5p %c{36} - %m%n"/>
</Console>
<File name="fileAppender" fileName="out/MDCTest.log">
<PatternLayout>
<Pattern>%X{id} %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="ConsoleAppender"/>
</Root>
<Logger name="testMDC" level="ALL">
<AppenderRef ref="fileAppender"/>
</Logger>
</Loggers>
</Configuration>
最佳答案
它不是线程安全的。 Logger 不记录初始消息,因为它默认配置为 ERROR
级别,然后重新配置为 INFO
。您可以通过将 calculate()
中的日志记录方法从 info()
更改为 error()
来检查 - 您将收到全部 3 条消息。
要修复此问题,需要在干扰线程之前重新配置记录器。例如,您可以创建一个记录器字段:
private final Logger logger = LogManager.getLogger();
并在这样的计算方法中使用:
public void calculate() {
loger.info( "total is ..." );
}
此外,每次调用calculate()时,它都会通过getLogger()方法为您节省记录器分辨率。
希望有帮助。
关于java - log4j2 LogManager.getLogger() 是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51965928/
我是一名优秀的程序员,十分优秀!