我是Log4j2的新手。我编写了一个简单的程序,实际上使用log4j2将数据记录到RollingRandomAccessFile中。以下是该计划:
public class Log4j2Example {
/**
* @param args the command line arguments
*/
public static Logger mlogger = null;
public static void main(String[] args) throws InterruptedException {
mlogger = LogManager.getLogger("Messages-log");
int i = 0;
while (true) {
String str = "Hello" + i;
System.out.println(str);
mlogger.info(str);
i++;
Thread.sleep(20);
}
}
}
我的log4j2.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<RollingRandomAccessFile name="Messages-log" fileName="Log4J/Messages-${date:yyyy-MM-dd}.log"
immediateflush="true" filePattern="Log4J/Messages-%d{MM-dd-yyyy-HH}-%i.log.gz">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="500 MB"/>
</Policies>
<DefaultRolloverStrategy max="50"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Logger name="Messages-log" level="info" additivity="false">
<appender-ref ref="Messages-log" level="info"/>
</Logger>
<root level="info">
<appender-ref ref="Messages-log"/>
</root>
</Loggers>
</Configuration>
我正在为日志文件写一个简单的语句,为每条记录休眠20毫秒。现在文件中的时间戳应该是例如: 如果第一个语句记录在17:20:32:354,则下一个语句应记录在17:20:32:374,但它记录的是17:20:32:384。每条记录都会额外增加11毫秒。下面是我的日志文件输出
2017-12-04 17:40:42.205 INFO Hello11
2017-12-04 17:40:42.236 INFO Hello12
2017-12-04 17:40:42.268 INFO Hello13
2017-12-04 17:40:42.299 INFO Hello14
2017-12-04 17:40:42.330 INFO Hello15
2017-12-04 17:40:42.361 INFO Hello16
2017-12-04 17:40:42.393 INFO Hello17
2017-12-04 17:40:42.424 INFO Hello18
您可以看到第一个语句记录为.205毫秒,第二个语句记录为.236毫秒。事实上,我正在睡眠线程20毫秒,因此正确的时间戳应为.226毫秒。我在这做错了什么?我需要写出准确的时间戳,因为它在制作中非常重要。我也用log4j 1尝试了这个但结果相同。我也将我的系统时间与互联网时间同步。有一件事我发现它可以在5毫秒和15毫秒的睡眠时间内完美地工作,但从20毫秒开始,这引起了一个大问题。
答案 0 :(得分:2)
我在这里做错了什么?
大多数缺陷的假设和期望:
appenders
。答案 1 :(得分:1)
我认为这不是由日志记录引起的。您可以通过将测试代码更改为以下(以排除日志记录)来验证这一点,并查看您是否得到了类似的结果:
public static void main(String[] args) throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss.SSS");
int i = 0;
while (true) {
System.out.println(format.format(new Date()) + " Hello " + i);
i++;
Thread.sleep(20);
}
}
正如Ralph在Log4j2-2141中指出的那样,很可能是你遇到了Windows调度程序的粒度。请参阅WinAPI Sleep() function call sleeps for longer than expected和https://forum.sysinternals.com/bug-in-waitable-timers_topic16229.html。