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 >>> >>> >> >