This part of the conversation should actually be happening in the "Using Custom Levels with a Custom/Wrapper Interface" thread.
Nick On Jan 27, 2014, at 12:17 PM, Gary Gregory wrote: > Yes that's the idea. > > Gary > > > -------- Original message -------- > From: Ralph Goers > Date:01/27/2014 11:19 (GMT-05:00) > To: Log4J Developers List > Subject: Re: Enums and Custom Levels - completed. > > If the user creates a custom Logger Wrapper then they can just code against > that and not use an interface, correct? > > Ralph > > On Jan 27, 2014, at 6:40 AM, Nick Williams <nicho...@nicholaswilliams.net> > wrote: > >> Wrapping a logger /implementation/ is fine. But the user needs an >> /interface/ to program against. That interface should extend Logger rather >> than re-define all of Logger's methods. >> >> Nick >> >> On Jan 27, 2014, at 8:24 AM, Gary Gregory wrote: >> >>> Please note that in the case of domain specific logging (DSL!), I do not >>> want to extend, I want to wrap a logger. See my DEFCON example. >>> >>> Gary >>> >>> >>> On Sun, Jan 26, 2014 at 6:51 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 >>>> >>>> >>> >>> >>> >>> >>> -- >>> 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 >> >