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 11:59:26 UTC

Re: DOMConfigurator.configureAndWatch w/multiple async appenders

Mark,

The problem is that log4j configurators do not  reset the existing 
configuration when reading a new configuration file.

The settings for categories that were defined previously but not in the 
current config file remain *untouched*. On the other hand, when an existing 
category is redefined in the new config file, then the configurator removes 
all existing appenders attached to that category. That is the reason behind 
the appender finalization messages you are seeing. Do you see?

This is perhaps not the best reconfiguration policy. You are welcome to 
suggest alternatives. Cheers, Ceki


At 10:59 23.01.2001 +0100, you wrote:
>Greetings,
>
>I'm struggling with the "configureAndWatch" method.  In our project, we want
>to do all logging asynch.  Additionally, we want to direct different
>severity levels to different targets (appenders), and we want to be able to
>use the Category hierarchy to vary the level of logging output.  I've got
>all this working great, with static configuration.  My problem is, when I
>try to use the "configureAndWatch" method (as opposed to just "configure",
>eh?), something's going wrong.  On the surface, it seems as if only the
>appenders that are attached to root are being re-initialized.  Here's the
>XML config file:
>
><?xml version="1.0" encoding="UTF-8"?>
><!DOCTYPE configuration SYSTEM "log4j.dtd">
>
><configuration configDebug="true">
>
>         <appender name="ASYNC_ROOT" class="org.apache.log4j.AsyncAppender">
>                 <appender-ref ref="STDOUT"/>
>                 <appender-ref ref="ERROR_LOG"/>
>         </appender>
>
>         <appender name="ASYNC_DEBUG" class="org.apache.log4j.AsyncAppender">
>                 <appender-ref ref="DEBUG_LOG"/>
>         </appender>
>
>         <appender name="ERROR_LOG" class="org.apache.log4j.FileAppender">
>                 <param name="File" value="error.log"/>
>                 <param name="Threshold" value="ERROR"/>
>                 <layout class="org.apache.log4j.PatternLayout">
>                      <param name="ConversionPattern"
>                             value="%d,%p,[%t],[%c],%m%n"/>
>                 </layout>
>         </appender>
>
>         <appender name="DEBUG_LOG" class="org.apache.log4j.FileAppender">
>                 <param name="File" value="debug.log"/>
>                 <param name="Threshold" value="DEBUG"/>
>                 <layout class="org.apache.log4j.PatternLayout">
>                      <param name="ConversionPattern"
>                             value="%d,%p,[%t],[%c],%x,%m%n"/>
>                 </layout>
>         </appender>
>
>         <appender name="STDOUT" class="org.apache.log4j.FileAppender">
>                         <param name="File" value="System.out" />
>                         <param name="Threshold" value="ERROR"/>
>                         <layout class="org.apache.log4j.PatternLayout">
>                         <param name="ConversionPattern"
>value="%d,%p,[%t],[%c],%x,%m%n"/>
>                         </layout>
>         </appender>
>
>         <category name="trace_test.TraceTestFrame.methodName" 
> additivity="true">
>                 <priority value="debug"/>
>                 <appender-ref ref="ASYNC_DEBUG"/>
>         </category>
>
>         <root>
>                 <priority value="error"/>
>                 <appender-ref ref="ASYNC_ROOT"/>
>         </root>
></configuration>
>
>In my code, I'm using Category objects per class, plus one extra Category in
>a specific method.  In the config above, I have things set up to limit debug
>output to this one method, and that works fine.  If I change the category
>definition in the config file, changing it from the FQN for the method, for
>example, to just the package name (i.e. from
>"trace_test.TraceTestFrame.methodName" to "trace_test"), and re-run the app,
>I get debug output from all of my Category objects.  Now, if I use
>"configureAndWatch" and change the lines as described above, this doesn't
>work.  If I start with the more restrictive variant (method name), and
>change to the looser one (package name), I expect to see all of the debug
>output being logged after the changed config file is re-loaded.  But this
>doesn't happen.
>
>Interestingly, with "configDebug=true", I see the following statements on
>the console after the re-initialization:
>log4j: Finalizing appender named [STDOUT].
>log4j: Finalizing appender named [ERROR_LOG].
>
>Note that these are the 2 appenders that are attached to the asynch appender
>that is attached to root.  There is no mention of "finalizing" the DEBUG_LOG
>appender that is attached to the other asynch appender that is attached to
>my category.
>
>Am I doing something wrong?  Is there in error in my config file?  Or have I
>stumbled over a bug?
>
>Thanks in advance.
>--Mark
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: log4j-user-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: log4j-user-help@jakarta.apache.org

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


Re: DOMConfigurator.configureAndWatch w/multiple async appenders

Posted by Ceki Gulcu <cg...@urbanet.ch>.
At 13:06 23.01.2001 +0100, you wrote:
>On Tue, 23 Jan 2001, Ceki Gulcu wrote:
>
>|
>| The problem is that log4j configurators do not  reset the existing
>| configuration when reading a new configuration file.
>
>Why not?

Because that is not the desired behavior at all times. Resetting the 
configuration at all times would make it hard if not impossible to 
configure without resetting. Does that make better sense?

>I have asked for a "resetConfig()" function before, since I also find this
>counter intuitive. What's the rationale for this? How's the reload of a
>config supposed to work if you actually cannot properly reconfigure the
>system?

Er... there is already the BasicConfigurator.resetConfiguration method. It 
has been there for quite some time. Maybe this should be a FAQ item. 
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



RE: DOMConfigurator.configureAndWatch w/multiple async appenders

Posted by Ceki Gulcu <cg...@urbanet.ch>.
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,

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

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?

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... :-)

Cheers,
Mark



Re: DOMConfigurator.configureAndWatch w/multiple async appenders

Posted by Endre Stølsvik <En...@Stolsvik.com>.
On Tue, 23 Jan 2001, Anders Kristensen wrote:

| > I have asked for a "resetConfig()" function before, since I also find this
| > counter intuitive. What's the rationale for this? How's the reload of a
| > config supposed to work if you actually cannot properly reconfigure the
| > system?
|
| >From javadoc comment to PropertyConfigurator.doConfigure:
|
|   "The existing configuration is not cleared nor reset. If you require a
| different call, behaviour, then call [BasicConfigurator.]
| resetConfiguration method before calling doConfigure."

oops.. ;-}   See, I asked about if there was something like that this
other time, and thought I got a "no" from somewhere!

But what about the "reloader"? Make one yourself which call this reset
thing, I guess..


-- 
Mvh,
Endre



Re: DOMConfigurator.configureAndWatch w/multiple async appenders

Posted by Anders Kristensen <ak...@dynamicsoft.com>.

Endre Stølsvik wrote:
> 
> On Tue, 23 Jan 2001, Ceki Gulcu wrote:
> 
> |
> | The problem is that log4j configurators do not  reset the existing
> | configuration when reading a new configuration file.
> 
> Why not?

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.

> 
> I have asked for a "resetConfig()" function before, since I also find this
> counter intuitive. What's the rationale for this? How's the reload of a
> config supposed to work if you actually cannot properly reconfigure the
> system?

Re: DOMConfigurator.configureAndWatch w/multiple async appenders

Posted by Endre Stølsvik <En...@Stolsvik.com>.
On Tue, 23 Jan 2001, Ceki Gulcu wrote:

|
| The problem is that log4j configurators do not  reset the existing
| configuration when reading a new configuration file.

Why not?

I have asked for a "resetConfig()" function before, since I also find this
counter intuitive. What's the rationale for this? How's the reload of a
config supposed to work if you actually cannot properly reconfigure the
system?

-- 
Mvh,
Endre