Search code examples
javajsonlog4j

Log4J2: JsonTemplateLayout timestamp format problem


I jave a log4j timestamp formatting problem, any help will be appreciated.

Using JsonTemplateLayout and following xml config, I am trying, with no success, to achieve timestamp formatting like so: 2020-02-07T13:38:47.098+02:00(Notice the : char at +02:00):

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="ConsoleJSONAppender" target="SYSTEM_OUT">
          <JsonTemplateLayout eventTemplateUri="classpath:log4j2.json"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="com.my.logger" additivity="false" level="debug">
            <AppenderRef ref="ConsoleJSONAppender"/>
        </Logger>
    </Loggers>
</Configuration>

According to the Timestamp Resolver manual the default format is the one I need, but the parsed format looks like this:

2020-02-07T13:38:47.098+0200. (Notice the missing colon char at +0200)

Following is a snippet from my eventTemplate JSON using default formatting and resulting to the format above.

  "timestamp": {
    "$resolver": "timestamp"
  }

Using the ISO8601_OFFSET_DATE_TIME_HHCMM of FixedDateFormat.FixedFormat enum also leads to formatting without : at +02:00:

"timestamp": {
    "$resolver": "timestamp",
    "format": "%d{ISO8601_OFFSET_DATE_TIME_HHCMM}"
  }

Strangely, using the format from ISO8601_OFFSET_DATE_TIME_HHCMM which is yyyy-MM-dd'T'HH:mm:ss,SSSXXX, I get exception:

Unable to invoke factory method in class org.apache.logging.log4j.layout.template.json.JsonTemplateLayout for element JsonTemplateLayout:
java.lang.IllegalStateException:
No factory method found for class org.apache.logging.log4j.layout.template.json.JsonTemplateLayout java.lang.IllegalStateException:
No factory method found for class org.apache.logging.log4j.layout.template.json.JsonTemplateLayout
"timestamp": {
    "$resolver": "timestamp",
    "pattern": {
      "format": "yyyy-MM-dd'T'HH:mm:ss,SSSXXX",
      "timeZone": "UTC"
    }
  }

Solution

  • [The IllegalStateException is due to a bug introduced in version 2.15.0 and solved in 2.19.0 (cf. LOG4J2-3614). Upgrade to version 2.20.0 to get rid of it]

    Log4j2 uses multiple date formatters: Apache Commons' FastDateFormat, Log4j's FixedDateFormat (an optimalized version of the first one) and Java's DateTimeFormatter.

    The default JSON Template Layout is yyyy-MM-dd'T'HH:mm:ss.SSSZZZ, where the time zone part is interpreted as:

    • sign + 2 digits + colon + 2 digits by FastDateFormat
    • sign + 4 digits by DateTimeFormatter.

    Due to some changes in version 2.15.0 the semantics of the pattern switched from FastDateFormat to DateTimeFormatter. I have reported it as Github issue #1420.

    To maintain the previous behavior you need to use:

    "timestamp": {
        "$resolver": "timestamp",
        "pattern": {
          "format": "yyyy-MM-dd'T'HH:mm:ss.SSSxxx"
        }
    }
    

    An XXX pattern would output Z instead of +00:00.