You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Mark Womack <mw...@bevocal.com> on 2002/01/28 07:37:44 UTC

[CODE] Updated Watchdog Code

Here is the latest edition of the new Watchdog design and implementation. I
have gone through a number of iterations since the original version and I
think I have incorporated all of the initial feedback.  I gave up on my
earlier thoughts on "passive" vs "active" watchdogs.  I decided that there
was no reason to introduce that confusion to the design.  But I did make
some changes to accomadate both types, as I hope you will see.

Watchdog.java - Now implemented as an interface.  Requires implementations
to support name and configurator class name properties as well as
startWatching() and stopWatching() methods.

WatchdogBase.java - Abstract base implementation of Watchdog interface using
threads and the Runnable interface.  This is the base implementation used
for all of the current watchdogs implemented for log4j, but developers can
create their own to suit their needs.  This implementation requires
subclasses to implement the methods reconfigure() and
checkForReconfiguration().  The checkForReconfiguration() generalizes the
concept of "get modification time".  It should return "true" if the watchdog
has found updated configuration data.  The subclass can now do whatever is
required to check for new configuration data.  It might depend on a
modification date, or it might depend on something else altogether.  This
class also implements three helper methods that subclasses can take
advantage of: getConfiguratorClass(), reconfigureByURL(), and
reconfigureByInputStream().  I am remaining agnostic on the topic of whether
a URL and/or an InputStream is required to reconfigure.  Both options are
available to subclasses as they need them, the base class does not enforce
one over the other.

URLWatchdogBase.java - Abstract base implementation that extends
WatchdogBase to include the setting of url, interval, and modification time
properties.  It also implements the reconfigure() method to call the
reconfigureByURL() helper method.  This class is the base class that can be
used to implement a watchdog that watches a url entity, where ever, what
ever it might be.

FileWatchdog.java - Implementation that extends URLWatchdogBase to watch a
configuration file located on the file system.  Implements the
checkForReconfiguration() method in the usual way that has been implemented
before.  Please note that the wait interval is handled at the end of this
method if the watched file has not been modified.  The wait interval is no
longer handled in the main loop (now implemented in WatchdogBase.java). It
is up to subclasses of WatchdogBase to handle the wait interval.  This class
also overrides the setup() and cleanup() methods (defined in
WatchdogBase.java) to create and release the file object used to describe
the configuration file to watch.

HttpWatchdog.java - Implementation that extends URLWatchdogBase to watch a
configuration file located on a web server.  Pretty much the same as
FileWatchdog, but checks the Last-Modified time in the response header for
the modification time.

SocketWatchdog.java - Implementation that extends WatchdogBase to implement
a new kind of Watchdog.  It creates a ServerSocket on a given port number
and then watches for new sockets opened on it.  When a socket is accepted,
the socket's InputStream is used to reconfigure log4j.  The setup() and
cleanup() methods are written to create and close the ServerSocket.
checkForReconfiguration() is written to call the accept() method of the
ServerSocket, waiting for new sockets to be opened. reconfigure() has been
written to grab the InputStream from the socket and call the
reconfigureByInputStream() method to reconfigure log4j.

DOMConfigurator.java - Same modifications as before, but now added some code
to convert the file name to a URL, prepending "file:" to the start of it.

PropertyConfigurator.java - Ditto plus the added doConfigure(InputStream)
method.

WatchdogTester.java - This is some very rough code that I have been using to
test the watchdog implementation and functionality.  You'll have to look at
the code to figure out the command line you can use to test each watchdog.
Or you can write your own code to do it.

ReconfigureViaSocket.java - This is some rough code I use to test the
SocketWatchdog.  It basically opens a socket and stuffs configuration data
(from a specified file) into an OutputStream.  If you have a SocketWatchdog
configured to watch the same socket port, it gets the data and reconfigures.
This class could morph into an example of sending configuration data via
sockets.

Issues:

1) I have removed the static methods that were being used to keep track of
and stop all the active watchdogs.  Do we want to have a WatchdogManager?
If so, then how do we guarantee that Watchdogs get added to the active list
if Watchdog.java is an interface?  Seems to me that it would require that
Watchdog.java be an abstract class with final methods for startWatching()
and stopWatching().  These methods could then make calls to the Watchdog
manager statc methods to add/remove watchdogs.  I would appreciate some
feedback on this.  We really only need the manager class if it is ever
planned to include watchdogs in configuration files.  Otherwise, it can be
left as an effort for the developer to keep track of their watchdogs any way
they want.

2) If Watchdog.java remains an interface, what should be its package name?
org.apache.log4j.spi?

3) I would like the Watchdog interface to contain the reconfigure() method
definition, but then it will be required to be public.  reconfigure() should
not be public as it should only be called after it has been decided that new
configuration data is available.  So, unless there are other ideas, I'm
going to leave it out of the interface.

4) I am hoping that the SocketWatchdog class will help explain why I feel
just having a doConfigure(URL) method in the Configurator interface is not
sufficient.  A URL will not work in this case, right?  All it has is a
socket with the InputStream of data.  There is no url...or can I somehow
specify the socket as a url?  And if the configurator supports url (as it is
now required), it could also support an InputStream with little trouble, I
think. And if doConfigure(InputStream) is in the Configurator interface,
then the Watchdog would not need to use reflection to find the right method.
But either way, I am fine with it.

5) I have tested and used FileWatchdog, HttpWatchdog, and SocketWatchdog.
They seem to work as advertised, but there may still be more lingering bugs.
Use with care.  I would also like more feedback regarding the design and
implementation.

Thanks,
-Mark