[
https://issues.apache.org/jira/browse/LOG4J2-3152?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17405859#comment-17405859
]
Andy Lehane commented on LOG4J2-3152:
-------------------------------------
I'm giving the conversion from POJO -> MapMessage(Map) using Jackson
ObjectMapper (converting to from POJO -> JSON -> Map, not ideal but if this
works, I'll see whether it's possible to go directly from POJO -> Map in one
operation if that work).
Using a MapMessage(Map) using the messageParameter resolver results in just
[""] being generated:
{{{"@version":1,"source_host":"localhost","message":[""],"thread_name":"Tester","@timestamp":"2021-08-27T15:08:54.227+01:00","level":"INFO","logger_name":"Test.Logger","node":"localhost"}}}
Adding the map enties using the MapMessage.setProperty method, gets a little
closer but does not generate valid JSON as part of the whole logging event:
{{{"@version":1,"source_host":"localhost","message":["eventHeader:\{eventType=START,
timeStamp=2021-08-27T14:14:15.636Z, node=test,
version=1.0}\n"],"thread_name":"Tester","@timestamp":"2021-08-27T15:14:16.071+01:00","level":"INFO","logger_name":"Test.Logger","node":"localhost"}}}
Using the "message" resolver with a MapMessage(map), produces the same output
as the "messageProperty" resolver and using the message properties, i.e:
{{{"@version":1,"source_host":"localhost","message":["eventHeader:\{eventType=START,
timeStamp=2021-08-27T14:14:15.636Z, node=test,
version=1.0}\n"],"thread_name":"Tester","@timestamp":"2021-08-27T15:14:16.071+01:00","level":"INFO","logger_name":"Test.Logger","node":"localhost"}}}
I think I need to revert back to using my local implementation of the
JsonLayout that has the JodaModule loaded and then keep an eye on the
Improvement Jira call you've mentioned above and take that if/when it gets
implemented.
If you have any further ideas, I'm willing to give them a shot.
> 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)