quarkus
quarkus copied to clipboard
Customizing the JSON logging formatter
Description
I use structured (JSON) logging quite a bit and need to be able to modify the properties of log records being generated by the application in order to be able to do filtering on log messages.
One specific example is for dealing with exceptions, where I'll pass enum based error codes into any thrown exception, with the enum name being automatically injected into a log record which logged that exception, like in the label
or errorCode
property. This allows for exceptions to be filtered / filtered out based on those error codes, making it a lot easier to go through logs. In theory MDC could be used for this, but it feels wrong to add a thread local error code just to have it show up in the one log record that actually prints the exception log.
With Logback this is fairly easy, and can be achieved by extending the JsonLayout class it uses. I looked into something similar with Quarkus, and while the JsonFormatter class seems to support this via the StructuredFormatter#before method as suggested here, there's no easy to extend the Quarkus JsonFormatter
because it's initialized directly in the recorder.
The feature request would be to either allow the quarkus-logging-json
extension to have alternative implementations (instances of JsonFormatter
) to be provided to be used by Quarkus to format JSON logs, or an alternative mechanism to augment log records, for example by overriding the before
method and running optional interceptors (provided via CDI) on the generator / log record.
Implementation ideas
Not super familiar with recorders and the way formatter creation is implemented right now, playing around with it, I wasn't able to create the JsonFormatter
instance with an @ApplicationScoped
JsonFormatterFactory
class that just creates a new instance and have that be injected into the recorder with a synthetic injection point.
If going with a more basic @Producer
based approach, then either the Formatter
beans could have @Default
on them allowing for overrides, or the existing JsonFormatter
class could override the before
method and take in a list of LogRecordInterceptor
implementations, which would be allowed to modify the log record before it's written. I'm not fully familiar with the potential impact in switching from recorders to producers though.