I’m using slf4j and log4j2 as the implementation. I wanted my messages (in JSON) to be logged as JSON and not escaped as Strings.
Looking at the org.apache.logging.log4j.layout.template.json.resolver.MessageResolver
class, I see that it should work if I remove the stringified
tag in my template (JsonTemplateLayout
), which I did. But it doesn’t work.
While debugging the code, I can see that my Message is a MutableLogEvent
(and not a MultiformatMessage
or ObjectMessage
), so the MessageResolver
fallbacks to a default logging that escapes the quotes…
I’m not sure how log4j determines the type of message to use or if I need to log somehow differently, or configure something special to get this…
Adding some context: I’m one of the authors of Powertools for AWS Lambda (Java) and we provide a logging library on top of SLF4J (+log4j/logback implem). Objective is to let developers log simply and we handle the formatting and add some contextual data to the logs. We want to keep things lean and easy for developers.
2
Answers
I solved this using my own resolver, checking if the string is a valid json (using Jackson
readTree
function), then writing the raw String (without ") or using standard Strings otherwise.You are using SLF4J as logging API, which is more restrictive compared to the native API of Log4j Core: Log4j API.
In particular SLF4J does not allow to log
Object
s as messages and the best you can do is to pass it a formatString
and a list ofObject
arguments. This is why the SLF4J to Log4j API adapter only creates two kinds of messages: some kind ofParameterizeMessage
or some kind ofSimpleMessage
.In order to pass your objects to the Log4j API, without stringifying it, you must use the API directly.
Remark: Since the Log4j API is almost a strict superset of SLF4J (with a few exception discussed in #1813), you don’t lose any Logback capability if you employ the combination Log4j API + Logback. On the other hand you lose many features with the combination SLF4J + Log4j Core.