Gary,

The hard-coded levels were proposed because it seemed that the extensible
enum idea raised by Nick was not going to be accepted.
My original position was that Markers could fulfill the requirement but
Nick and yourself made it clear that this was not satisfactory.

With extensible enums and markers off the table it seemed that the
hard-coded levels was the only alternative, and discussion ensued about
what these levels should be called and what strength they should have.

During this discussion, several people, including me, repeatedly expressed
strong reservations about adding pre-defined levels, but by this time I
think people were thinking there was no alternative.

It looked like we were getting stuck, with half the group moving in one
direction ("add pre-defined levels!") and the other half wanting to move in
another direction ("don't add pre-defined levels!"). I asked that we
re-reviewed our assumptions and try to reach a solution that would satisfy
all users.

We then decided to explore the option of using extensible enums again. This
is still ongoing, but I haven't seen anyone arguing against this idea since
we started this thread.

Hard-coded levels and the extensible enum are different solutions to the
same problem.
The extensible enum solution satisfies all of us who are opposed to adding
pre-defined levels, while also satisfying the original requirement raised
by Nick and yourself. Frankly I don't understand why you would still want
the pre-defined levels.

Remko



On Sat, Jan 25, 2014 at 12:53 AM, Gary Gregory <garydgreg...@gmail.com>wrote:

