How to reproduce
- Create a custom logger that extends AbstractLoggerWrapper (or generate one with the tool attached to
- In the custom logger provide a public method that invokes the log(Level, String) method
- Configure a pattern layout that uses location, like %C for the logger FQCN
- From a sample app, call the public method on your custom logger.
- The output will show the class name of the custom logger instead of the class name of the calling class in the sample application.
AbstractLogger's FQCN field is static final and initialized to AbstractLogger.class.getName(). Then, in Log4jLogEvent#calcLocation(), when walking over the stack trace elements, the element following the FQCN is returned. So only loggers that directly subclass from AbstractLogger will work correctly. Loggers that inherit from AbstractLoggerWrapper are two levels removed from AbstractLogger and the calcLocation() method will not work correctly.
I think AbstractLogger's FQCN field should be made non-static, and initialized to getClass().getName() in the constructor of AbstractLogger. Log4jLogEvent#calcLocation() can then be modified to return the StackElement whose class name matches the FQCN, instead of the next element. Location-based functionality should then work for arbitrarily deep subclass hierarchies of AbstractLogger.