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

Reply via email to