log4j:当前时间的毫秒数

18
log4j.properties 中,我可以设置 PatternLayout,例如 ("[%p] %c - %m - %d %n")
是否有任何符号(%something)可以返回当前时间的毫秒数?

你需要以毫秒为单位记录日志时间的原因是什么?无论如何,日志都按执行顺序打印。 - Rajesh J Advani
@RajeshJAdvani 我正在尝试从分布式系统中收集日志,并计算它们之间的时间差。我需要可靠的信息来确定日志生成的时间。 - alicjasalamon
5个回答

26

4
不要使用PatternLayout!它存在并发问题,并且有时不支持异常语句。答案是EnhancedPatternLayout。 - ingyhere

20

目前没有符合你需求的Log4J符号。

%d 返回当前日期,并由SimpleDateFormat定义给定模式(括号中的模式),但不提供毫秒级别的时间。

%r 返回自执行开始以来的毫秒数。

实现你所需功能的一种可能方法是扩展Log4j的行为,尽管这样会变得更加复杂,但如果绝对必要......请参考以下链接:

自定义log4j(编辑:不再在线?)
自定义log4j (编辑:2018年可选)

编辑:请注意,根据您的评论,如果您需要计算不同机器上执行之间的时间差,请确保机器的时钟已经同步,否则会导致错误结论。


11
我不同意这是不可能的说法。符号 %d 实际上的默认显示单位是毫秒,但你可以配置它来关闭毫秒的显示。举个例子时间:2012年8月1日17时41分53.357秒。所使用的符号是:%d{dd MMM yyyy HH:mm:ss,SSS}。 - Rajesh J Advani
2
这里的毫秒是日期的一部分,而不是以毫秒为单位的日期。两者完全不同。从原始问题来看,OP想要的是一种以毫秒为单位打印时间戳的方法。请在点踩之前先阅读。 - pcalcao
好的,同意。我想撤销我的反对票,但是时间过去太久了,所以无法撤销。但是如果 OP 需要比较多个系统的日志,则仍然可以使用带毫秒的时间,并在自己的计算中进行计算 - givenDateFormat.parse(dateString).getTime()。这比扩展 log4j 更简单,并且也适用于先前生成的日志文件。 - Rajesh J Advani
@Rajesh:Log4j中的日期处理使用Java的可怕缓慢Date API。实际上,通过获取System.currentTimeMillis()可以削减每个日志语句的执行时间多个毫秒或十多个毫秒。对于那些将日志记录到数据库的人来说,这是非常有用的,因为他们可以将日期计算分配给可能更快的地方! - ingyhere

14

试试这个:

   %d{dd MMM yyyy HH:mm:ss,SSS}

5
您应该能够使用%d{UNIX_MILLIS},根据手册

%d{UNIX}输出UNIX时间(以秒为单位)。%d{UNIX_MILLIS}输出UNIX时间(以毫秒为单位)。UNIX时间是当前时间和协调世界时1970年1月1日午夜之间的差异,对于UNIX为秒,对于UNIX_MILLIS为毫秒。虽然时间单位是毫秒,但粒度取决于操作系统(Windows)。这是一种有效的输出事件时间的方法,因为只进行从长整型到字符串的转换,没有涉及日期格式化。


手册还说可以使用%d{ISO8601}来获取ISO 8601格式,但实际上并不是这样的,所以我不确定我是否还能信任它。 - Hakanai
非常完美的解决方案 - Alireza
无法使用UNIX实例化SimpleDateFormat 无法使用UNIX_MILLIS实例化SimpleDateFormat java.lang.IllegalArgumentException: 非法的模式字符'U' 似乎有三个明确的检查ABSOLUTEDATEISO8601,如果不是这些,则将字符串逐字传递给SimpleDateFormat - Mark Jeronimus
太好了!非常感谢。但请注意,它必须是2.x版本(曾在一段时间内暴露安全漏洞的那个版本)。 - Rick Dou

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接