[
https://issues.apache.org/jira/browse/LOG4J2-555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13917419#comment-13917419
]
Remko Popma commented on LOG4J2-555:
------------------------------------
I keep thinking there must be a more robust way to achieve this... So far, the
best I've been able to come up with is instead of having a single FQCN, we can
have a {{Set}} of all FQCNs of the class hierarchy of loggers that extend
AbstractLogger. When a logger instance is constructed, it builds that Set in
the constructor, starting with {{getClass()}}, then keep calling
{{cls.getParent()}} until either {{AbstractLogger}} is found or {{null}}.
So for a generated extended logger the set would be { {{ExtendedLogger,
AbstractLoggerWrapper, AbstractLogger}} }, and for a "normal" logger obtained
from {{LogManager}} the set would be { {{core.Logger, AbstractLogger}} }.
Unfortunately this breaks down for custom loggers that don't extend from
{{AbstractLoggerWrapper}} but instead _have an_ {{AbstractLoggerWrapper}} field
that they delegate calls to. How to add the FQCN of such custom loggers to the
FQCN Set of the {{AbstractLoggerWrapper}} that they delegate to? (And wouldn't
this just move the problem: now custom logger authors need to remember to add
the custom logger FQCN to the FQCN Set of its {{AbstractLoggerWrapper}} field,
which is almost as bad as saying "don't use these methods, you can call only
this one"...) :-(
And then of course there is the cost-benefit trade-off: how much effort to
spend on this... Perhaps just updating the docs is good enough. I just wanted
to write my thoughts down, I may revisit this later.
> Location-based functionality broken in AbstractLoggerWrapper subclasses
> -----------------------------------------------------------------------
>
> Key: LOG4J2-555
> URL: https://issues.apache.org/jira/browse/LOG4J2-555
> Project: Log4j 2
> Issue Type: Bug
> Components: API, Core
> Affects Versions: 2.0-rc1
> Reporter: Remko Popma
> Assignee: Remko Popma
> Fix For: 2.0-rc2
>
>
> *How to reproduce*
> * Create a custom logger that extends {{AbstractLoggerWrapper}} (or generate
> one with the tool attached to LOG4J2-519)
> * 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.
> *Cause*
> {{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.
> *Solution*
> 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.
--
This message was sent by Atlassian JIRA
(v6.1.5#6160)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]