Dear all

I've almost finished the LogKitManagement and I'd like to express the 
abstractions I've choosen. I'll commit the sources into the scratchpad sometimes 
this evening (Europe) when I can tested then a bit more extensively.

First the configuration syntax:

<logkit>
  <!-- The definitions of the LogTargetFactories
       This could well be put into an own configuration file somewhere
       into the source tree and be loaded as a resource via classloader
       but I've choosen to have it here for now.
       The type attribute denotes the name of the elements in the 
       targets section
  -->
  <factories>
    <factory type="file" 
      class="org.apache.avalon.excalibur.logger.factory.FileTargetFactory"/>
    <factory type="property-filter"         
      class="org.apache.avalon.excalibur.logger.factory.FilterTargetFactory"/>
    <factory type="servlet" 
      class="org.apache.avalon.excalibur.logger.factory.ServletTargetFactory"/>
  </factories>

  <targets>
    <file id="root">
      <filename>logs/main.log</filename>
    </file>
    <file id="classloader">
      <filename>logs/classloader.log</filename>
    </file>
    <file id="foo">
      <filename>logs/foo.log</filename>
    </file>
    <priority-filter id="servlet" log-level="ERROR">
      <servlet/>
    </priority-filter>
  </targets>

  <categories>
    <category name="cocoon" log-level="INFO">
      <log-target id-ref="root"/>
      <log-target id-ref="servlet"/>

      <category name="classloader" log-level="DEBUG">
        <log-target id-ref="classloader"/>
      </category>
    </category>
    <category name="foo" log-level="INFO">
      <log-target id-ref="foo"/>
    </category>
  </categories>
</logkit>

The first abstraction is the LogKitManager:

public interface LogKitManager
    Logger getLogger( String categoryName );

There is a implementation named DefaultLogKitManager which is the only class 
exposed to clients. As a convenient a additional interface is introduced for the 
ComponentManager (stolen from the role management system) which states that a 
class is willing to get a LogKitManager:

public interface LogKitManageable
    void setLogKitManager( LogKitManager logmanager );

This method has to be called before the configure method but after the 
contextualize method.

The DefaultLogKitManager is Configurable (as well as Loggable [the 
initial default logger] and Contextualizable [to pass along for ie. 
ServletLogTarget]) and gets a Configuration object as expressed in the logkit 
xml syntax above. This DefaultLogKitManager then uses a object of type

public interface LogTargetFactoryManager
    LogTargetFactory getLogTargetFactory( String factoryName );

The DefaultLogTargetFactoryManager is Configurable (as well as Loggable and 
Contextualizable) and gets the Configuration object located at the <factories> 
element. It will instanciate the concrete factories into a map keyed by the type 
attribute. So we are at the LogTargetFactory abstraction which is:

public interface LogTargetFactory
    LogTarget createTarget( Configuration configuration ) 
        throws ConfigurationException;

I've initially written a FileTargetFactory (given the fact that this is the one 
most in flux these days it is absolutely minimum). I've found that the following 
interface is also needed:

public interface LogTargetFactoryManageable
    void setLogTargetFactoryManager( 
        LogTargetFactoryManager logTargetFactoryManager );

This eases writing factories which acts like decorators (AsyncLogTarget, 
PriorityFilter) and thus need a LogTargetFactoryManager to create the decorated 
LogTargets which are embeded in the configuration of them (see <priority-filter> 
above).

After initializing the LogTargetFactoryManager a LogTargetManager 

public interface LogTargetManager
    LogTarget getLogTarget( String targetId );

is created. The implementation DefaultLogTargetManager is, you guess it, 
Configurable (as well as Loggable and Contextualizable). The Configuration 
object is the <targets> element in the xml syntax and is put into a map keyed by 
the id attribute of the target element. It is also LogTargetFactoryManageable to 
be able to create the LogTargets.

The last step of the DefaultLogKitManagers configure method is to create the 
actual categories based on the categories elements content. It does it as the 
syntax will show in a recursive way populating the Loggers retrieved by 
Hierarchy.getDefaultHierarchy().getLoggerFor( full_category ) with the denoted 
LogTargets from the LogTargetManager and keeps the created loggers in 
a map keyed by category.

After that the LogKitManager is ready to be asked for Loggers. For now if it 
cannot find the requested logger for a category the default logger is returned 
(the one passed in via Loggable).

One last step that is to be made is enable the LogKitManagement into the 
ExcaliburComponentManager by use of "magic attributes" like logger="category" on 
the component definition syntax. Would you encourage me to put the classes 
modified for it into the scratchpad area as well?

Thought and comments appreciated.

Giacomo


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

Reply via email to