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