I aim to extend log4j in Spring Boot 3 to intercept log arguments and hide sensitive data when logging automatically. Since I had a difficult time to find a solution, I am opening and answering my own question, hoping it will help someone else.
Add the dependency org.apache.logging.log4j:log4j-api:2.24.2
.
Then create a custom LogFactory
class by extending org.apache.logging.log4j.message.MessageFactory2
and implement all the methods (yes, they are many but implementation is easy). Example:
class MyLogFactory : MessageFactory2 {
override fun newMessage(charSequence: CharSequence?): Message {
return charSequence?.let {
ParameterizedMessage(it.toString())
} ?: ParameterizedMessage("")
}
override fun newMessage(message: String?, p0: Any?): Message {
return ParameterizedMessage(
message,
hideSensitiveData(arrayOf(p0))
)
}
override fun newMessage(message: String?, p0: Any?, p1: Any?): Message {
return ParameterizedMessage(
message,
hideSensitiveData(arrayOf(p0, p1))
)
}
// and so on
}
Then when creating the logger, specific to use the custom LogFactory:
Logger log = LogManager.getLogger(MyCurrentClass.class, new MyLogFactory());
If you prefer to use the custom log factory by default for any class, then you can specify it by defining a file under resources named log4j2.properties
:
log4j2.loggerFactory=com.example.MyLogFactory