We can’t no-op because the user is doing

public static Level NOTE = new Level(“NOTE”, 123){};

Of course, this will generate a new object, not return a preexisting one. The 
only way around this would be to use a Level factory pattern such as 

public static Level NOTE = Level.getOrCreateLevel(“NOTE”, 123);

I actually like that as it means the Level constructor can then be private.

I think it is worth it to make that change.

Ralph

On Jan 26, 2014, at 5:24 PM, Scott Deboy <scott.de...@gmail.com> wrote:

> Couldn't we no-op instead of throw if the same identical level were 
> registered?
> 
> If those levels were then added to the same custom level class from the 
> config, could we use that single class in the logger calls?
> On Jan 26, 2014 5:15 PM, "Ralph Goers" <ralph.go...@dslextreme.com> wrote:
> I am certain I could create a LevelPlugin that would allow you to define one 
> or more Levels in the configuration, but to use that Level the user would 
> have to code:
> 
> logger.log(Level.toLevel(“DIAG”), “hello world”);
> 
> In order to directly reference the level it has to be declared as a static 
> from somewhere and it can only be instantiated a single time, so creating it 
> from the configuration will prevent that.
> 
> Ralph
> 
> On Jan 26, 2014, at 4:03 PM, Scott Deboy <scott.de...@gmail.com> wrote:
> 
>> I have one goal: to remove my request for new built in levels by allowing 
>> the levels to be defined strictly via configuration. I agree there may be 
>> some hurdles but that's my goal.
>> 
>> I'd like to avoid the requirement that users provide their own level 
>> implementation or use a different API.
>> 
>> Scott
>> On Jan 26, 2014 3:52 PM, "Nick Williams" <nicho...@nicholaswilliams.net> 
>> wrote:
>> Generating a logger /interface/ is going to be hard. Sure, writing the code 
>> automatically will be a piece of cake. But then what do we do with that 
>> code? The user needs to program against it. So we have to have a 
>> command-line utility or Maven/Ant plug-in to generate the source 
>> pre-compile. However, since the vast majority of users are using IDEs, those 
>> IDEs will still warn them about the interface not existing until they have 
>> run the utility to generate the source.
>> 
>> I think a better approach would be to 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(Marker, Message)
>> void(Marker, Message, Throwable t)
>> void(Marker, Object)
>> void(Marker, Object, Throwable t)
>> void(Marker, String)
>> void(Marker, String, Object...)
>> void(Marker, String throwable)
>> void(Message)
>> void(Message, Throwable t)
>> void(Object)
>> void(Object, Throwable t)
>> void(String)
>> void(String, Object...)
>> void(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.
>> 
>> Make sense?
>> 
>> N
>> 
>> On Jan 26, 2014, at 5:32 PM, Scott Deboy wrote:
>> 
>>> Yes that's what I was thinking.
>>> 
>>> Scott
>>> 
>>> On Jan 26, 2014 3:18 PM, "Remko Popma" <remko.po...@gmail.com> wrote:
>>> Scott,
>>> The way I interpreted Gary's idea was that based on user-specified custom 
>>> levels, we would generate an extension of the Logger interface that has a 
>>> method for each of the custom levels (well, actually 14 methods for each 
>>> level :-) ).
>>> I haven't really thought about how users would specify their custom levels, 
>>> as long as the tool can know what methods to generate. 
>>> 
>>> We could go one step further and generate the Level subclass from 
>>> configuration as well. I suppose that would entail adding a new <Levels> 
>>> element, with sub-elements like <Level name="DETAIL" intLevel="450" />... 
>>> Is that what you are thinking of?
>>> 
>>> I would be fine with that too, but would like to first focus on generating 
>>> the extended Logger interface.
>>> 
>>> 
>>> 
>>> On Mon, Jan 27, 2014 at 5:29 AM, Scott Deboy <scott.de...@gmail.com> wrote:
>>> Is there a way to generate code/update the Levels enumeration so a new
>>> Level class isn't required?
>>> 
>>> Would be great to be able to use logger.detail("Detail message");
>>> 
>>> Is that what you're thinking of, Remko?
>>> 
>>> On 1/26/14, Ralph Goers <ralph.go...@dslextreme.com> wrote:
>>> > I haven’t done anything to directly do that. However, custom levels need 
>>> > to
>>> > be mapped to the standard levels in several places. It would be simple to
>>> > add support for that wherever you want it.  Level.StdLevel.getStdLevel() 
>>> > is
>>> > the method used to do that.
>>> >
>>> > Ralph
>>> >
>>> > On Jan 26, 2014, at 7:45 AM, Scott Deboy <scott.de...@gmail.com> wrote:
>>> >
>>> >> Are these serialization-wise going to be the same as standard levels?
>>> >>
>>> >> Receivers and apps like Chainsaw would benefit from not requiring the
>>> >> originating level class be included in the classpath.
>>> >>
>>> >> I'm thinking about socketreceiver and to a lesser extent
>>> >> logfilepatternreceiver.
>>> >>
>>> >> Scott
>>> >> On Jan 26, 2014 7:28 AM, "Scott Deboy" <scott.de...@gmail.com> wrote:
>>> >> So I assume we could build on this by adding the ability to generate 
>>> >> these
>>> >> custom levels from the config, with no user provided class required?
>>> >>
>>> >>
>>> >>
>>> >> On Jan 26, 2014 12:58 AM, "Ralph Goers" <ralph.go...@dslextreme.com>
>>> >> wrote:
>>> >> >
>>> >> > I have completed the work on custom levels.  It uses a variation of
>>> >> > Nick’s “extensible enum” class.  The major difference with what he
>>> >> > proposed is that the custom enums must be declared in a class annotated
>>> >> > with @Plugin(name=“xxxx” category=“Level”) for them to be usable during
>>> >> > configuration.
>>> >> >
>>> >> > Are their any objections to me checking this in?  I’ll be doing the
>>> >> > commit at around noon Pacific Daylight Time if I don’t hear any.
>>> >> >
>>> >> > Ralph
>>> >> >
>>> >> >
>>> >> >
>>> >> > On Jan 25, 2014, at 7:08 AM, Ralph Goers <ralph.go...@dslextreme.com>
>>> >> > wrote:
>>> >> >
>>> >> >> I am working on the implementation of custom levels now.  I should 
>>> >> >> have
>>> >> >> it done today.
>>> >> >>
>>> >> >> Ralph
>>> >> >>
>>> >> >> On Jan 24, 2014, at 7:07 PM, Remko Popma <remko.po...@gmail.com>
>>> >> >> wrote:
>>> >> >>
>>> >> >>> What is the best way to make progress on the custom levels
>>> >> >>> implementation?
>>> >> >>>
>>> >> >>> Do we re-open LOG4J-41 or start a fresh Jira ticket? For
>>> >> >>> implementation ideas, do we attach files to Jira, or create a branch?
>>> >> >>>
>>> >> >>> Remko
>>> >> >>>
>>> >> >>> On Saturday, January 25, 2014, Gary Gregory <garydgreg...@gmail.com>
>>> >> >>> wrote:
>>> >> >>>>
>>> >> >>>> On Fri, Jan 24, 2014 at 11:48 AM, Remko Popma 
>>> >> >>>> <remko.po...@gmail.com>
>>> >> >>>> wrote:
>>> >> >>>>>
>>> >> >>>>> 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.
>>> >> >>>>
>>> >> >>>>
>>> >> >>>> Hello All:
>>> >> >>>>
>>> >> >>>> Absolutely not. See my DEFCON example.
>>> >> >>>> Talking about an "extensible enum" is mixing design and
>>> >> >>>> implementation, we are talking about 'custom' and/or 'extensible'
>>> >> >>>> levels.
>>> >> >>>> Custom/Extensible levels can be designed to serve one or all of:
>>> >> >>>>
>>> >> >>>> - Allow inserting custom levels between built-in levels.
>>> >> >>>> - Allow for domain specific levels outside of the concept of 
>>> >> >>>> built-in
>>> >> >>>> levels, the DEFCON example.
>>> >> >>>> - Should the custom levels themselves be extensible?
>>> >> >>>>
>>> >> >>>> Gary
>>> >> >>>>
>>> >> >>>>>
>>> >> >>>>> 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 co
>>> >> >>>>
>>> >> >>>>
>>> >> >>>>
>>> >> >>>>
>>> >> >>>> --
>>> >> >>>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
>>> >> >>>> Java Persistence with Hibernate, Second Edition
>>> >> >>>> JUnit in Action, Second Edition
>>> >> >>>> Spring Batch in Action
>>> >> >>>> Blog: http://garygregory.wordpress.com
>>> >> >>>> Home: http://garygregory.com/
>>> >> >>>> Tweet! http://twitter.com/GaryGregory
>>> >> >>
>>> >> >>
>>> >> >
>>> >
>>> >
>>> 
>>> ---------------------------------------------------------------------
>>> 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