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

Reply via email to