You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Ceki Gulcu <cg...@urbanet.ch> on 2001/01/23 13:19:25 UTC

RE: DOMConfigurator.configureAndWatch w/multiple async appenders

At 12:25 23.01.2001 +0100, Mark Masterson wrote:
>Ceki,
>
> >> when an existing category is redefined in the new config file, then the
>configurator removes all existing appenders attached to that category<<
>
>No, I guess I don't see.  Conceptually, isn't this what I'm doing? When I
>change the category definition to point to the package level instead of the
>method level?  By doing so, am I not indicating that I want to "redefine"
>the configuration of the existing category so that DEBUG is set at the top
>of the Category hierarchy, instead of the bottom?
>
>Moreover, I still don't grasp why the root seems to be getting re-defined,
>and not the category that I explicitly touch.  You seem to be saying that by
>making a change in the config file to my category, the appenders attached to
>root get removed and re-attached.  That's kind of strange -
>counterintuitive, if you like -- if that is, in fact, what's happening.

OK. Let me give you an example.

Assume that at T0, your config file defines the categories root and x.y.z. 
By defining I mean attaching appenders and setting the priority of a category.

At a later time, T1, you define categories root and x.y. Both the 
PropertyConfigurator and the DOMConfigurator will remove all appenders 
attached to root and attach the appenrders as defined in the new config 
file. The "x.y" will be configured by removing all appenders (there are 
none) attaching any defined appenders and setting the priority as defined 
by the new config file. The category "x.y.z" remains untouched. In 
particular, the appenders that were atatched to "x.y.z" at T0 remain as you 
defined them at T0.

This is what happens. I am not saying it's intuitive I am just describing 
the current behavior. Does this description correspond to what you are 
observing? Please keep aside your reservations about the wisdom of the 
approach.

>On a more generic level, it might be worth considering changing this, if
>only to make the behavior of "configureAndWatch" equivalent to the behavior
>of statically re-loading the config file by re-starting the app and using
>"configure".  On a high level, it seems to me like these two alternative
>"use cases", if you will, ought to result in equivalent behavior, or?

Unfortunately what makes sense and seems natural in one case seems exactly 
the contrary in different contexts. Read on.

>Finally, I'm a pragmatist - can you suggest any alternative that I might be
>able to use to achieve the desired behavior with the existing
>"configureAndWatch"?  Short of writing a MyDOMConfigurator, I mean, which is
>already running through my head... :-)

OK. There is a very easy solution that will require just a few lines of code.
Here is a copy of  what PropertyConfigurator.configureAndWatch does:

   static
   public
   void configureAndWatch(String configFilename, long delay) {
     PropertyWatchdog pdog = new PropertyWatchdog(configFilename);
     pdog.setDelay(delay);
     pdog.start();
   }

You can see that all PropertyConfigurator.configureAndWatch does is to 
delegate work to a new PropertyWatchdog.
Here is the code of PropertyWatchdog:
-----------------------------------------------------------------------------------------------------------------------
class PropertyWatchdog extends FileWatchdog {

   PropertyWatchdog(String filename) {
     super(filename);
   }

   /**
      Call {@link PropertyConfigurator#configure(String)} with the
      <code>filename</code> to reconfigure log4j. */
   public
   void doOnChange() {
     new PropertyConfigurator().doConfigure(filename, 
Category.defaultHierarchy);
   }
}
----------------------------------------------------------------------------------------------------------------------------

You can see that PropertyWatchdog extends FileWatchdog which does most of 
the work in the background. The PropertyWatchdog overrrides the doOnChange 
method of FileWatchdog. This method is called by FileWatchdog whenever the 
config file changes.

The behavior you want is to reset the configuration before reconfiguring. 
The configuration can be reset by calling the 
BasicConfigurator.resetConfiguration method. Here is a custom watchdog that 
will do exactly this:


-----------------------------------------------------------------------------------------------------------------------
class CustomWatchdog extends FileWatchdog {

