[
https://issues.apache.org/jira/browse/LOG4J2-3152?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17405866#comment-17405866
]
Volkan Yazici commented on LOG4J2-3152:
---------------------------------------
Given the following Log4j configuration:
{code:xml}
<Configuration status="OFF">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<JsonTemplateLayout>
<EventTemplateAdditionalField key="message"
value='{"$resolver":"message"}' format="JSON"/>
</JsonTemplateLayout>
</Console>
</Appenders>
<Loggers>
<Root level="TRACE">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
{code}
Below JUnit 5 test in the Log4j source code
{code:java}
@Test
@LoggerContextSource("LOG4J2-3152-log4j2.xml")
void LOG4J2_3152() {
Logger logger = LogManager.getLogger();
logger.info(new ObjectMessage(Collections.singletonMap("foo", "bar")));
logger.info(new MapMessage<>(Collections.singletonMap("foo", "bar")));
}
{code}
produces the following output:
{code:json}
{"@timestamp":"2021-08-27T15:06:20.749Z","ecs.version":"1.2.0","log.level":"INFO","message":{"foo":"bar"},"process.thread.name":"ForkJoinPool-1-worker-9","log.logger":"org.apache.logging.log4j.layout.template.json.JsonTemplateLayoutAdditionalFieldTest"}
{"@timestamp":"2021-08-27T15:06:20.749Z","ecs.version":"1.2.0","log.level":"INFO","message":{"foo":"bar"},"process.thread.name":"ForkJoinPool-1-worker-9","log.logger":"org.apache.logging.log4j.layout.template.json.JsonTemplateLayoutAdditionalFieldTest"}
{code}
Note that I needed to override the {{message}} field in {{EcsLayout}} (the
default template used by {{JsonTemplateLayout}}) to avoid its {{"stringified":
true}} flag.
> JSONLayout - Add mechanism for registering additional modules (i.e.
> JodaModule)
> -------------------------------------------------------------------------------
>
> Key: LOG4J2-3152
> URL: https://issues.apache.org/jira/browse/LOG4J2-3152
> Project: Log4j 2
> Issue Type: Improvement
> Components: Layouts
> Affects Versions: 2.14.0
> Reporter: Andy Lehane
> Priority: Minor
>
> When I attempt to use a JsonLayout with the following configuration:
> {{<JsonLayout compact="true" eventEol="true" properties="true"
> objectMessageAsJsonObject="true" />}}
>
> and log an object with a Joda LocalDateTime property, I get the following
> exception:
>
> {{2021-08-26 15:48:30,437 Log4j2-TF-67-AsyncLoggerConfig-6 ERROR
> com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Joda date/time
> type `org.joda.time.LocalDateTime` not supported by default: add Module
> "com.fasterxml.jackson.datatype:jackson-datatype-joda" to enable handling
> (through reference chain:
> org.apache.logging.log4j.core.layout.AbstractJacksonLayout$LogEventWithAdditionalFields["logEvent"]->org.apache.logging.log4j.core.impl.Log4jLogEvent["message"]->com.mycompany.StartEvent["timeStamp"])2021-08-26
> 15:48:30,437 Log4j2-TF-67-AsyncLoggerConfig-6 ERROR
> com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Joda date/time
> type `org.joda.time.LocalDateTime` not supported by default: add Module
> "com.fasterxml.jackson.datatype:jackson-datatype-joda" to enable handling
> (through reference chain:
> org.apache.logging.log4j.core.layout.AbstractJacksonLayout$LogEventWithAdditionalFields["logEvent"]->org.apache.logging.log4j.core.impl.Log4jLogEvent["message"]->com.mycompany.StartEvent["timeStamp"])}}
> {{ at
> com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)}}
> {{ at
> com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)}}
> {{ at
> com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
> at
> com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
> }}
> {{ at
> com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:3126)
> }}
> {{ at
> com.fasterxml.jackson.core.base.GeneratorBase.writeObject(GeneratorBase.java:388)
> }}
> {{ at
> org.apache.logging.log4j.core.jackson.ObjectMessageSerializer.serialize(ObjectMessageSerializer.java:44)
> }}
> {{ at
> org.apache.logging.log4j.core.jackson.ObjectMessageSerializer.serialize(ObjectMessageSerializer.java:33)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.serializeAsField(SimpleBeanPropertyFilter.java:208)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFieldsFiltered(BeanSerializerBase.java:822)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanSerializer.serialize(UnwrappingBeanSerializer.java:136)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter.serializeAsField(UnwrappingBeanPropertyWriter.java:127)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
> }}
> {{ at
> com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
> }}
> {{ at
> com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1514)
> }}
> {{ at
> com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1215)
> }}
> {{ at
> com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1059)
> }}
> {{ at
> org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:344)
> }}
> {{ at
> org.apache.logging.log4j.core.layout.JsonLayout.toSerializable(JsonLayout.java:291)
> }}
> {{ at
> org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:292)
> }}
> {{ at
> org.apache.logging.log4j.core.layout.JsonLayout.toSerializable(JsonLayout.java:68)
> }}
> {{ at
> org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:52)
> }}
> {{ at
> org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:308)
> }}
> {{ at
> org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:210)
> }}
> {{ at
> org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:37)
> }}
> {{ at
> org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197)
> }}
> {{ at
> org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:190)
> }}
> {{ at
> org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:181)
> }}
> {{ at
> org.apache.logging.log4j.core.appender.RollingFileAppender.append(RollingFileAppender.java:312)
> }}
> {{ at
> org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
> }}
> {{ at
> org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
> }}
> {{ at
> org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
> }}
> {{ at
> org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
> }}
> {{ at
> org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:543)
> }}
> {{ at
> org.apache.logging.log4j.core.async.AsyncLoggerConfig.callAppenders(AsyncLoggerConfig.java:127)
> }}
> {{ at
> org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:502)
> }}
> {{ at
> org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:485)
> }}
> {{ at
> org.apache.logging.log4j.core.async.AsyncLoggerConfig.log(AsyncLoggerConfig.java:121)
> }}
> {{ at
> org.apache.logging.log4j.core.async.AsyncLoggerConfig.logToAsyncLoggerConfigsOnCurrentThread(AsyncLoggerConfig.java:169)
> }}
> {{ at
> org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor.java:112)
> }}
> {{ at
> org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor.java:98)
> }}
> {{ at
> com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:169)
> }}
> {{ at
> com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:126) }}
> {{ at java.lang.Thread.run(Thread.java:748)}}
> {{ }}
> Looking through both the log4j2 documentation and code, there is no mechanism
> for being able to add further modules to the Jackson ObjectMapper object that
> the JsonAppender uses, i.e:
> {{public Log4jJsonObjectMapper(final boolean encodeThreadContextAsList, final
> boolean includeStacktrace, final boolean stacktraceAsString, final boolean
> objectMessageAsJsonObject) {}}
> {{{{ this.registerModule(new
> Log4jJsonModule(encodeThreadContextAsList,}}}}{{{{ includeStacktrace,
> stacktraceAsString, objectMessageAsJsonObject));}}}}
> {{ *{{this.registerModule(new JodaModule());}}*}}
> {{{{ this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);}}}}
> {{}}}
>
> Perhaps the config could look something like:
>
> {{<JsonLayout compact="true" eventEol="true" properties="true"
> objectMessageAsJsonObject="true">}}
> {{ <module class="com.fasterxml.jackson.datatype.joda.JodaModule">}}
> {{</JsonLayout>}}
>
> I've been able to work around this by creating my own versions of the
> following classes:
> - JSONLayout,
> - JacksonFactory,
> - Log4jJsonObjectMapper
> but this is not ideal as it's brittle to internal log4j changes.
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)