Tuesday, February 2, 2010

EventLog based Error Logging using ELMAH

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.IO;
using System.Text;
using Elmah;
using System.Diagnostics;


namespace Sample.SampleSystems.Sales.Web.Helpers
{
/// <summary>
/// This class extends Elmah ErrorLog class to log errors to EventLog.
/// </summary>
public class EventLogErrorLog : Elmah.ErrorLog
{
string _eventLog = string.Empty;
string _eventSource = string.Empty;

public string EventLogName
{
get
{
return _eventLog;
}
set
{
_eventLog = value;
}
}

public string EventSourceName
{
get
{
return _eventSource;
}
set
{
_eventSource = value;
}
}

public EventLogErrorLog(string eventLog, string eventSource)
{
_eventLog = eventLog;
_eventSource = eventSource;
}


public EventLogErrorLog(System.Collections.IDictionary config)
{
string eventLog = Mask.NullString(config["eventLog"] as string);

if (eventLog.Length == 0)
{
eventLog = Mask.NullString(config["EventLog"] as string);

if (eventLog.Length == 0)
throw new Elmah.ApplicationException("EventLog is missing for the EventLog-based error log.");
}

string eventSource = Mask.NullString(config["eventSource"] as string);

if (eventSource.Length == 0)
{
eventSource = Mask.NullString(config["EventSource"] as string);

if (eventSource.Length == 0)
throw new Elmah.ApplicationException("EventLog is missing for the EventLog-based error log.");
}
_eventLog = eventLog;
_eventSource = eventSource;
}

public override string Name
{
get { return "iMAD EventLog Error Log"; }
}

public override ErrorLogEntry GetError(string id)
{
ErrorLogEntry logEntry = null;
if (EventLog.SourceExists(_eventSource))
{
// Create an EventLog instance and assign its source.
EventLog imadLog = new EventLog(_eventLog);
foreach (EventLogEntry entry in imadLog.Entries)
{
XmlTextReader reader = new XmlTextReader(new StringReader(entry.Message));
while (reader.IsStartElement("error"))
{
string errorid = reader.GetAttribute("errorId");

if (errorid == id)
{
Error error = ErrorXml.Decode(reader);
logEntry = new ErrorLogEntry(this, errorid, error);
break;
}

reader.Read();

}
reader.Close();
if (logEntry != null)
break;
}
}
return logEntry;

}

public override int GetErrors(int pageIndex, int pageSize, System.Collections.IList errorEntryList)
{
if (EventLog.SourceExists(_eventSource))
{
// Create an EventLog instance and assign its source.
EventLog imadLog = new EventLog(_eventLog);

if (imadLog.Entries.Count > 0)
{
for (int counter = pageIndex; counter < pageSize; counter++)
{
if (counter >= imadLog.Entries.Count)
{
break;
}
EventLogEntry entry = imadLog.Entries[counter];
XmlTextReader reader = new XmlTextReader(new StringReader(entry.Message));

while (reader.IsStartElement("error"))
{
string id = reader.GetAttribute("errorId");
Error error = ErrorXml.Decode(reader);
errorEntryList.Add(new ErrorLogEntry(this, id, error));
}

reader.Close();
}
}
return errorEntryList.Count;
}

return default(int);
}

public override string Log(Error error)
{
string errorId = Guid.NewGuid().ToString();
StringWriter swritter = new StringWriter();
XmlTextWriter xwriter = new XmlTextWriter(swritter);
xwriter.Formatting = Formatting.Indented;
xwriter.WriteStartDocument();
xwriter.WriteStartElement("error");
xwriter.WriteAttributeString("errorId", errorId.ToString());
ErrorXml.Encode(error, xwriter);
xwriter.WriteEndElement();
xwriter.Flush();
xwriter.Close();

// Make sure the Eventlog Exists
if (EventLog.SourceExists(_eventSource))
{
// Create an EventLog instance and assign its source.
EventLog imadLog = new EventLog(_eventLog);
imadLog.Source = _eventSource;
string messageString = swritter.ToString();
if (messageString.Length > 32765)
{
////Max limit of characters that EventLog allows for an event is 32766.
messageString = messageString.Substring(0, 32765);
}
// Write the error entry to the event log.
imadLog.WriteEntry(messageString, EventLogEntryType.Error);
}

return errorId;

}
}

internal sealed class Mask
{
public static string NullString(string s)
{
return s == null ? string.Empty : s;
}

public static string EmptyString(string s, string filler)
{
return Mask.NullString(s).Length == 0 ? filler : s;
}

private Mask() { }
}
}

7 comments:

  1. Hello Deba,

    Thank you very much for this article! It's very helpful for me!

    But I have a question: how to register, configure and use this module? Can i use this module and standard Elmah module (XmlFileErrorLog for example) together?

    Best Regards,
    Aleksandrs

    ReplyDelete
  2. Easy-to-understand Dell Boomi concepts. We turn learning into practical integration skills.dell boomi online training

    ReplyDelete
  3. Python Django online training focuses on application development with hands-on exposure.It builds confidence.This python django online training prepares learners for real projects.It is effective.

    ReplyDelete
  4. ⭐ Workday HCM Training Online
    Comprehensive workday hcm training online helps learners master HR management systems.
    The training includes staffing, payroll, and benefits modules.
    Live classes ensure interactive learning.

    ReplyDelete
  5. The explanation makes ceh training easy to understand.

    ReplyDelete