Logging Exceptions
Writing to the Event Log
You can interact with event logs in an ASP.NET page by using the cl asses in the System.Diagnostics
namespace. First, import the namespace at the beginning of your code-behind file:
using System.Diagnostics;
The following example rewrites the simple ErrorTest page to use event logging:
public partial class ErrorTestLog : Page
{
protected void cmdCompute_Click(Object sender, EventArgs e)
{
try
{
decimal a, b, result;
a = Decimal.Parse(txtA.Text);
b = Decimal.Parse(txtB.Text);
result = a / b;
lblResult.Text = result.ToString();
lblResult.ForeColor = System.Drawing.Color.Black;
}
catch (Exception err)
{
lblResult.Text = "<b>Message:</b> " + err.Message + "<br /><br />";
lblResult.Text += "<b>Source:</b> " + err.Source + "<br /><br />";
lblResult.Text += "<b>Stack Trace:</b> " + err.StackTrace;
lblResult.ForeColor = System.Drawing.Color.Red;
// Write the information to the event log.
EventLog log = new EventLog();
log.Source = "DivisionPage";
log.WriteEntry(err.Message, EventLogEntryType.Error);
}
}
}
{
protected void cmdCompute_Click(Object sender, EventArgs e)
{
try
{
decimal a, b, result;
a = Decimal.Parse(txtA.Text);
b = Decimal.Parse(txtB.Text);
result = a / b;
lblResult.Text = result.ToString();
lblResult.ForeColor = System.Drawing.Color.Black;
}
catch (Exception err)
{
lblResult.Text = "<b>Message:</b> " + err.Message + "<br /><br />";
lblResult.Text += "<b>Source:</b> " + err.Source + "<br /><br />";
lblResult.Text += "<b>Stack Trace:</b> " + err.StackTrace;
lblResult.ForeColor = System.Drawing.Color.Red;
// Write the information to the event log.
EventLog log = new EventLog();
log.Source = "DivisionPage";
log.WriteEntry(err.Message, EventLogEntryType.Error);
}
}
}
Custom Log
// Register the event source if needed.
if (!EventLog.SourceExists("ProseTech"))
{
// This registers the event source and creates the custom log,
// if needed.
EventLog.CreateEventSource("DivideByZeroApp", "ProseTech");
}
// Open the log. If the log doesn't exist,
// it will be created automatically.
EventLog log = new EventLog("ProseTech");
log.Source = "DivideByZeroApp";
log.WriteEntry(err.Message, EventLogEntryType.Error);
if (!EventLog.SourceExists("ProseTech"))
{
// This registers the event source and creates the custom log,
// if needed.
EventLog.CreateEventSource("DivideByZeroApp", "ProseTech");
}
// Open the log. If the log doesn't exist,
// it will be created automatically.
EventLog log = new EventLog("ProseTech");
log.Source = "DivideByZeroApp";
log.WriteEntry(err.Message, EventLogEntryType.Error);
A Custom Logging Class
Here’s an example of a class named MyLogger that handles the event logging details:
public class MyLogger
{
public void LogError(string pageInError, Exception err)
{
RegisterLog();
EventLog log = new EventLog("ProseTech");
log.Source = pageInError;
log.WriteEntry(err.Message, EventLogEntryType.Error);
}
private void RegisterLog()
{
// Register the event source if needed.
if (!EventLog.SourceExists("ProseTech"))
{
EventLog.CreateEventSource("DivideByZeroApp", "ProseTech");
}
}
}
{
public void LogError(string pageInError, Exception err)
{
RegisterLog();
EventLog log = new EventLog("ProseTech");
log.Source = pageInError;
log.WriteEntry(err.Message, EventLogEntryType.Error);
}
private void RegisterLog()
{
// Register the event source if needed.
if (!EventLog.SourceExists("ProseTech"))
{
EventLog.CreateEventSource("DivideByZeroApp", "ProseTech");
}
}
}
Once you have a class in the App_Code folder, it’s ea sy to use it anywhere in your website. Here’s
how you might use the MyLogger class in a web page to log an exception:
try
{
// Risky code goes here.
}
catch (Exception err)
{
// Log the error using the logging class.
MyLogger logger = new MyLogger();
logger.LogError(Request.Path, err);
// Now handle the error as appropriate for this page.
lblResult.Text = "Sorry. An error occurred.";
}
{
// Risky code goes here.
}
catch (Exception err)
{
// Log the error using the logging class.
MyLogger logger = new MyLogger();
logger.LogError(Request.Path, err);
// Now handle the error as appropriate for this page.
lblResult.Text = "Sorry. An error occurred.";
}
Retrieving Log Information
Here’s the web page code you’ll need:
public partial class EventReviewPage : System.Web.UI.Page
{
protected void cmdGet_Click(Object sender, EventArgs e)
{
lblResult.Text = "";
// Check if the log exists.
if (!EventLog.Exists(txtLog.Text))
{
lblResult.Text = "The event log " + txtLog.Text ;
lblResult.Text += " doesn't exist.";
}
else
{
EventLog log = new EventLog(txtLog.Text);
foreach (EventLogEntry entry in log.Entries)
{
// Write the event entries to the page.
if (chkAll.Checked ||
entry.Source == txtSource.Text)
{
lblResult.Text += "<b>Entry Type:</b> ";
lblResult.Text += entry.EntryType.ToString();
lblResult.Text += "<br /><b>Message:</b> ";
lblResult.Text += entry.Message;
lblResult.Text += "<br /><b>Time Generated:</b> ";
lblResult.Text += entry.TimeGenerated;
lblResult.Text += "<br /><br />";
}
}
}
}
protected void chkAll_CheckedChanged(Object sender,
EventArgs e)
{
// The chkAll control has AutoPostback = true.
if (chkAll.Checked)
{
txtSource.Text = "";
txtSource.Enabled = false;
}
else
{
txtSource.Enabled = true;
}
}
}
{
protected void cmdGet_Click(Object sender, EventArgs e)
{
lblResult.Text = "";
// Check if the log exists.
if (!EventLog.Exists(txtLog.Text))
{
lblResult.Text = "The event log " + txtLog.Text ;
lblResult.Text += " doesn't exist.";
}
else
{
EventLog log = new EventLog(txtLog.Text);
foreach (EventLogEntry entry in log.Entries)
{
// Write the event entries to the page.
if (chkAll.Checked ||
entry.Source == txtSource.Text)
{
lblResult.Text += "<b>Entry Type:</b> ";
lblResult.Text += entry.EntryType.ToString();
lblResult.Text += "<br /><b>Message:</b> ";
lblResult.Text += entry.Message;
lblResult.Text += "<br /><b>Time Generated:</b> ";
lblResult.Text += entry.TimeGenerated;
lblResult.Text += "<br /><br />";
}
}
}
}
protected void chkAll_CheckedChanged(Object sender,
EventArgs e)
{
// The chkAll control has AutoPostback = true.
if (chkAll.Checked)
{
txtSource.Text = "";
txtSource.Enabled = false;
}
else
{
txtSource.Enabled = true;
}
}
}
Here’s the more efficient way (using StringBuilder) you could write the string processing code :
// For maximum performance, join all the event
// information into one large string using the
// StringBuilder.
System.Text.StringBuilder sb = new System.Text.StringBuilder();
EventLog log = new EventLog(txtLog.Text);
foreach (EventLogEntry entry in log.Entries)
{
// Write the event entries to the StringBuilder.
if (chkAll.Checked ||
entry.Source == txtSource.Text)
{
sb.Append("<b>Entry Type:</b> ");
sb.Append(entry.EntryType.ToString());
sb.Append("<br /><b>Message:</b> ");
sb.Append(entry.Message);
sb.Append("<br /><b>Time Generated:</b> ");
sb.Append(entry.TimeGenerated);
sb.Append("<br /><br />");
}
// Copy the complete text to the web page.
lblResult.Text = sb.ToString();
}
// information into one large string using the
// StringBuilder.
System.Text.StringBuilder sb = new System.Text.StringBuilder();
EventLog log = new EventLog(txtLog.Text);
foreach (EventLogEntry entry in log.Entries)
{
// Write the event entries to the StringBuilder.
if (chkAll.Checked ||
entry.Source == txtSource.Text)
{
sb.Append("<b>Entry Type:</b> ");
sb.Append(entry.EntryType.ToString());
sb.Append("<br /><b>Message:</b> ");
sb.Append(entry.Message);
sb.Append("<br /><b>Time Generated:</b> ");
sb.Append(entry.TimeGenerated);
sb.Append("<br /><br />");
}
// Copy the complete text to the web page.
lblResult.Text = sb.ToString();
}