Custom Providers


If the suite of built-in providers doesn't meet your needs, you can build your own provider. It can be as sophisticated as you like, supporting buffering (by deriving from BufferedWebEventProvider) if desired.

If you require any initialization parameters from web.config, you'll need to override the Initialize method and retrieve and then remove any configuration attributes specific to your class before calling your base class' Initialize method.

The interesting method you'll be overriding is ProcessEvent, where you'll be given the event that needs to be recorded. Listing 7-12 shows how to implement a custom provider that logs events to a text file.

Listing 7-12. Implementing a simple custom Web event provider

using System; using System.IO; using System.Collections.Specialized; using System.Web.Management; public class LogFileWebEventProvider : WebEventProvider {    object fileLock = new object();    string fileName;    public override void Initialize(string name,                                    NameValueCollection config)    {      fileName = config.Get("fileName");      config.Remove("fileName");      base.Initialize(name, config);    }    public override void Flush()    {}    public override void Shutdown() {}    public override void ProcessEvent(WebBaseEvent raisedEvent)    {      lock (fileLock) {        using (StreamWriter w = File.AppendText(fileName)) {          w.WriteLine("{0} - {1} - {2}",           raisedEvent.EventTime, raisedEvent.GetType(),           raisedEvent.Message);        }      }    } } 

Since this class doesn't implement buffering, we need to override the abstract method Flush() and do nothing. And since this class doesn't hold any resources like file handles open, there's nothing to do in Shutdown, but we must override it since it's an abstract method in the base class.

To add support for buffering, you'll need to derive from BufferedWebEventProvider instead, and implement ProcessEventFlush to handle batched events as they are being flushed. You'll also need to tweak your ProcessEvent implementation to check if buffering is enabled and let the base class handle the method if so, allowing it to add the message to its buffer. The example in Listing 7-13 adds buffering support to the text file provider.

Listing 7-13. Implementing a buffered custom Web event provider

using System; using System.IO; using System.Collections.Specialized; using System.Web.Management; public class BufferedLogFileWebEventProvider : BufferedWebEventProvider {     object fileLock = new object();     string fileName;     public override void Initialize(string name,                                     NameValueCollection config)     {         fileName = config.Get("fileName");         config.Remove("fileName");         base.Initialize(name, config);     }     public override void ProcessEvent(WebBaseEvent raisedEvent)     {         if (this.UseBuffering)         {             // let BufferedWebEventProvider buffer the event for us             base.ProcessEvent(raisedEvent);         }         else         {             // do the normal synchronous thing             lock (fileLock)             {                 using (StreamWriter w = File.AppendText(fileName))                 {                     writeEvent(w, raisedEvent);                 }             }         }     }     public override void ProcessEventFlush(                             WebEventBufferFlushInfo info)     {         lock (fileLock)         {            using (StreamWriter w = File.AppendText(fileName))            {                 w.WriteLine("--- Buffered Event Flush ---");                 w.WriteLine("Events in buffer: {0}",                             info.EventsInBuffer);                 w.WriteLine("Events lost since last notification: {0}",                     info.EventsDiscardedSinceLastNotification);                 foreach (WebBaseEvent e in info.Events)                     writeEvent(w, e);             }         }     }     private void writeEvent(TextWriter w, WebBaseEvent raisedEvent)     {         w.WriteLine("{0} - {1} - {2}",              raisedEvent.EventTime, raisedEvent.GetType(),              raisedEvent.Message);     } } 

Back in the description of how buffering works (refer to Table 7-1), we discussed a counter that tracks lost messages. In Listing 7-13 you can see how that counter is communicated to the provider via the WebEventBufferFlushInfo class. The buffered example logs this information to the text file along with the events themselves.

If you run both of these providers simultaneously, you'll see that the buffered provider ends up writing out several events at a time in bursts, with the interval dependent on the bufferMode you choose. The synchronous provider, on the other hand, writes each event as it occurs.

To use a custom provider, you need to refer to it in web.config, just like the built-in providers. The example in Listing 7-14 assumes that the provider has been built into a class library assembly called CustomProviders.dll, which is deployed in the bin directory of the Web application.

Listing 7-14. Referring to a custom provider in web.config

<!-- web.config --> <providers>   <add name="BufferedLogFileProvider"        type="BufferedLogFileWebEventProvider,CustomProviders"        fileName="c:\temp\buffered_log.txt"        buffer="true"        bufferMode="Notification"/> </providers> 

While many people will likely need custom events, fewer will need to write a custom provider, but it's good to know this extensibility point exists in case you need it.




Essential ASP. NET 2.0
Essential ASP.NET 2.0
ISBN: 0321237706
EAN: 2147483647
Year: 2006
Pages: 104

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net