I am going to have to echo what Nick said. If you can think of a way to make
logger.log(SomeClass.SomeLevel, “hello world”); work without actually creating SomeClass then please share! Ralph On Jan 26, 2014, at 7:45 PM, Nick Williams <[email protected]> wrote: > It would not be possible to do this strictly through configuration because > the user needs a compiled interface to code against. Where is that compiled > interface to come from? > > Nick > > On Jan 26, 2014, at 9:40 PM, Scott Deboy wrote: > >> If there is a way to support this strictly through configuration that would >> be ideal. >> >> I'm trying to find a way to remove my request for additional built in levels >> but through configuration instead of adding them ourselves. >> >> Scott >> Scott >> >> On Jan 26, 2014 7:38 PM, "Nick Williams" <[email protected]> >> wrote: >> Here's a split-off thread for discussing how we can make using custom levels >> easier. Some on the team have expressed a desire to make it even easier. >> Given hypothetical custom levels DIAG and NOTE, the following would be nice >> to have: >> >> logger.note("message"); >> logger.diag("message"); >> etc. >> >> We're to discuss how best to approach this. My proposal (from previous >> email): >> >> > Allow the user to define an interface that /must/ extend Logger. That >> > interface may contain any methods that match the following signatures (the >> > interface must have at least one method and there is no limit to the >> > number of methods it may have): >> > >> > void [methodName](Marker, Message) >> > void [methodName](Marker, Message, Throwable t) >> > void [methodName](Marker, Object) >> > void [methodName](Marker, Object, Throwable t) >> > void [methodName](Marker, String) >> > void [methodName](Marker, String, Object...) >> > void [methodName](Marker, String throwable) >> > void [methodName](Message) >> > void [methodName](Message, Throwable t) >> > void [methodName](Object) >> > void [methodName](Object, Throwable t) >> > void [methodName](String) >> > void [methodName](String, Object...) >> > void [methodName](String throwable) >> > >> > Each method /must/ be annotated with @LoggingLevel(name = "levelName"). >> > Now LogManager has a few new methods: >> > >> > <T extends Logger> T getCustomLogger(Class<T> loggerClass) >> > <T extends Logger> T getCustomLogger(Class<T> loggerClass, Class<?>) >> > <T extends Logger> T getCustomLogger(Class<T> loggerClass, Class<?>, >> > MessageFactory) >> > <T extends Logger> T getCustomLogger(Class<T> loggerClass, MessageFactory) >> > <T extends Logger> T getCustomLogger(Class<T> loggerClass, Object) >> > <T extends Logger> T getCustomLogger(Class<T> loggerClass, Object, >> > MessageFactory) >> > <T extends Logger> T getCustomLogger(Class<T> loggerClass, String) >> > <T extends Logger> T getCustomLogger(Class<T> loggerClass, String, >> > MessageFactory) >> > >> > The user can then obtain such a logger like so, etc.: >> > >> > MyLogger logger = LogManager.getCustomLogger(MyLogger.class); >> > >> > Log4j will generate an implementation of MyLogger that extends the default >> > implementation, cache that implementation so that it doesn't have to be >> > implemented again, and then instantiate/cache the logger instance like >> > normal. >> >> Others have suggested deriving the level name from the method name instead >> of using an annotation. That's a viable alternative. >> >> Matt Sicker asked: >> >> > And can't getCustomLogger also provide a default method that uses the >> > getClassName method? >> >> I think you misunderstand the purpose of the Class<T> argument. It has >> nothing to do with the logger name--it's the class of the Logger interface >> to automatically implement. >> >> Nick >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [email protected] >> For additional commands, e-mail: [email protected] >> >
