Description
Context
Logback ILoggingEvent
(source) has two important fields / getter methods:
message
- contains the message template (e.g."Hello {}!"
)formattedMessage
- contains the final formatted/merged log message (e.g."Hello world!"
)
This distinction is useful -- for example, we use this to aggregate log messages and this works fine when we call SLF4J API directly.
However, we are now migrating to Kotlin and have started using kotlin-logging (Kotlin logging library on top of SLF4J). Kotlin logging supports constructing log messages with Kotlin-native String interpolation, like this:
logger.debug { "Some $expensive message!" }
This results in the log message "template" merged with log message arguments too early. I have a proposal for kotlin-logging to support passing in the log message "template" so I could implement a Kotlin compiler plugin that would collect the template from Kotlin source code and would pass it along with the formatted message.
Issue
Even if I pass the log message template to kotlin-logging, it cannot pass it on as SLF4J does not support such scenario -- SLF4J LoggingEvent
does not have a field for this. I guess SLF4J was designed to be the user-facing API and did not have a need to expose such low-level concepts in the API.
Proposal
Introduce a new field in SLF4J LoggingEvent
that would contain the (pre)formatted log message. Then the logger implementations can use it like this:
- in case the field is filled, it is used as-is for logging (e.g. Logback
ILoggingEvent.getFormattedMessage()
method). - in case the field is not filled, the current behaviour is followed (log message template is merged with the arguments).
This will make possible for me to implement something on top of KLogger
to fill that field properly.