   CustomWatchdog(String filename) {
     super(filename);
   }

   public
   void doOnChange() {
     BasicConfigurator.resetConfiguration();
     new PropertyConfigurator().doConfigure(filename, 
Category.defaultHierarchy);
   }
}
-----------------------------------------------------------------------------------------------------------------------

All you need to do is to invoke your custom watchdog. For example:

     CustomWatchdog cdog = new CustomWatchdog(configFilename);
     cdog.setDelay(20000); // check every 30 seconds
     cdog.start();


Let us know if this solves the issue. Cheers, Ceki




----
Ceki Gülcü (cgu@urbanet.ch)


RE: DOMConfigurator.configureAndWatch w/multiple async appenders

Posted by Mark Masterson <ma...@compuserve.com>.
Ceki,

>> This is what happens. I am not saying it's intuitive I am just describing
the current behavior. Does this description correspond to what you are
observing? Please keep aside your reservations about the wisdom of the
approach.<<

Yes.  This is exactly what I'm seeing.  I understand now.  However, I still
think it's kind of weird.  I guess what's bothering me is that it seems to
contradict the basic philosophy of Log4J as expressed in the Category
hierarchy and the additivity principle.  When you say:

>> The "x.y" will be configured by removing all appenders (there are none)
attaching any defined appenders and setting the priority as defined by the
new config file. The category "x.y.z" remains untouched.<<

I think to myself, "But, gee, I thought that this was exactly the sort of
the thing that this additivity property was supposed to be controlling."
IOW, as long as I've got additivity set to true, changes I make at the top
of the hierarchy ought to percolate down.  And in fact, as long as I'm
willing to stop and restart my app, and not use the "configureAndWatch"
functionality, this seems to be exactly how things work.  And *that*
discrepancy constitutes my only possible criticism.  At the risk of
repeating myself, from a design viewpoint, things that do superficially
identical things should produce identical results.  That doesn't seem to be
the case here.

Also, I do understand that the implementation of the Category hierarchy is
not a doubly-linked list, or the equivalent, and that you actually build
from the bottom up.  I've made it far enough into the docs to grasp this,
and suspect it may be involved in making it hard for you to implement what I
seem to be asking for.  At least I think I've grasped it - the docs on
Hierarchy seem a little unclear.  :-)

Please don't misunderstand me; I'm still much too new to Log4J to presume to
comment on the "wisdom" of any part of it, I think.  I understand that some
situations demand the behavior as is.  For example, I understand what Anders
means, when he says

<< Because it's not always desirable. You may want to configure part of the
Category namespace using one config file, and another part using another
config file. In that case you want the additive behaviour. >>

It seems to me, however, that we're talking about a situation where there
are clearly two separate, contradictory implementations possible, and where
*both* could be conceivably desirable.  Doesn't that sound like a
description of a method that needs a parameter to distinguish between these
possibilities?  The problem, as I see it now, is that there is no
parameter - you've got it hard-coded for "no reset".  Which alternative is
wiser, i.e. which reflects more the everyday usage by the typical user, is
not relevant.  The point is, both are probably needed, but only one is
available.  Or to put it another way, you said:

<< Unfortunately what makes sense and seems natural in one case seems
exactly the contrary in different contexts. >>

to which I would respond, "Well, gee, if nothing else, just the traffic this
thread generated would seem to justify an assertion that, in fact, there is
a clear need for the implementation to support multiple contexts."

FWIW, BTW, the suggestions from some other folks re.
BasicConfigurator.resetConfiguration(); don't help me, as far as I can tell,
although I understand them.  The problem is, I'd need a way to get a mere
change in the config file to invoke this, and I don't see how that could be
done.  Understand: we are striving for a) zero programmatic configuration,
and b) total control from the config file.

Anyway, thanks very much for the suggested code.  That was very gracious of
you, and I appreciate it.  Yes, I'm sure this will work.  I was already on
the way there, and you've saved me a good bit of time.

Cheers,
Mark