Writing Events via Configuration: Running the Example Using the samplesection illustrated in the previous listings in this chapter, you can now write all errors as well as audits that fa
Trang 1<add name="EventLogProvider"
type="System.Web.Management.EventLogWebEventProvider,System.Web,
Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
The three attributes discussed so far are required attributes The rest are considered optional attributes TheminInstancesattribute defines the minimum number of times this Web event must occur before it is logged ThemaxLimitattribute defines the maximum number of instances of the defined Web event that can be recorded If instances are likely to occur because of some continuous loop, you might want to add
a value here TheminIntervalattribute denotes the minimum time allowed between log entries This
means that if theminIntervalis set to00:01:00and two Web events being monitored occur within 15 seconds of each other, the first one is recorded but the second instance is discarded because it falls within the 1-minute setting
Within the<rules>section, you can also see aprofileattribute defined in the<add />elements of the rules defined The value of this attribute comes from a definition that is supplied from the<profiles>
section of the<healthMonitoring>section This section is discussed next
<profiles>
The<profiles>section enables you to define some of the behaviors for Web event monitoring These
definitions are utilized by any number of rule definitions within the<rules>section An example use of the<profiles>section is illustrated in Listing 32-7
Listing 32-7: Using the<profiles> section
<configuration>
<system.web>
<healthMonitoring enabled="true">
<eventMappings>
<! Code removed for clarity >
</eventMappings>
<providers>
<! Code removed for clarity >
</providers>
<rules>
<! Code removed for clarity >
</rules>
<profiles>
<clear />
<add name="Default" minInstances="1" maxLimit="Infinite"
minInterval="00:01:00" custom="" />
Continued
Trang 2<add name="Critical" minInstances="1" maxLimit="Infinite"
minInterval="00:00:00" custom="" />
</profiles>
</healthMonitoring>
</system.web>
</configuration>
As with the other sections, you add a profile definition by using the<add />element within the
<profiles>section Thenameattribute allows you to provide a friendly name that is then utilized from
the definitions placed within the<rules>section, as illustrated here:
<rules>
<add name="All Errors Default" eventName="All Errors"
provider="EventLogProvider"
profile="Default" minInstances="1" maxLimit="Infinite"
minInterval="00:01:00" custom="" />
</rules>
The definitions in the<profiles>section also use the attributesminInstances,maxLimit, and
min-Interval These have the same meanings as if they were used directly in the<rules>section (see the
explanation in the previous section) The idea here, however, is that you can more centrally define these
values and use them across multiple rule definitions
Writing Events via Configuration: Running the Example
Using the sample<healthMonitoring>section (illustrated in the previous listings in this chapter), you
can now write all errors as well as audits that fail (failed logins) to the event log automatically
To test this construction in the<healthMonitoring>section, create a simple ASP.NET page that allows
you to divide two numbers and then show the result of the division on the screen An example ASP.NET
page is presented in Figure 32-11
Figure 32-11
Trang 3As you can see from this page, you can enter a single number in the first text box and another in the
second text box and press the calculate button This allows the two numbers to be divided The result
appears in a Label control on the page In this example, the code intentionally does not use any exception handling Therefore, if the end user tried to divide 5 by 0 (zero), an exception is thrown This event, in
turn, causes the exception to be written to the event log In fact, if you run a similar example and look in the event log, you find that the error has indeed been written as you have specified it should be within theweb.configfile The report from the event log is presented in Figure 32-12
Figure 32-12
Routing Events to SQL Server
Pushing Web events to the event log is something most Web applications do and is also something you should consider if you have overridden these built-in (and default) features Even more powerful than
writing them to the event log, however, is being able to write them to a database
Writing them to a database allows you to actually create a larger history, makes them more secure, and allows you to more easily retrieve the values and use them in any type of administration application that you might create
This capability was briefly introduced in Chapter 1 and is not that difficult to work with If you work
from the same<healthMonitoring>section created earlier in this chapter, writing the events to SQL
Server is as simple as adding some<add />elements to the various sections
Trang 4As shown in the previous<providers>section, a declaration actually exists for recording events into
SQL Server It is presented here again:
<providers>
<clear />
<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>
If you look over this bit of code, you see the definition to record events into SQL Server is presented in the
bold section within the<providers>section The section in bold shows a connection to the SQL Server
instance that is defined by theLocalSqlServerconnection string name You can find this connection
string in themachine.configfile, and you see that it points to an auto-generated SQL Server Express file
that ASP.NET can work with
<connectionStrings>
<add name="LocalSqlServer" connectionString="data source=.\SQLEXPRESS;Integrated
Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
To work with Microsoft’s SQL Server 2005, you simply create a new connection string within your
ASP.NET application’sweb.configfile and reference the friendly name provided to this connection
from the<add />element of the<providers>section.
Although this SQL Server instance is declared and defined, it is not utilized by any of the rules that you
have established Looking at the previous sections, you can see that within the<rules>section of the
health monitoring section of theweb.config, only two rules exist: a rule to write all errors to the event
log and another rule to write failure audits to the event log To add a new rule to write errors (all errors
again) to SQL Server, you use the construction shown in Listing 32-8
Listing 32-8: Creating a rule to write events to SQL Server
<configuration>
<system.web>
<healthMonitoring enabled="true">
Trang 5<! 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="" />
<add name="All Errors SQL Server" eventName="All Errors"
provider="SqlWebEventProvider"
profile="Default" minInstances="1" maxLimit="Infinite"
minInterval="00:01:00" custom="" />
</rules>
</healthMonitoring>
</system.web>
</configuration>
To be able to write to SQL Server, you must create a new<add />element within the<rules>section of the document The friendly name provided via thenameattribute must be unique in the list of defined
rules or you encounter an error In this case, the name of the rule isAll Errors SQL Serverand like
theAll Errors Defaultrule, it points to the event mapping ofAll Errorsas shown via the
event-Nameattribute Theproviderattribute then points to the SQL Server definition contained within the
<providers>section In this case, it isSqlWebEventProvider
With all this in place, run the ASP.NET page (shown earlier) that allows you to throw an error by dividing
by zero If you run this page a couple of times, you see that ASP.NET has automatically created an
ASPNETDB.MDFfile in your project (if you didn’t already have one)
You can then open the SQL Server Express Edition database and expand the Tables node in the Server
Explorer of Visual Studio In this list of available tables, you find a new table calledaspnet_WebEvent_ Events Right-click this table and select Show Table Data from the menu This gives you something
similar to what is illustrated in Figure 32-13
As you can see from this figure, the entire event is now stored within SQL Server (it is the first and only event at the moment) One of the nice things about this example is that not only is this event recorded to the database, but it is also written to the event log because you can use more than a single provider for each event You can just as easily use a provider that comes fromMailWebEventProviderand send the error out as an e-mail message
Trang 6Figure 32-13
Buffering Web Events
When you start working with Web events that you want to write to a database (such as SQL Server) or
sent via an e-mail, you soon realize that doing so can really lock up your database or result in a huge
amount of e-mail (especially if your application is sent into some perpetual loop of errors) For this
reason, you can see why these providers inherit fromBufferedWebEventProvider
BufferedWebEventProviderdoes exactly what it says — it buffers (or queues) your collected Web events
before performing the specified action upon them The reason you might want to buffer is to eliminate
the possibility of your database being pounded or your e-mail box being flooded
Definitions of how the buffering should occur are located in the<bufferModes>section within the
<healthMonitoring>section of theweb.configfile An example of the<bufferModes>section is
pre-sented in Listing 32-9
Listing 32-9: Using the<bufferModes> section
<configuration>
<system.web>
<healthMonitoring enabled="true">
Trang 7<clear />
<add name="Critical Notification" maxBufferSize="100" maxFlushSize="20"
urgentFlushThreshold="1" regularFlushInterval="Infinite"
urgentFlushInterval="00:01:00"
maxBufferThreads="1" />
<add name="Notification" maxBufferSize="300" maxFlushSize="20"
urgentFlushThreshold="1" regularFlushInterval="Infinite"
urgentFlushInterval="00:01:00"
maxBufferThreads="1" />
<add name="Analysis" maxBufferSize="1000" maxFlushSize="100"
urgentFlushThreshold="100" regularFlushInterval="00:05:00"
urgentFlushInterval="00:01:00" maxBufferThreads="1" />
<add name="Logging" maxBufferSize="1000" maxFlushSize="200"
urgentFlushThreshold="800"
regularFlushInterval="00:30:00" urgentFlushInterval="00:05:00"
maxBufferThreads="1" />
</bufferModes>
<eventMappings>
<! Code removed for clarity >
</eventMappings>
<providers>
<! Code removed for clarity >
</providers>
<rules>
<! Code removed for clarity >
</rules>
<profiles>
<! Code removed for clarity >
</profiles>
</healthMonitoring>
</system.web>
</configuration>
In this code, you can see four buffer modes defined Each mode has a friendly name defined using the
nameattribute For each mode, a number of different attribute can be applied To examine these attributes, take a closer look at theLoggingbuffer mode
<add name="Logging"
maxBufferSize="1000"
maxFlushSize="200"
urgentFlushThreshold="800"
regularFlushInterval="00:30:00"
urgentFlushInterval="00:05:00"
maxBufferThreads="1" />
Trang 8This buffer mode is called Logging and, based on the values assigned to its attributes, any provider using
this buffer mode sends the messages to the database or via e-mail every 30 minutes This is also referred
to as flushing the Web events The time period of 30 minutes is defined using theregularFlushInterval
attribute Therefore, every 30 minutes, ASP.NET sends 200 messages to the database (or via e-mail) It will
not send more than 200 messages at a time because of what is specified in themaxFlushSizeattribute
Well, what happens if more than 200 messages are waiting within that 30-minute time period? ASP.NET
still sends only 200 messages every 30 minutes and holds additional messages when the number exceeds
200 The maximum number of message held in the queue cannot exceed 1,000 messages This number
is set through themaxBufferSizeattribute However, after the total in the queue hits 800 messages,
ASP.NET starts flushing the messages every 5 minutes instead of every 30 minutes The change in
fre-quency of messages is determined by theurgentFlushThresholdattribute, and the time interval used
to send messages when theurgentFlushThresholdis hit is determined by theurgentFlushInterval
attribute
After you have defined the buffering modes you want to use, the next step is to apply them To analyze
the process, look back on how theSqlWebEventProvideris declared
<providers>
<clear />
<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>
Again, this event is shown in bold First, the most important attribute is thebufferattribute By default,
buffering of messages is turned off This is done by setting thebufferattribute tofalse ThebufferMode
attribute allows you to assign one of the defined buffer modes created within the<bufferModes>section
In this case, theNotificationbuffer mode is referenced Changing the buffer attribute totrueenables
the events to be sent only to SQL Server according to the time intervals defined by theNotification
buffer mode
E-mailing Web Events
When monitoring a server for Web events, you are not always going to be networked into a server or
actively monitoring it every second This doesn’t mean that you won’t want to know immediately if
something is going very wrong with your ASP.NET application For this reason, you will find the
Sim-pleMailWebEventProviderand theTemplatedMailWebEventProviderobjects quite beneficial
Trang 9Using the SimpleMailProvider
TheSimpleMailWebEventProvidersends Web events as a simple text e-mail, as shown in Figure 32-14
Figure 32-14
To set up this provider, you place an additional<add />element within the<providers>section, as
illustrated in Listing 32-10
Listing 32-10: Adding a SimpleMailWebEventProvider instance
<add name="SimpleMailProvider"
type="System.Web.Management.SimpleMailWebEventProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
from="website@company.com"
to="admin@company.com"
cc="adminLevel2@company.com"
bcc="director@company.com"
bodyHeader="Warning!"
bodyFooter="Please investigate ASAP."
subjectPrefix="Action required."
buffer="false"
maxEventLength="4096"
maxMessagesPerNotification="1" />
Trang 10After the provider is added, you also add a rule that uses this provider in some fashion (as you do with
all the other providers) This is done by referencing theSimpleMailWebEventProvidername within the
provider attribute of the<add />element contained in the<rules>section
For this to work, be sure that you set up the SMTP capabilities correctly in yourweb.configfile An
example is presented in Listing 32-11
Listing 32-11: Setting up SMTP in the web.config file
<configuration>
<system.web>
<! Code removed for clarity >
</system.web>
<system.net>
<mailSettings>
<smtp deliveryMethod="Network">
<network host="localhost"
port="25"
defaultCredentials="true"
/>
</smtp>
</mailSettings>
</system.net>
</configuration>
If you do not have a quick way of setting up SMTP and still want to test this, you can also have ASP.NET
create e-mail messages and store them to disk by setting up the<smtp>section as illustrated in
Listing 32-12
Listing 32-12: Another option for setting up the SMTP section
<configuration>
<system.web>
<! Code removed for clarity >
</system.web>
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation ="C:\"/>
</smtp>
</mailSettings>
</system.net>
</configuration>
In this scenario, the e-mails will be just placed within theC:\root directory