18

In log4j.properties I can set PatternLayout e.g. ("[%p] %c - %m - %d %n")

Is there any symbol (%something) which returns current time in milliseconds?

alicjasalamon
  • 4,171
  • 15
  • 41
  • 65
  • Is there a reason why you need to capture log time in milliseconds? Logs are printed in order of execution anyway. – Rajesh J Advani Aug 01 '12 at 10:38
  • @RajeshJAdvani I try to gather logs from distributed system and calculate time difference between them. I need reliable information when the log was generated. – alicjasalamon Aug 01 '12 at 10:41

4 Answers4

26

You can try this one.

log4j.appender.appender_name.layout=org.apache.log4j.PatternLayout
log4j.appender.appender_name.layout.ConversionPattern=%d %p [%c] - %m%n

Date params %d. For example : %d{HH:mm:ss,SSS}.

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html

turankonan
  • 1,011
  • 6
  • 13
  • 4
    Do not use PatternLayout! Fraught with concurrency issues and doesn't always like exception statements. The answer is EnhancedPatternLayout. – ingyhere Nov 29 '13 at 19:27
20

There is no Log4J symbol that does exactly what you want.

%d returns the current date with a given pattern, defined by a SimpleDateFormat (the pattern you put between the brackets), but doesn't give you the time in millis.

%r gives the number of milliseconds since the start of execution.

One possible way of achieving what you want is to extend the behaviour of Log4j, it's quite a bit more complex, but if it's absolutely necessary... here you go:

Customize log4j (edit: no longer online?)
Customize log4j (edit: 2018 alternative)

Edit: Keep in mind that, from your comment, if you need to figure out time differences between executions in different machines, you have to make sure the clocks of the machines are synchronized, or it'll be leading you to wrong conclusions.

el-teedee
  • 1,293
  • 1
  • 15
  • 27
pcalcao
  • 15,789
  • 1
  • 44
  • 64
  • 11
    I don't agree that this is not possible. The %d symbol actually works as the default is to show milliseconds, while you can configure it to turn it off. Sample time: 01 Aug 2012 17:41:53,357. Symbol used: %d{dd MMM yyyy HH:mm:ss,SSS} – Rajesh J Advani Aug 01 '12 at 12:14
  • 2
    That's milliseconds as part of the date, not the date in milliseconds. It's completely different. From the original question, what the OP was asking for was for a way to print a timestamp *in* milliseconds. Read before downvoting please. – pcalcao Aug 01 '12 at 12:26
  • Ok, agreed. I'd like to remove my downvote, but can't since too much time has gone by. But if the OP needs to compare the logs from multiple systems, (s)he can still use the time WITH milliseconds and do the calculation on their own - givenDateFormat.parse(dateString).getTime(). It would be simpler than extending log4j and would work on previously generated log files too. – Rajesh J Advani Aug 02 '12 at 06:04
  • @Rajesh: Date processing in Log4j uses Java's horribly slow Date api. Literally, multiple milliseconds or tens of milliseconds can be shaved off the execution time for each log statement by grabbing System.currentTimeMillis(). This is expecially useful for people who log to DBs as they can then farm off the date computations where they might actually be faster! – ingyhere Nov 29 '13 at 19:25
14

Try this,

   %d{dd MMM yyyy HH:mm:ss,SSS}
Sai Ye Yan Naing Aye
  • 6,622
  • 12
  • 47
  • 65
5

You should be able to use %d{UNIX_MILLIS} From the manual:

%d{UNIX} outputs the UNIX time in seconds. %d{UNIX_MILLIS} outputs the UNIX time in milliseconds. The UNIX time is the difference, in seconds for UNIX and in milliseconds for UNIX_MILLIS, between the current time and midnight, January 1, 1970 UTC. While the time unit is milliseconds, the granularity depends on the operating system (Windows). This is an efficient way to output the event time because only a conversion from long to String takes place, there is no Date formatting involved.

thegeko
  • 1,382
  • 1
  • 13
  • 18
  • The manual also says %d{ISO8601} to get ISO 8601, but that isn't the case either, so I'm not sure I can trust it anymore. – Hakanai Jun 28 '17 at 05:40
  • very very perfect solution – Alireza Apr 30 '19 at 10:19
  • `Could not instantiate SimpleDateFormat with UNIX` `Could not instantiate SimpleDateFormat with UNIX_MILLIS` `java.lang.IllegalArgumentException: Illegal pattern character 'U'` It seems there are three explicit cheks for `ABSOLUTE`, `DATE`, and `ISO8601`, and if its neither of those, the string is passed to `SimpleDateFormat` verbatim. – Mark Jeronimus Jan 31 '20 at 08:12
  • Great! Thanks so much. But note that it must be version 2.x (the one that exposed security vulnerabilities some time ago) – Rick Dou Mar 16 '22 at 04:23