Hi msew,

At 09:17 14.03.2001 -0800, msew wrote:
>At 11:44 03/14/2001 +0100, Ceki Gülcü wrote:
>>Appender Additivity
>>====================
>>
>>The output of a log statement of category C will go to all the appenders in C and 
>its ancestors. This is the meaning of the term "appender additivity".
>>
>>However, if an ancestor of category C, say P, has the additivity flag set to false, 
>then C's output will be directed to all the appenders in C and it's ancestors upto 
>and including P but not the appenders in any of the ancestors of P.
>>
>>Categories have their additivity flag set to true by default.
>>========================================================
>
>yup read this and semi disagree on the implementation of it (theory is fine).
>
>
>While this make sense from the logical way of thinking about it,  it seems that when 
>you are actually working with your log config files  you will do something like the 
>following:
>
><!-- start of the RobotNetworkConnectionLobbyImpl -->
> <category name="foo.bar.common.network.RobotNetworkConnectionLobbyImpl">
> <priority value="debug" />
>  <appender-ref ref="defaultNetworkLogger" />
> </category>
><!-- end of the RobotNetworkConnectionLobbyImpl -->
>
>
>keeping your category object as a template with:  (note this template is poor but it 
>serves the purpose for now)
>
> <appender-ref ref="defaultNetworkLogger" />            ALWAYS with the object.
>
>
>ie later on down the road you want to EASILY and with little to no work / brain power 
>on your side change/add an appender to a category  you just want to change/add the 
>ref="<var>"    and voila you are done!

I strongly disagree with the above argument. You don't copy properties just so that 
you can have a template that you can change later. It is as if in a derived class we 
copied all the code from a super class just to have a template to modify. That's just 
wrong.


>Also it seems to me that once your config file becomes at all large / with other 
>people adding to it, the hierarchy of the appenders it going to get very complex and 
>possibly even intractable to understand :-)
>
>
>When this comes to be, then it seems a really nice idea to be able to do:
>
><!-- start of the RobotNetworkConnectionLobbyImpl -->
> <category name="foo.bar.common.network.RobotNetworkConnectionLobbyImpl">
> <priority value="debug" />
>  <appender-ref ref="defaultNetworkLogger" />
>  <appender-ref ref="foo" />
>  <appender-ref ref="bar" />
> </category>
><!-- end of the RobotNetworkConnectionLobbyImpl -->
>
>And we ALWAYS want to be additive because we don't know what is higher up on the 
>hierarchy that someone else made and is depending on being there.  But for our 
>current debugging session or for the next N days we want to log something specific, 
>we need to add a bunch of appenders which may or may not be the same as the ones 
>higher in the hierarchy.
>
>
>When this occurs, duplicates are inserted and results in numDups x output.    To me 
>this seems that the implementation should be more forgiving and not count duplicates 
>if they are inserted for that category.  (ie this results in NO functional change to 
>what is logged but allows the user to be really explicit in their categories).  The 
>assumption being here:  that you never want to log the same thing twice to an 
>appender (I can't ever think of a reason why you would want to do this).

That's true. Duplicates are probably always unwanted and can be considered as errors.

>Further, we are debugging the following:
>
>foo.bar.util   and we turn off additivity as the amount of data generated and being 
>emailed out to people is driving them insane.

OK. I assume that the SMTPAppender has been attached to a category higher up the 
hierarchy, say root or foo.bar. Right?

>in foo.bar.util.spank  we get the shaft as the inherited appenders from our parent  
>(foo.bar.util) has been turned off, even tho we still wanted all of the rest of the 
>classes to get the "normal" appenders, just not foo.bar.util.

Why on earth would you have an SMTPAppender on a site that was being debugged?

Moreover, category foo.bar.util that you are debugging is an ancestor of 
foo.bar.util.spank, you are not debugging foo.bar.util.spank? 

>so now to make things "work" we need to go and add all of the previously inherited 
>appenders to foo.bar.util.spank  and then remember to take them out again once we 
>turn additivity back on in foo.bar.util  .
>
>Further, some child class deep down is depending on some parent appender being there. 
> Sadly, someone decides that some high, in the hierarchy, category needs to be 
>changes to appender57!  The child NEEDS to have appender56.  Someone looked and 
>looked and just missed this fact and bad things occur.   With duplicates caught on 
>insert, the child could have explicitly stated that they NEED appender56 and if some 
>one changed parent's appenders, no worry.

Someone decided to *replace* appender56 with appender57. They should have known that 
appender57 is no substitute for appender56. No tool is a substitute for thinking.

>You could say:  just turn off additivity if you want to be explicit!  But that is 
>wrong as you really want the POWER of the inherited appenders being additive so you 
>can, over the entire project, turn on the uber logger!  Or add another type of logger 
>that everyone inherits.
>
>Also being 100% explicit is a maintenance nightmare.  But allowing specific 
>categories to explicitly state their appenders is a GREAT thing.

This is like saying "eating cake is great paying for it is less so." You can't have 
the cake and eat it too.


>To sum up:  I don't see any functional / result change from having the 
>DOMConfigurator check to see if an appender is already in the list for a specific 
>category.  If it is in the list then don't add it again. If it is not in the list 
>then add it.

OK. This is certainly feasible but not that easily. Remember that in log4j categories 
can be defined in any order. So you might be defining appenders for "x.y.z" first and 
redefine them in "x" a few moments later. This means that the removal of appenders 
needs to be done once the configuration is complete. The best algorithm I can think of 
is O(N^2) where N is the number of defined categories. It would cycle through all 
categories and check if there are duplicates. We could actually add such a duplicate 
removal method to DOMConfigurator and PropertyConfigurator.  

>And then because of this your life when making a category is much much easier, as you 
>can say: gee this category needs to have the following appenders: <long list of 
>appenders>   and you can be happy knowing that that list is the minimum set of 
>appenders (you may have more from the parents and you don't really care about them in 
>so much as you know that the parent will correctly log what is needed and you as 
>yourself are logging what you need, explicitly).

Although I disagree with most of the reasons you put forward, it is not up to me to 
impose the way you want to use log4j. Thus, I will add duplicate appender removal 
functionality to our TODO list. Regards, Ceki 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to