System.Diagnostics Tools

I l @ ve RuBoard

System.Diagnostics Tools

The .NET Framework includes a number of tools in the System.Diagnostics namespace that are useful for gathering debugging information. A common tool used to track Windows Distributed internet Applications (DNA) applications is the event log. A major disadvantage of using events to log debugging information was the fact that you couldn't generally access the event log without direct access to the server (either physically or through a remote control application). Using the System.Diagnostics namespace, it is very easy to build an event log viewer in ASP.NET, so that you can see your events without having to access the server directly.

Logging Events

The System.Diagnostics namespace offers many useful functions, and logging events is just one of them. A common place where you may want to log events is in response to system errors, so that you can track them down at a later date. The easiest way to do this is to add an Application_Error function to your global.asax file. Listing 13.7 shows how to configure an error event handler for your ASP.NET application.

Listing 13.7 global.asax Application_Error function (C#).
 public void Application_Error(Object sender, EventArgs e) {         string LogName = "ASPAlliance";         string ErrorMessage;         ErrorMessage = "URL: " + Request.Path;         ErrorMessage += " Error: " +                 Server.GetLastError().ToString();         // Create event log if it doesn't exist         if (!System.Diagnostics.EventLog.SourceExists(LogName))         {         System.Diagnostics.EventLog.CreateEventSource(LogName, LogName);         }         System.Diagnostics.EventLog Log = new System.Diagnostics.EventLog();         Log.Source = LogName;         Log.WriteEntry(ErrorMessage, System.Diagnostics.EventLogEntryType.Error); } 

The first two lines of this function set the event log name to the name of our application and build our event string from the page's URL and exception that caused this event to be raised, which is available through the use of the this keyword (the me keyword in VB).

We determine whether this log has been created already by using the SourceExists method of the System.Diagnostics.EventLog namespace. This returns true if the name we pass exists, and false otherwise . If the log doesn't exist, we create it by using the CreateEventSource function, passing the LogName variable for both the event source and the event log name. Finally, we create an instance of the EventLog class, set its source to our application's name, and use its WriteEntry method to log the error message, specifying an event type of Error using the EventLogEntryType class (which has properties for each possible event type).

To test that this is working, create a simple ASPX page in your application that creates a variable, assigns it to zero, and then attempts to divide by it. You should note that the error is captured by this event handler and logged to an event log. You can read the event log on the Web server by using the Administrative Tools “ Event Viewer utility, or you can write an ASP.NET page to read the event log, as we will now do.

Reading Event Logs

Logging events is great, but only if you can read them ”preferably without having to be logged on locally to the Web server. The next example is a full-featured event viewer that you can copy to any .NET-enabled Web server. The complete source is available from this book's Web site ”we will just look at the interesting parts here. Listing 13.8 displays the code that is used to retrieve the events and bind them to our repeater control, or delete them.

NOTE

View This Example Live:

http://aspauthors.com/aspnetbyexample/ch13/events.aspx


Listing 13.8 events.aspx (C#).
 protected void Page_Load(object sender, EventArgs e) {             try{                 if (!IsPostBack)                 {                         BindEvents();                 }             }             catch{                 Response.Write("There were errors in the processing of your request.");             }         }         private void BindEvents()         {                    int i;                 // Get an array with all of the event logs on the server                 EventLog[]elArray = EventLog.GetEventLogs(".");                 // Populate a SELECT box with the different event logs                 logs.DataSource = elArray;                 logs.DataTextField = "Log";                 logs.DataValueField = "Log";                 logs.DataBind();                 for (i=0;i<logs.Items.Count;i++)                 {                     try{                         logs.Items[i].Text =                                              logs.Items[i].Text +                                              " (" + elArray[i].Entries.Count +                                              " rows)";                     }                     catch(Exception e){                         // do not display the restricted logfiles                         Trace.Write("BindEvents",                                              "Cannot Access " +                                              logs.Items[i].Text);                         Trace.Write("BindEvents","",e);                         logs.Items.Remove(logs.Items[i]);                         i--;                     }                 }         }         protected void getMessages_Click(object sender,                                                                     EventArgs e)         {             GetLogEntries();         }         protected void clearLog_Click(object sender, EventArgs e)         {             EventLog el = new EventLog();             el.MachineName = ".";             el.Log = logs.SelectedItem.Value.ToString();             el.Clear();             el.Close();             BindEvents();             GetLogEntries();         }         protected void GetLogEntries()         {             EventLog el = new EventLog();             el.MachineName=".";             el.Log = logs.SelectedItem.Value.ToString();             System.Collections.ArrayList alEvents =                        new System.Collections.ArrayList(el.Entries);             alEvents.Reverse();             messages.DataSource = alEvents;             messages.DataBind();             el.Close();         }         protected string GetEventTypeDesc(EventLogEntryType elet)         {             switch(elet)             {                 case EventLogEntryType.Error:                     return "Error";                 case EventLogEntryType.Warning:                     return "Warning";                 case EventLogEntryType.Information:                     return "Information";                 case EventLogEntryType.SuccessAudit:                     return "Success Audit";                 default:  //EventLogEntryType.FailureAudit                     return "Failure Audit";             }         } 

In the Page_Load function, we first bind a list of all event logs on this machine to a drop-down box control called logs . This is accomplished using the GetEventLogs() method, and passing it a "." to represent the local machine. The resulting array is then used as the data source for our drop-down list. To make the list more useful, we then loop through it and append the number of events in each log to the displayed text, using the Entries.Count property of the EventLog object.

Clicking on the button to display messages in a log calls the getMessages_ Click method, which in turn simply calls GetLogEntries . GetLogEntries retrieves the event log referenced in the drop-down list, reverses the order by using an array, and then binds the repeater control messages to the array. By default, messages are listed in order from oldest to newest, so the Reverse is necessary to make the events display most recent first, like the Windows Event Viewer application.

Clearing an event log is accomplished simply by instantiating an Eventlog object, setting it to the log described by the drop-down list logs, and using the Clear() method.

That's it! I recommend that you use event logging only for events that happen infrequently, or else your logs will get very large very quickly. For most times when you're actively debugging, the Trace function is better, but if you have a production application and you want to know if it is misbehaving, event logging may be the way to go. And with this application, you won't have to log on to the server itself to view the event logs!

Other System.Diagnostics Tools

The System.Diagnostics tools offer a lot of functionality for debugging and monitoring of your ASP.NET applications. Although we don't have time to cover much more in detail, I do want to demonstrate how easy it is to display performance counter values through this library. For this example, we'll display how many users are logged on to the Web server (total for all webs), something impossible to do using classic ASP without a custom component.

If you are using Visual Studio.NET, you can use the Server Explorer to locate performance counters that you would like to include in your ASP. NET page, and just drag them onto the page. However, even without Visual Studio.NET, taking advantage of Windows performance counters in your .NET application is really very easy. Listing 13.9 demonstrates how to set up a counter object. You can view this example live and download the complete source from this book's support Web site.

Listing 13.9 perfActiveSessionsCS.aspx (C#).
 protected void Page_Load() { if (!IsPostBack) {     System.Diagnostics.PerformanceCounter SessionsActiveCounter;     SessionsActiveCounter = new System.Diagnostics.PerformanceCounter ();     SessionsActiveCounter.CategoryName = "ASP.NET Applications";     SessionsActiveCounter.InstanceName = "__Total__";     SessionsActiveCounter.CounterName = "Sessions Active";     SessionsActiveCounter.MachineName = ".";     lblUsers.Text = SessionsActiveCounter.NextValue().ToString(); } } 

Performance counters are exposed by the System.Diagnostics. PerformanceCounter class. To use a counter object, simply provide it with some required properties, such as the category and name of the counter, the instance of the counter if it has more than one, and the machine name of the server on which the counter resides. That's it. To get the scalar value of a counter at any given instant, use the RawValue constant. In this example, we are displaying the total active sessions for the Web server (for ASP.NET) in a label control on the page.

NOTE

See a demonstration of how to use performance counters in your ASP.NET pages live at http://aspauthors.com/aspnetbyexample/ch13/.


I l @ ve RuBoard


Asp. Net. By Example
ASP.NET by Example
ISBN: 0789725622
EAN: 2147483647
Year: 2001
Pages: 154

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