Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1475 Chapter 32: Instrumentation void DisplayInstances(PerformanceCounterCategory pcc) { List<string> listPcc = new List<string>(); foreach (string item in pcc.GetInstanceNames()) { listPcc.Add(item.ToString()); } listPcc.Sort(); DropDownList3.DataSource = listPcc; DropDownList3.DataBind(); } protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { PerformanceCounterCategory pcc; pcc = new PerformanceCounterCategory(DropDownList1.SelectedItem.Text); DropDownList2.Items.Clear(); DropDownList3.Items.Clear(); DisplayCounters(pcc); } protected void Button1_Click(object sender, EventArgs e) { PerformanceCounter pc; if (DropDownList3.Items.Count > 0) { pc = new PerformanceCounter(DropDownList1.SelectedItem.Text, DropDownList2.SelectedItem.Text, DropDownList3.SelectedItem.Text); } else { pc = new PerformanceCounter(DropDownList1.SelectedItem.Text, DropDownList2.SelectedItem.Text); } Label1.Text = "<b>Latest Value:</b> " + pc.NextValue().ToString(); } </script> To make this work, you have to deal with only a couple of performance-counter objects such as the PerformanceCounterCategory and the PerformanceCounter objects. The first drop-down list is pop- ulated with all the categories available. These values are first placed in a List(Of String) object that enables you to call a Sort() method and also allows you to remove any categories you aren’t interested in by using the Remove() method before binding to the DropDown list control. The category selected in the first drop-down list drives what is displayed in the second and third drop- down lists. The second drop-down list displays a list of counters that are available for a particular category. You might tend to think that the third drop-down list of instances is based upon the counter that is selected, but instances are set at the category level. 1475 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1476 Chapter 32: Instrumentation When the button on the page is clicked, a new instance of the PerformanceCounter object is created and, as you can see from the example, it can be instantiated in several ways. The first constructor takes just a category name and a counter name, whereas the second constructor takes these two items plus the instance name utilized. After a PerformanceCounter is created, the NextValue() method pulls a sample from the specified item, thus producing the results that are illustrated in Figure 32-7. Application Tracing ASP.NET does an excellent job of displaying trace information either directly on the requested pages of your ASP.NET application or in a trace log that can be found at http://[server]/[application]/trace .axd . Sample screenshots of both of these scenarios appear in Figure 32-8. Figure 32-8 You can get a lot of detailed information on working with tracing for instrumentation in Chapter 24. 1476 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1477 Chapter 32: Instrumentation Understanding Health Monitoring One of the more exciting instrumentation capabilities provided by ASP.NET is the health monitoring sys- tem introduced with ASP.NET 2.0. ASP.NET health monitoring is built around various health monitoring events (which are referred to as Web events) occurring in your application. Using the health monitoring system enables you to use the event logging for Web events such as failed logins, application starts and stops, or any unhandled exceptions. The event logging can occur in more than one place; therefore, you can log to the event log o r even back to a database. In addition to this disk-based logging, you can also use the system to e-mail health monitoring information. By default, the health monitoring system is already enabled. All default errors and failure audits are logged into the event logs on your behalf. For instance, throwing an error produces an entry in the event log, as illustrated in Figure 32-9. Figure 32-9 By default, these errors are registered in the event logs, but you can also record these events in a couple of other places. You define where you record these event messages through the various providers available to the health monitoring system. These providers are b riefly covered next. The Health Monitoring Provider Model Quite a bit of information about what a provider model is and how the health monitoring system works with providers is covered in Chapter 12, but a short review of the providers available to the health mon- itoring system is warranted here as well. 1477 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1478 Chapter 32: Instrumentation The health monitoring system has the most built-in providers in ASP.NET. A diagram of the available providers is shown in Figure 32-10. Figure 32-10 Seven providers are available to the health monitoring system right out of the box: ❑ System.Web.Management.EventLogWebEventProvider : Enables you to use the ASP.NET health monitoring system to record security operation errors and all other errors into the Windows event log. ❑ System.Web.Management.SimpleMailWebEventProvider : Allows you to use the ASP.NET health monitoring system to send error information in an e-mail. ❑ System.Web.Management.TemplatedMailWebEventProvider : Similar to the SimpleMailWeb- EventProvider ,the TemplatedMailWebEventProvider classthisproviderletsyousenderror information in a templated e-mail. Templates are defined using a standard .aspx page. ❑ System.Web.Management.SqlWebEventProvider : Enables you to use the ASP.NET health mon- itoring system to store error information in SQL Server. Like the other SQL providers for the other systems in ASP.NET, the SqlWebEventProvider stores error information in SQL Server Express Edition by default. ❑ System.Web.Management.TraceWebEventProvider : Enables you to use the ASP.NET health monitoring system to send error information to the ASP.NET page tracing system. ❑ System.Web.Management.IisTraceWebEventProvider –: Provides you with the capability to use the ASP.NET health monitoring system to send error information to the IIS tracing system. 1478 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1479 Chapter 32: Instrumentation ❑ System.Web.Management.WmiWebEventProvider : Enables you to connect the ASP.NET health monitoring system to the Windows Management Instrumentation (WMI) event provider. Health Monitoring Configuration By default, the EventLogWebEventProvider object is what is utilized for all errors and failure audits. These rules are defined along with the providers and what Web events to trap in the root web.config file found at C: \ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ CONFIG . All the information for the health monitoring section is defined within the <healthMonitoring> section of this file. Even though these items are defined in the root web.config file, you can also override these settings and define them yourself in your application’s web.config file. To define the health monitoring capabilities and behaviors in your web.config file, place a <healthMon- itoring> section within the < system.web > section of your configuration file: <configuration> <system.web> <healthMonitoring enabled="true"> </healthMonitoring> </system.web> </configuration> The <healthMonitoring> section can include a number of subsections, including the following: ❑ <bufferModes> ❑ <eventMappings> ❑ <profiles> ❑ <providers> ❑ <rules> You next look at some of the core sections and how you can use these sections to define health monitoring tasks in your application’s web.config file. < eventMappings > The <eventMappings> section of the health monitoring system allows you to define friendly names for specific events t hat can be captured. You can declare a number of events in this section, but doing so doesn’t mean that they are utilized automatically. Remember that when placing events in this section, you are just simply defining them in this configuration file for reuse in other sections. Listing 32-4 shows an example of event mapping. Listing 32-4: Using the <eventMappings> section <configuration> <system.web> Continued 1479 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1480 Chapter 32: Instrumentation <healthMonitoring enabled="true"> <eventMappings> <clear /> <add name="All Events" type="System.Web.Management.WebBaseEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="Heartbeats" type="System.Web.Management.WebHeartbeatEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="Application Lifetime Events" type="System.Web.Management.WebApplicationLifetimeEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="Request Processing Events" type="System.Web.Management.WebRequestEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="All Errors" type="System.Web.Management.WebBaseErrorEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="Infrastructure Errors" type="System.Web.Management.WebErrorEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="Request Processing Errors" type="System.Web.Management.WebRequestErrorEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="All Audits" type="System.Web.Management.WebAuditEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="Failure Audits" type="System.Web.Management.WebFailureAuditEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> <add name="Success Audits" type="System.Web.Management.WebSuccessAuditEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> </eventMappings> </healthMonitoring> </system.web> </configuration> 1480 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1481 Chapter 32: Instrumentation From this se ction, you can see that a number of different event types are defined within this <eventMappings> section. Not all these definitions are required, just the ones you are interested in work- ing with. Because these definitions are important, look at how the first one is listed: <add name="All Events" type="System.Web.Management.WebBaseEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> The <add> element takes a number of different attributes. The first, name , allows you to give a user- friendly name that can be used later in one of the other sections of the document. In this case, the friendly name provided is All Events . The next attribute is the type attribute. This enables you to define the .NET event object with which this event mapping is associated. In this case, it is the base event used by all the other event types as a base class. Although the object definition with the type attribute is shown on multiple lines in this book, you should define it on a single line in order for it to work. All the possible Web events it might associate with are found in the System.Web.Management namespace. Each Web Event that is recorded has a code associated with it, and you can use the startEventCode attribute to define a starting point for this code definition. In the preceding example, the event code starts at 0 and increments from there until it reaches the number defined in the endEventCode attribute. In this case, the ending event code is 2147483647 . The following table defines each event type you can find in the System.Web.Management namespace. Web Event (System.Web.Management) Description WebBaseEvent The WebBaseEvent class is the base class for all Web event types. You can, therefore, use this instance within the <eventMappings> section in order to create a definition to capture all events. WebHeartbeatEvent This event defines Web events that are recorded only at specific intervals instead of every time they occur. WebApplicationLifetimeEvent This event defines Web events that occur on the scale of the application and its lifecycle. These types of events include application starts and stops as well as compilation starts and stops. WebRequestEvent This event defines Web events that occur during a request cycle and include items such as when a transaction for a request is committed or aborted. WebBaseErrorEvent The WebBaseErrorEvent class is the base class for all Web events that deal with error types. You can, therefore, use this instance within the <eventMappings> section to create a definition to capture all error events. WebErrorEvent This event defines Web events that occur because of configuration errors or any compilation or parsing errors. 1481 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1482 Chapter 32: Instrumentation Web Event (System.Web.Management) Description WebRequestErrorEvent This event defines Web events that occur because requests are aborted or requests are larger than allowable as defined by the maxRequestLength attribute in the configuration file. It also includes any validation errors or any unhandled exceptions. WebAuditEvent The WebAuditEvent class is the base class for all Web events that deal with login attempts. These attempts can either fail or succeed. You can use this instance within the <eventMappings> section to write a definition to capture all login attempts. WebFailureAuditEvent This event defines Web events that occur because of failed login attempts. Now that all the error definitions are in place within the <eventMappings> section, the ne xt step is to further define the structure your health monitoring system will take by detailing the <providers> section, which is also found within the <healthMonitoring> section. < providers > As you saw earlier in Figure 32-10, seven different providers that you can use within the health moni- toring system are available to you out of the box. By default, ASP.NET records these events to the event logs using the EventLogWebEventProvider , but you can also modify the provider model so that it uses any of the other providers available. You can also build your own custom providers so you can record these Web events to any data store you want. You can find more information on building custom providers in Chapter 13. Providers are declared within the <providers> section, which is nested within the <healthMonitor- ing> section of the document. Within t he root web.config file found at C: \ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ CONFIG , you find a short list of declared providers. You can also declare other providers in your application’s web.config file as presented in Listing 32-5. Listing 32-5: Using the <providers> section <configuration> <system.web> <healthMonitoring enabled="true"> <eventMappings> <! Code removed for clarity > </eventMappings> <providers> <clear /> 1482 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1483 Chapter 32: Instrumentation <add name="EventLogProvider" type="System.Web.Management.EventLogWebEventProvider,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" /> <add name="SqlWebEventProvider" connectionStringName="LocalSqlServer" maxEventDetailsLength="1073741823" buffer="false" bufferMode="Notification" type="System.Web.Management.SqlWebEventProvider,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" /> <add name="WmiWebEventProvider" type="System.Web.Management.WmiWebEventProvider,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" /> </providers> </healthMonitoring> </system.web> </configuration> In this example, you see three separate health monitoring providers declared in the web.config file. A provider is defined for storing Web events in the event logs, another for storing in SQL Server, and finally another for the Windows Management Instrumentation (WMI) system. By declaring these providers within the <providers> section of the web.config file, you don’t ensure that these providers are actually utilized. Instead, they are simply defined and ready for you to use. You specify which providers to use within the <rules> section of the <healthMonitoring> section, which is defined shortly. You can add defined providers by using the <add /> element within the <providers> section. Within the <add /> element, you find a series of available attributes. The first one is the name attribute. This allows you to provide a friendly name to the defined provider instance that you will use later when specifying the provider to actually use. The name can be anything you want. The type attribute allows you to define the class used for the provider. In some cases, this is all you need (for example, for the event log provider). If you are working with a database-linked provider, however, you must further define things like the connectionString attribute along with the buffer and bufferMode attributes. These are covered in more detail later. Afteryourprovidersaredefinedinthe <healthMonitoring> section of the document, the next step is to determine which We b events to work with and which provider(s) should be utilized in the monitoring of these events. Both these operations are accomplished from within the <rules> section. < rules > The <rules> section allows you to define the Web events to monitor and the providers to tie them to when one of the monitored Web events is actually triggered. When you are using the health mon- itoring system, you can actually assign multiple providers to watch for the same Web events. This means that you can store the same Web event in both the event logs and in SQL Server. That is pretty powerful. Listing 32-6 provides an example of using the <rules> section within your application’s web.config file. 1483 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1484 Chapter 32: Instrumentation Listing 32-6: Using the <rules> section <configuration> <system.web> <healthMonitoring enabled="true"> <eventMappings> <! Code removed for clarity > </eventMappings> <providers> <! Code removed for clarity > </providers> <rules> <clear /> <add name="All Errors Default" eventName="All Errors" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom="" /> <add name="Failure Audits Default" eventName="Failure Audits" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom="" /> </rules> </healthMonitoring> </system.web> </configuration> In this example, two types of Web events are being recorded. You specify rules (the Web events to mon- itor) by using the <add /> element within the <rules> section. The name attribute allows you to provide a friendly name for the rule definition. The eventName is an important attribute because it takes a value of the Web event to monitor. These names are the friendly names that you defined earlier within the <eventMappings> section of the <healthMonitoring> section. The first <add /> element provides a defi- nition of monitoring for All Errors via the eventName attribute. Looking back, you can see that this was, indeed, defined in the <eventMappings> section. <eventMappings> <add name="All Errors" type="System.Web.Management.WebBaseErrorEvent,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647" /> </eventMappings> After specifying which Web event to work with through the eventName attribute, the next step is to define which provider to use for this Web event. You do this using the provider attribute. In the case of the first <add /> element, the EventLogProvider is utilized. Again, t his is the friendly name that was used for the provider definition in the <providers> section, as shown here: 1484 . working with tracing for instrumentation in Chapter 24. 1476 Evjen c32.tex V2 - 01/28/2008 4:05pm Page 1477 Chapter 32 : Instrumentation Understanding Health Monitoring One of the more exciting instrumentation. ASP. NET is the health monitoring sys- tem introduced with ASP. NET 2.0. ASP. NET health monitoring is built around various health monitoring events (which are referred to as Web events) occurring. producing the results that are illustrated in Figure 32 -7. Application Tracing ASP. NET does an excellent job of displaying trace information either directly on the requested pages of your ASP. NET