> On Thu, Jan 23, 2014 at 10:45 PM, Remko Popma <remko.po...@gmail.com>wrote:
>
>> Gary,
>>
>> I think that's a very cool idea!
>> Much more flexible, powerful and elegant than pre-defined levels could
>> ever be.
>>
>
> As I wrote: "I am discussing custom levels here with the understanding
> that this is a separate topic from what the built-in levels are."
>
> I'm not sure why you want to make the features mutually exclusive. (Some)
> others agree that these are different features.
>
> I see two topics:
>
> - What are the default levels for a 21st century logging framework. Do we
> simply blindly copy Log4j 1? Or do we look at frameworks from different
> languages and platforms for inspiration?
> - How (not if, I think we all agree) should we allow for custom levels.
>
> Gary
>
> It definitely makes sense to design the extensible enum with this
>> potential usage in mind.
>>
>> Remko
>>
>>
>> On Friday, January 24, 2014, Gary Gregory <garydgreg...@gmail.com> wrote:
>>
>>> I am discussing custom levels here with the understanding that this is a
>>> separate topic from what the built-in levels are. Here is how I convinced
>>> myself that custom levels are a “good thing”.
>>>
>>> No matter which built-in levels exits, I may want custom levels. For
>>> example, I want my app to use the following levels DEFCON1, DEFCON2,
>>> DEFCON3, DEFCON4, and DEFCON5. This might be for one part of my app or a
>>> whole subsystem, no matter, I want to use the built-in levels in addition
>>> to the DEFCON levels. It is worth mentioning that if I want that feature
>>> only as a user, I can “skin” levels in a layout and assign any label to the
>>> built-in levels. If I am also a developer, I want to use DEFCON levels in
>>> the source code.
>>>
>>>
>>> At first, my code might look like:
>>>
>>>
>>> logger.log(DefconLevels.DEFCON5, “All is quiet”);
>>>
>>>
>>> Let’s put aside for now the type of DefconLevels.DEFCON* objects. I am a
>>> user, and I care about my call sites.
>>>
>>>
>>> What I really want of course is to write:
>>>
>>>
>>> defconLogger.defcon5(“All is quiet”)
>>>
>>>
>>> Therefore, I argue that for any “serious” use of a custom level, I will
>>> wrap a Logger in a custom logger class providing call-site friendly methods
>>> like defcon5(String).
>>>
>>>
>>> So now, as a developer, all I care about is DefConLogger. It might wrap
>>> (or subclass) the Log4J Logger, who knows. The implementation of
>>> DefConLogger is not important to the developer (all I care is that the
>>> class has ‘defconN’ method) but it is important to the configuration
>>> author. This tells me that as a developer I do not care how DefConLogger is
>>> implemented, with custom levels, markers, or elves. However, as
>>> configuration author, I also want to use DEFCON level just like the
>>> built-in levels.
>>>
>>>
>>> The configuration code could allow hiding the fact that markers (or
>>> elves) are used so that the configuration looks like a normal
>>> configuration. Maybe a markerLevel attribute is used, who knows. The point
>>> is that this is now getting too complicated and too clever. Bottom line:
>>> real custom levels (not hidden through markers and definitively not elves)
>>> are needed to cleanly implement the custom level feature.
>>>
>>>
>>> Now, I am convinced that custom levels are needed and useful.
>>>
>>>
>>> Next up is how to implement them, a different story… but still based on
>>> the fact that I want a DefConLogger class, that’s my user story. First, the
>>> obvious, it would be nice to have:
>>>
>>>
>>> public enum DefConLevel { DEFCON1, DEFCON2, DEFCON3, DEFCON4, DEFCON5 }
>>>
>>>
>>> The order would determine the precedence from most to least important
>>> level. The enum might not be strictly needed (at first at least) since I
>>> 80/20 care about methods on DefConLogger, not how it works internally.
>>>
>>>
>>> So how do I write DefConLogger?
>>>
>>>
>>> Wouldn’t it be nice to be able to write:
>>>
>>>
>>> @CustomLogger(levels=DefConLevel.class)
>>> public class DefConLogger {}
>>>
>>>
>>> And have Log4J generate the boiler plate code (If you have the right
>>> magic hooked up in your IDE)? It might generate bytecodes directly, not
>>> sure. There are all sorts of code BC and generation possibilities with ASM,
>>> BCEL or a code generator.
>>>
>>>
>>> That still leaves the implementation TDB but then it really does not
>>> matter how we do it, as long as we do the dirty work for the user.
>>>
>>>
>>> Well, we care about the implementation on this ML of course.
>>>
>>>
>>> Gary
>>>
>>>
>>> On Wed, Jan 22, 2014 at 10:05 PM, Paul Benedict <pbened...@apache.org>wrote:
>>>
>>>> As Gary wanted, a new thread....
>>>>
>>>> First, each enum needs an inherit strength. This would be part of the
>>>> interface. Forgive me if the word "strength" is wrong; but it's the 100,
>>>> 200, 300, etc. number that triggers the log level. So make sure the
>>>> interface contains the intLevel() method.
>>>>
>>>> Second, we need to know the name, right? The name probably requires a
>>>> new method since it can't be extracted from the enum anymore.
>>>>
>>>> public interface Level {
>>>> int intLevel();
>>>> String name();
>>>> }
>>>>
>>>> PS: The intStrength() name seems hackish. What about strength() or
>>>> treshold()?
>>>>
>>>> Third, the registration can be done manually by providing a static
>>>> method (as your did Remko) that the client needs to invoke, or you could
>>>> have a class-path scanning mechanism. For the latter, you could introduce a
>>>> new annotation to be placed on the enum class.
>>>>
>>>> @CustomLevels
>>>> public enum MyCustomEnums {
>>>> }
>>>>
>>>> Paul
>>>>
>>>> On Wed, Jan 22, 2014 at 8:52 PM, Remko Popma <remko.po...@gmail.com>wrote:
>>>>
>>>>> Paul, can you give a bit more detail?
>>>>>
>>>>> I tried this: copy the current Level enum to a new enum called
>>>>> "Levels" in the same package (other name would be fine too). Then
>>>>> change Level to an interface (removing the constants and static methods,
>>>>> keeping only the non-static methods). Finally make the Levels enum
>>>>> implement the Level interface.
>>>>>
>>>>> After this, we need to do a find+replace for the references to
>>>>> Level.CONSTANT to Levels.CONSTANT and Level.staticMethod() to
>>>>> Levels.staticMethod().
>>>>>
>>>>> Finally, the interesting part: how do users add or register their
>>>>> custom levels and how do we enable the Levels.staticLookupMethod(String,
>>>>> Level) to recognize these custom levels?
>>>>>
>>>>>
>>>>>
>>>>> On Thursday, January 23, 2014, Paul Benedict <pbened...@apache.org>
>>>>> wrote:
>>>>>
>>>>>> Agreed. This is not an engineering per se, but really more about if
>>>>>> the feature set makes sense.
>>>>>>
>>>>>> Well if you guys ever look into the interface idea, you'll give log4j
>>>>>> the feature of getting enums to represent custom levels. That's pretty
>>>>>> cool, IMO. I don't know if any other logging framework has that and that
>>>>>> would probably get some positive attention. It shouldn't be so hard to 
>>>>>> do a
>>>>>> find+replace on the code that accepts Level and replace it with another
>>>>>> name. Yes, there will be some minor refactoring that goes with it, but
>>>>>> hard? It shouldn't be.
>>>>>>
>>>>>> A name I propose for the interface is LevelDefinition.
>>>>>>
>>>>>> Paul
>>>>>>
>>>>>>
>>>>>> On Wed, Jan 22, 2014 at 6:48 PM, Gary Gregory <garydgreg...@gmail.com
>>>>>> > wrote:
>>>>>>
>>>>>> Hi, I do not see this as an engineering problem but more a feature
>>>>>> set definition issue. So while there may be lots of more or less 
>>>>>> internally
>>>>>> complicated ways of solving this with interfaces, makers and whatnots, 
>>>>>> the
>>>>>> built in levels are the most user friendly.
>>>>>>
>>>>>> I have have lots of buttons, knobs and settings on my sound system
>>>>>> that I do not use, just like I do not use all the methods in all the
>>>>>> classes in the JRE...
>>>>>>
>>>>>> Gary
>>>>>>
>>>>>>
>>>>
>>>
>>>
>>> --
>>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
>>> Java Persistence with Hibernate, Second 
>>> Edition<http://www.manning.com/bauer3/>
>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>> Spring Batch in Action <http://www.manning.com/templier/>
>>> Blog: http://garygregory.wordpress.com
>>> Home: http://garygregory.com/
>>> Tweet! http://twitter.com/GaryGregory
>>>
>>
>
>
> --
> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
> Java Persistence with Hibernate, Second 
> Edition<http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>

Reply via email to