Aug2008
25

ASP.NET Health Monitoring - Building an EventLogWebEventProvider - Part 3

by nmgomes

On my previous posts on this health monitoring series I explain to you how and why I made my own EventLogWebEventProvider and which benefits you can achieve by using this provider or by making your own.

Now I'll write about how to use this new provider in one application.

Well, almost everything have been written about this topic and Microsoft has one good article on "How To: Use Health Monitoring in ASP.NET 2.0" so I wont even try to explain all the possible scenarios and configurations, I will simply explain the standard scenario.

Typically I simply want to keep track on two Web Event types:

  1. the ones related to application errors
  2. an the others related to application life cycle

As far as I notice there are many people that simply track those from point 1.

Another decision to make is where to store these Web Events data, You do this by choosing a Web Event provider.

ASP.NET give us out-of-the-box several providers and you can make your own provider. Once your provider is done you can use it just like all the others.

In this example I will use the newly created provider.

Now that I know exactly what to track and where to store it I can update my configuration.

All health monitoring configuration data is stored in the system.web\healthMonitoring section and my standard configuration will look like:

<healthMonitoring enabled="true">
  <providers>
    <add name="ExtendedEventLogWebEventProvider" type="NG.Web.Management.EventLogWebEventProvider, NG.Web" source="MyEvtLogSource" />
  </providers>
  <rules>
    <clear />
    <add name="Application Lifetime Events Default" eventName="Application Lifetime Events" provider="ExtendedEventLogWebEventProvider" profile="Default" />
    <add name="All Errors Default" eventName="All Errors" provider="ExtendedEventLogWebEventProvider" profile="Default" />
  </rules>
</healthMonitoring>

Notice the source attribute from the ExtendedEventLogWebEventProvider, using it you can set which EventLog source to use.

Remember that when you create a EventLog source you can choose to create a brand new EventLog and if you choose so, all entries written by this provider in this application context will be isolated from all the others providing one easy way for visual tracking and filtering.

With the health monitoring data in place you should now be able to see the entries appearing in EventLog.

Filed in: ASP.NET

Aug2008
24

ASP.NET Health Monitoring - Building an EventLogWebEventProvider - Part 2

by nmgomes

In the first post of this series I've manage to find the correct eventId for each Web Event type, and by this time the major problem has been solved, but I cannot yet write a correct entry into the EventLog.

I still have to decided the best severity type and category to apply.

Severity

If you look at entries in the EventLog generated by the default EventLogWebEventProvider you will find that they are marked mainly as Information and a few of them are also marked as Warning but no one is ever marked as Error.

Since I'm making my own provider I will take this chance to map the EventLog entry severity type according to the source Web Event.More...

Filed in: ASP.NET

Aug2008
18

SQL Server - Undocumented Stored Procedure sp_MSforeachtable

by nmgomes

I'm not an every day SQL Server user but I use SQL Server regularly since 7.0 version until the 2005 version (not yet tried 2008 in a serious way) and from time to time I still find some nice hidden gems.

A few days ago I needed to created a cleanup script for an application and one of the tasks was to drop all tables that match a specific name pattern.

My first thought was to use a cursor to loop or a dynamic SQL statement ...

... but this time I decided to google for some other approach, and I found the amazing undocumented sp_MSforeachtable stored procedure from the master database.

It does the same but it requires considerably less code and improves the script readability.

Below is the syntax for calling the sp_MSforeachtable SP: More...

Filed in: MS SQL

Aug2008
12

ASP.NET - Health Monitoring and EventLogWebEventProvider - Part 1

by nmgomes

The ASP.NET health monitoring enables you to add instrumentation to Web applications by using the so called Web Events. These Web events give us information about health status.

You can configure health monitoring by setting events and providers in the healthMonitoring section.

Naturally, ASP.NET provide us with a few out-of-the-box providers such as the EventLogWebEventProvider.

As many of you may have already notice, when using the EventLogWebEventProvider the events are added to the Application EventLog with the following source pattern:

        ASP.NET "framework version"

If you are using ASP.NET 2.0 the source will look similar to "ASP.NET 2.0.50727.0 ".

You can imagine what happen when a server hosts several web applications ... you can't easily figure which application raised a web event because you can't apply a filter to do that. To figure it out you must inspect the eventlog entry data.

If you think this is wrong and that Microsoft should do something about it, go here and here, vote and comment.

What can you do to overlap this? Well you can create your own EventLogWebEventProvider that allows you to specified which Source to use.

Doing such a provider is fairly simple but lead us to THE problem: which eventId to use when creating the EventLog entry?

What? Why is this a problem? are you saying.

Well, lets start all from the beginning ... you want to create your own provider so you can specify the EventLog source but you certainly desire to keep the remaining settings unchanged so that monitoring applications that track the EventLog entry for well known eventIds still working fine.

The problem is that Microsoft don't expose the algorithm used to created the eventId from the WebEvent data, and this way we can only guess which eventId to use.

If you look at EventLogWebEventProvider.ProcessEvent method you will find the following code:

int num = UnsafeNativeMethods.RaiseEventlogEvent((int) type, (string[]) dataFields.ToArray(typeof(string)), dataFields.Count); 

This is your black box, no source or information is available.

To guess which eventId is used for a specific Web Event I created a small page that raises all known Web  Events.

I found that even with all known Web Events configured to use EventLogWebEventProvider almost half of them don't appear in EventLog, but those that have an EventLog entry made me speculate that eventIds are sequential and follow the classes hierarchy. Here are the results:

Web Event EventLog entry eventId Speculated eventId range
WebBaseEvent - 1303
WebManagementEvent - 1304
WebApplicationLifetimeEvent 1305 1305
WebRequestEvent 1306 1306
WebHeartbeatEvent 1307 1307
WebBaseErrorEvent - 1308
WebRequestErrorEvent 1309 1309
WebErrorEvent 1310 1310
WebAuditEvent - 1311
WebSuccessAuditEvent 1312 1312
WebAuthenticationSuccessAuditEvent - 1313
WebFailureAuditEvent 1314 1314
WebAuthenticationFailureAuditEvent - 1315
WebViewStateFailureAuditEvent 1316 1316

 

Please note that I'm considering that no two different Web Events share the same eventId.

If you believe the assumptions made are correct you can now start coding your provider.

Remember that you must create the EventLog source before  use it. You can do this by using the EventLog.CreateEventSource method.

Filed in: ASP.NET

Aug2008
12

ASP.NET - EventMappingSettingsCollection bug on Contains method

by nmgomes

Recently, while digging on ASP.NET 2.0 Health Monitoring I found a bug in the EventMappingSettingsCollection.Contains class method.

I was trying to check if an event mapping already exists but every time I try it the following exception was thrown:

System.NullReferenceException was unhandled by user code
  Message="Object reference not set to an instance of an object."
  Source="System.Web"
  StackTrace:
       at System.Web.Configuration.EventMappingSettingsCollection.GetElementKey(ConfigurationElement element)
       at System.Configuration.ConfigurationElementCollection.GetElementKeyInternal(ConfigurationElement element)
       at System.Configuration.ConfigurationElementCollection.BaseIndexOf(ConfigurationElement element)
       at System.Web.Configuration.EventMappingSettingsCollection.IndexOf(String name)
       at System.Web.Configuration.EventMappingSettingsCollection.Contains(String name)

I opened a bug in connect, so, if you think this is important go there and vote.

And if you think this one is not a common error ... well ... this is the second bug I found regarding Contains method from a collection class.

Filed in: .NET | ASP.NET