If I wanted to add this additional snippet to my configuration which would 
automatically call Flush on some buffered appenders at the given interval:

<flushBufferingAppendersTimer>
    <interval value="5000" />
    <appender-ref ref="BufferingAppender1" />
    <appender-ref ref="BufferingAppender2" />
</flushBufferingAppendersTimer>

my code would look something like this (I need two classes because the 
Hierarchy and the way its configured are currently two seperate classes):

    // untested
    public class FlushBufferingAppendersTimerHierarchy : Hierarchy
    {
        private Timer timer = null;
        private FlushBufferingAppendersTimerXmlHierarchyConfigurator 
configurator;

        // this method was added to allow a custom configuration instance
        public override XmlHierarchyConfigurator 
CreateXmlHierarchyConfigurator(Hierarchy hierarchy)
        {
            hierarchy.ConfigurationChanged += new 
LoggerRepositoryConfigurationChangedEventHandler(hierarchy_ConfigurationChanged);
            configurator = new 
FlushBufferingAppendersTimerXmlHierarchyConfigurator(hierarchy);
            return configurator;
        }

        private void hierarchy_ConfigurationChanged(object sender, EventArgs e)
        {
            if (timer != null)
            {
                timer.Stop();
            }

            timer = new Timer();
            timer.Interval = configurator.Interval;
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Start();
        }

        private void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            foreach (BufferingAppenderSkeleton bufferingAppender in 
configurator.BufferingAppendersToFlush)
            {
                bufferingAppender.Flush();
            }
        }
    }

    public class FlushBufferingAppendersTimerXmlHierarchyConfigurator : 
XmlHierarchyConfigurator
    {
        private AppenderCollection bufferingAppendersToFlush = new 
AppenderCollection();
        private double interval = 5000;

        public FlushBufferingAppendersTimerXmlHierarchyConfigurator(Hierarchy 
hierarchy)
            : base(hierarchy)
        {
            // empty
        }

        public override void ParseUnknownElement(XmlElement xmlElement, 
Hierarchy hierarchy)
        {
            if (xmlElement.LocalName == "flushBufferingAppendersTimer")
            {
                foreach (XmlNode currentNode in xmlElement.ChildNodes)
                {
                    if (currentNode.NodeType == XmlNodeType.Element)
                    {
                            // TODO: add code to parse the <interval> node
                        XmlElement appenderRef = (XmlElement) currentNode;

                        BufferingAppenderSkeleton bufferingAppender = 
                            FindAppenderByReference(appenderRef) as 
BufferingAppenderSkeleton;

                        if (bufferingAppender != null)
                        {
                            bufferingAppendersToFlush.Add(bufferingAppender);
                        }
                    }
                }
            }
            else
            {
                base.ParseUnknownElement(xmlElement, hierarchy);
            }
        }

        public AppenderCollection BufferingAppendersToFlush
        {
            get { return this.bufferingAppendersToFlush; }
        }

        public double Interval
        {
            get { return this.interval; }
        }
    }

You could write something similiar to automatically delete, move, compress, 
etc. old log files at a given interval on a different thread within log4net 
without the application having to worry about that.

The code is quite long :-( If things were done with plugins it would be 
possible to retrieve the plugin from the repository and change its properties 
during the application's lifetime similiar to how you can retrieve an 
IHttpModule by name and call methods on it:

// might appear in an admin area for an ASP.Net application
GZippedPageOutput gZippedPageOutput = 
    (GZippedPageOutput)Context.ApplicationInstance.Modules["GZippedPageOutput"];
gZippedPageOutput.CompressionLevel = 2;

// might appear on an admin screen for your application
FlushBufferingAppendersPlugin flusher = 
    
(FlushBufferingAppendersPlugin)LogManager.GetRepository().PluginMap["FlushBufferingAppendersPlugin"];
// calls Stop, sets Timer.Interval to the new value, then calls Start
flusher.SetInterval(10000);

The plugin architecture would allow you to add multiple plugins (compress old 
log files, flush buffers at a given internval, retrieve logging statistics, 
etc.) and easily retrieve them by name. Going back my recent post on 
plugins...I can't figure out a good way to allow plugins to hook into the 
configuration process parse the raw configuration file.

Comments?


----- Original Message ----

From: Igor Trofimov <[EMAIL PROTECTED]>

To: Log4NET User <[email protected]>

Sent: Friday, December 22, 2006 2:08:57 AM

Subject: Re: XmlHierarchyConfigurator



Yes! It would be great!

 And what about this small modification? :)



 

 2006/12/22, Ron Grabowski <[EMAIL PROTECTED]>: The call to SetParameter 
(XmlHierarchyConfigurator.cs:185) in the foreach loop inside the Configure 
method could be replaced with a call to ParseUnknownElement: 



protected virtual ParseUnknownElement(XmlElement xmlElement, Hierarchy 
hierarchy)

{

SetParameter(xmlElement, hierarchy);

}



to match ParseLogger, ParseRenderer, etc. That would allow you do extend 
XmlHierarchyConfigurator and do custom processing on user defined top level 
elements. The default behavior of calling SetParameter would remain the same. 



----- Original Message ----

From: Igor Trofimov <[EMAIL PROTECTED]>

To: Log4NET User <[email protected] >

Sent: Sunday, December 17, 2006 1:37:21 PM

Subject: Re: XmlHierarchyConfigurator



Well, i want to add recognition of my specific elements in hierarchy

configuration, similar to <logger>.

And this elements can contain <appender-ref> elements (just as logger do) 

with reference to some appender - so, i can't use default capabilities of

SetParameter - there can't be sutable add-method for "appender-ref".



---------------

You wrote to "Log4NET User" < [email protected]> on Sun, 17 Dec

2006 10:02:22 -0800 (PST):



RG> XmlHierarchyConfigurator seems like a fairly complex class that was

RG> designed to parse a particular file structure without much thought for 

RG> extensibility (its probably not a good thing to encourage people to use

RG> their own slightly different configuration file structure). Take the

RG> SetParameter method for example...making that virtual (~250 lines) 

RG> would allow you to change how parameters are set but my guess is that

RG> you'd still need to copy and paste a lot of that code to get your

RG> override to perform similiar to the base method.

 

RG> What parts of XmlHierarchyConfigurator do you want to override?















 







Reply via email to