[ https://issues.apache.org/jira/browse/LOG4J2-519?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13917141#comment-13917141 ]
Ralph Goers commented on LOG4J2-519: ------------------------------------ logger.fatal, logger.error, etc all go straight to AbstractLogger, which is why you get the correct class name - the methods in AbstractLogger all use AbstractLogger as the FQCN. However, the logger.diag and logger.notice methods in Remko's example are all calling a logger.log method that does not contain an FQCN, which is why the caller info is wrong. > Custom/Extended Loggers > ----------------------- > > Key: LOG4J2-519 > URL: https://issues.apache.org/jira/browse/LOG4J2-519 > Project: Log4j 2 > Issue Type: New Feature > Components: API > Affects Versions: 2.0-rc1 > Reporter: Remko Popma > Attachments: Generate.java > > > {anchor:Extending} > *[#Extending] the Logger interface* > LOG4J2-41 added support for custom log Levels. Users can now log messages at > the new custom level by passing the custom level to the {{Logger.log()}} > method: > {code} > final Logger logger = LogManager.getLogger(); > final Level VERBOSE = Level.forName("VERBOSE", 550); > logger.log(VERBOSE, "a verbose message"); > logger.log(VERBOSE, "another message"); > {code} > However, custom levels are not as easy to use as the built-in levels: one > needs to call the generic {{log()}} method and pass a {{Level}} parameter. > Built-in levels on the other hand have a set of convenience methods on the > Logger interface. For example, the Logger interface has 14 debug methods that > support the DEBUG level: > {code} > debug(Marker, Message) > debug(Marker, Message, Throwable) > debug(Marker, Object) > debug(Marker, Object, Throwable) > debug(Marker, String) > debug(Marker, String, Object...) > debug(Marker, String, Throwable) > debug(Message) > debug(Message, Throwable) > debug(Object) > debug(Object, Throwable) > debug(String) > debug(String, Object...) > debug(String, Throwable) > {code} > Similar method sets exist for the other built-in levels. > Several people have expressed the desire to have the same ease of use with > custom levels, so after declaring a custom VERBOSE level, we would like to be > able to use code like this: > {code} > logger.verbose("a verbose message"); // no need to pass the VERBOSE level as > a parameter > logger.verbose("another message"); > {code} > {anchor:Customizing} > *[#Customizing] the Logger interface* > In the above use case, convenience methods were _added_ to the Logger > interface, in addition to the existing {{trace()}}, {{debug()}}, {{info()}}, > ... methods for the built-in log levels. > There is another use case, Domain Specific Language loggers, where we want to > _replace_ the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods with > all-custom methods. > For example, for medical devices we could have only {{critical()}}, > {{warning()}}, and {{advisory()}} methods. Another example could be a game > that has only {{defcon1()}}, {{defcon2()}}, and {{defcon3()}} levels. > Finally, if it were possible to hide existing log levels, users could > customize the Logger interface to match their requirements. Some people may > not want to have a {{FATAL}} or a {{TRACE}} level, for example. They would > like to be able to create a custom Logger that only has {{debug()}}, > {{info()}}, {{warn()}} and {{error()}} methods. > {anchor:wrapper} > *Proposal: Generate source code for a Logger [#wrapper]* > Common log4j usage is to get an instance of the {{Logger}} interface from the > {{LogManager}} and call the methods on this interface. This makes it hard to > achieve the above customization; especially taking away existing methods is > not possible. > An alternative is for the user to create a wrapper class that exposes only > the convenience methods for the desired log levels. When _extending_ the > {{Logger}} API (_adding_ methods), this wrapper class could subclass > {{org.apache.logging.log4j.spi.AbstractLoggerWrapper}}. When _customizing_ > the {{Logger}} API (_removing_ built-in methods), the wrapper class would > simply not extend AbstractLoggerWrapper, so the only public methods would be > the methods for the custom log levels. > As the custom log Levels are not known in advance, Log4J cannot provide > pre-built wrapper classes for these custom log Levels. However, we don't want > to ask the users to hand-code such a wrapper class: this is cumbersome and > error-prone: there are 14 methods for each built-in level. To provide > comparable functionality for custom log Levels one would need to provide 14 > methods for each custom log Level. > The proposal is to solve this by providing a tool that generates the source > code for a wrapper class. The user can specify: > * the fully qualified name of the class to generate > * the list of custom levels to support and their {{intLevel}} relative > strength > * whether to extend {{Logger}} (and keep the existing built-in methods) or > have only methods for the custom log levels > and the tool generates the source code for the wrapper class that has exactly > the required methods. Users would include this source code in the project > where they want to use custom log levels. > {anchor:GeneratedWrapperUsage} > Note that no Log4J API changes are required to support this functionality. > Users would create instances of the wrapper by calling a factory method on > the wrapper class, instead of calling the {{LogManager.getLogger()}} methods. > For example, instead of writing: > {code} > import org.apache.logging.log4j.Level; > import org.apache.logging.log4j.LogManager; > import org.apache.logging.log4j.Logger; > final Logger logger = LogManager.getLogger(MyClass.class); // standard log4j > logger > final Level VERBOSE = Level.forName("VERBOSE", 550); > logger.log(VERBOSE, "a verbose message"); > {code} > users would instead write: > {code} > // MyLogger is a generated customized logger wrapper > import com.mycompany.myproject.MyLogger; > final MyLogger logger = MyLogger.create(MyClass.class); > logger.verbose("a verbose message"); > {code} > Creating an extended or customized Logger is as easy as creating a standard > Logger (one line of code). Extended Loggers are drop-in replacements for > standard Loggers - they only add more convenience methods. -- This message was sent by Atlassian JIRA (v6.1.5#6160) --------------------------------------------------------------------- To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org