问题
I'm looking to log the request and response to a web service. I'm using slf4j with underlying log4j2 implementation. My logger statement looks like the below.
LOGGER.info("{}",new CustomObject(request,response,param1,param2));
I have implemented the toString methods in all the necessary objects and in the CustomObject class to log all attributes of that object.
I see that the toString method of the CustomObject is called before it passes the log message to the Asynch logger.
Is there anyway that the serialization / toString method call of the custom object be deferred to when the actual logging takes place?
回答1:
This is by design: if an Object is logged it's possible that it is mutated before the background thread can log it, and you would end up with a log entry different from what you intended.
In your example your application doesn't hold a reference to the CustomObject, so it cannot change, but Log4j2 can't know that, so it takes the conservative approach.
There is a system property to switch this off, but using it means all objects logged must be effectively immutable or you will find your logs are lying to you... (I'm also not 100% sure that the system property still works since Log4j2 became garbage free in version 2.6.)
Update (2017-12-09): the system property still works in post 2.6 versions. (But I would not recommend rendering the message in the background thread unless you are very confident that the application doesn’t modify the objects that were logged.)
来源:https://stackoverflow.com/questions/43259076/slf4j-log4j-converts-objects-to-string-before-passing-to-asynchronus-logger