If we go the run-once tool route, then you might as well use annotation processing. I think it would support everything necessary to generate the appropriate custom logger class.
On 26 January 2014 23:00, Scott Deboy <scott.de...@gmail.com> wrote: > Of course, they'd have to use rhino, or something else...which doesn't > help. Where's duck typing when you need it :) > > On 1/26/14, Scott Deboy <scott.de...@gmail.com> wrote: > > Could we leverage Rhino? :) > > > > Scott > > > > On 1/26/14, Nicholas Williams <nicho...@nicholaswilliams.net> wrote: > >> Scott, invokedynamic and javassist...those are all /runtime/ things. The > >> user needs Logger#notice to be available at compile time. Those are not > >> compatible. > >> > >> Nick > >> > >> Sent from my iPhone, so please forgive brief replies and frequent typos > >> > >>> On Jan 26, 2014, at 22:37, Scott Deboy <scott.de...@gmail.com> wrote: > >>> > >>> Yes, I would like to declare in the config: > >>> > >>> Level: NOTICE, value: 232 > >>> > >>> And in Java code be able to use logger.notice("some message"). > >>> > >>> But I think that'd require invokedynamic..which would probably > >>> require..javassist/ASM? > >>> > >>> I'd be ok with anything that's really close to that :) > >>> > >>> Scott > >>> > >>> > >>>> On 1/26/14, Ralph Goers <ralph.go...@dslextreme.com> wrote: > >>>> Scott would like users to add a level definition to the logging > >>>> configuration and have everything else happen auto-magically. That > >>>> would > >>>> happen at run-time which is a bit late since the methods need to be > >>>> available at compile time. > >>>> > >>>> I believe Scott said he would be fine if users had to do > >>>> > >>>> logger.log(SomeClass.SomeLevel, "message); > >>>> > >>>> but even that requires "SomeClass" to be available at compile time. > >>>> > >>>> So what Scott says he would like and what Nick is proposing are two > >>>> different things. > >>>> > >>>> Ralph > >>>> > >>>> > >>>> > >>>>> On Jan 26, 2014, at 8:09 PM, Remko Popma <remko.po...@gmail.com> > >>>>> wrote: > >>>>> > >>>>> I actually thought that Nick's idea was the answer to that: users > >>>>> create > >>>>> a > >>>>> custom interface, something like this: > >>>>> > >>>>> public interface MyLogger extends Logger { > >>>>> @LoggingLevel(name="DIAG") > >>>>> void diag(String message); > >>>>> // optional other methods > >>>>> } > >>>>> > >>>>> They get an instance of this interface by calling: > >>>>> LogManager.getCustomLogger(MyLogger.class); > >>>>> > >>>>> LogManager has access to the processed configuration. The config has > >>>>> <Levels><Level name="DIAG" intValue="450"> elements. During > >>>>> configuration > >>>>> processing, the custom Level instances are created and registered, so > >>>>> on > >>>>> the first call to LogManager.getCustomLogger(MyLogger.class), the > >>>>> MyLogger > >>>>> instance is created and cached. Also, at this point the annotations > >>>>> are > >>>>> parsed to see what Level instance the MyLogger implementation will > >>>>> pass > >>>>> to > >>>>> the Logger.log(Level, String) method when the "diag" method is > called. > >>>>> > >>>>> What is still open in this scenario is how the instance is created. > >>>>> Proxy? > >>>>> Or generate source & compile? Or use a byte code library? > >>>>> > >>>>> On Monday, January 27, 2014, Ralph Goers <ralph.go...@dslextreme.com > > > >>>>> wrote: > >>>>> 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 > >>>>> <nicho...@nicholaswilliams.net> > >>>>> 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" > >>>>>>> <nicho...@nicholaswilliams.net> > >>>>>>> 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: log4j-dev-unsubscr...@logging.apache.org > >>>>>>> For additional commands, e-mail: log4j-dev-h...@logging.apache.org > >>> > >>> --------------------------------------------------------------------- > >>> To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org > >>> For additional commands, e-mail: log4j-dev-h...@logging.apache.org > >>> > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org > >> For additional commands, e-mail: log4j-dev-h...@logging.apache.org > >> > >> > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org > For additional commands, e-mail: log4j-dev-h...@logging.apache.org > > -- Matt Sicker <boa...@gmail.com>