Il sistema di Health Monitoring di ASP.NET 2.0 mette a disposizione un nutrito set di provider, progettati per processare i WebEvent generati a runtime.
Eccone una lista:
- EventLogWebEventProvider
- SqlWebEventProvider
- WmiWebEventProvider
- SimpleMailWebEventProvider
- TemplatedMailWebEventProvider
- TraceWebEventProvider
Se nessuno dei provider riuscisse a coprire i nostri requisiti, scrivendo una classe che erediti da WebEventProvider o BufferedWebEventProvider potremmo crearne uno personalizzato.
La scelta della classe base può ricadere su BufferedWebEventProvider, in modo da utilizzare il buffer del sistema di Health Monitoring per memorizzare i WebEvent prima del loro salvataggio, altrimenti si può usare la classe base WebEventProvider.
Il nostro obiettivo è scrivere un semplice provider per la memorizzazione dei WebEvent in un log conforme al formato RSS.
Creiamo una libreria di classi e aggiungiamo una classe che chiameremo RssProvider.
Per prima cosa, eseguiremo l'override del metedo Initialize, il quale riceve come argomento la collezione di impostazioni "config", dichiarate nella sezione di configurazione provider del web.config.
Affinché il runtime non generi un'eccezione, una volta recuperate le informazioni è necessario rimuovere dalla collezione config i valori appena letti, funzione affidata al metodo metodo FindEndDelete.
private void FindEndDelete(System.Collections.Specialized.NameValueCollection config) { //recupero gli elementi dal config RssPath = config.Get("rssLogPath"); RssTitle = config.Get("rssTitle"); RssLink = config.Get("rssLink"); RssDescrption = config.Get("rssDescription"); RssLanguage = config.Get("rssLanguage"); RssGenerator = config.Get("rssGenerator"); RssManagingEditor = config.Get("rssManagingEditor"); RssWebMaster = config.Get("rssWebMaster"); RssCopyright = config.Get("copyright"); //li rimuovo dalla collezione config.Remove("rssLogPath"); config.Remove("rssTitle"); config.Remove("rssLink"); config.Remove("rssDescription"); config.Remove("rssLanguage"); config.Remove("rssGenerator"); config.Remove("rssManagingEditor"); config.Remove("rssWebMaster"); config.Remove("rssCopyright"); }
Il passo successivo è eseguire l'override del metodo ProcessEvent, che viene richiamato quanto il runtime, un controllo utente o del codice custom generano un WebEvent.
Per prima cosa controlleremo se il provider è impostato per sfruttare un buffer e in caso affermativo richiameremo l'implementazione base del metodo, altrimenti le informazioni trasportate dal WebEvent verranno immediatamente scritte nel file XML:
public override void ProcessEvent(WebBaseEvent eventRaised) { //se il provider usa il buffer if (UseBuffering) { //richiama implementazione classe base //che bufferizza l'evento base.ProcessEvent(eventRaised); } else { //creo una nuova lista di eventi List<WebBaseEvent> listevent = new List<WebBaseEvent>(); //inserisco nella collezione l'evento appena generato listevent.Add(eventRaised); //scrivo nel file SaveToRss(listevent); } }
Infine eseguiremo l'override del metodo ProcessEventFlush, il quale viene richiamato quando il buffer deve essere svuotato.
Il metodo SaveToRss si occuperà infine di memorizzare nel file XML i WebEvent rimossi dal buffer scorrendo la lista che riceve come argomento.
private void SaveToRss(ICollection eventCollection) { //creo un nuovo XmlDocument XmlDocument document = new XmlDocument(); //carico il file xml document.Load(path); //creo un nuovo XPathNavigator XPathNavigator navigator = document.CreateNavigator(); //mi muovo navigator.MoveToChild("rss", ""); navigator.MoveToChild("channel", ""); //recupero un writer XmlWriter writer = navigator.AppendChild(); CultureInfo cultureInfo = new CultureInfo("en-US"); foreach (WebBaseEvent we in eventCollection) { writer.WriteStartElement("item"); writer.WriteElementString("title", we.Message); writer.WriteElementString("link", string.Empty); writer.WriteElementString("pubDate", we.EventTime.ToString("r",cultureInfo.DateTimeFormat)); writer.WriteElementString("description", we.ToString(false,true)); writer.WriteEndElement(); } writer.Flush(); writer.Close(); document.Save(path); }
Compilata la libreria di classi in una dll e copiata nella cartella bin, aggiungiamo le seguenti righe nel web.config per configurare il nostro provider:
<healthMonitoring enabled="true"> <providers> <clear/> <add name="MyRssProvider" type="MyHealthMonitoring.RssProvider" bufferMode="BufferRss" buffer="true" rssLogPath="~/log/log2.xml" rssTitle="Log" rssLink="https://www.aspitalia.com" rssDescription="eventi registrati" rssLanguage="it-it" rssGenerator="RSS generato da RssProvider" rssManagingEditor="my@mysite.com" rssWebMaster="webMaster@mysite.com" rssCopyright="copyright"/> </providers> <!-- impostazioni del buffer --> <bufferModes> <clear/> <add name="BufferRss" maxBufferSize="100" maxBufferThreads="1" regularFlushInterval="00:01:00" maxFlushSize="10" urgentFlushThreshold="10" urgentFlushInterval="00:00:30"/> </bufferModes> <!-- mapping degli eventi --> <eventMappings> <clear/> <add name="Application Event" type="System.Web.Management.WebApplicationLifetimeEvent"/> <!-- startup/shutdown dell'app --> <add name="Generic Event" type="System.Web.Management.WebErrorEvent" /> <!-- errore generico --> </eventMappings> <!-- mappe delle regole --> <rules> <clear/> <add eventName="Generic Event" provider="MyRssProvider" name="RSSRules 1"/> <add eventName="Application Event" provider="MyRssProvider" name="RSSRules 2"/> </rules> </healthMonitoring>
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.