Implementing Health Monitoring in ASP.NET MVC Applications

As you introduce more and more functionalities into your website, the chance of exception occurrence in a real production scenario also grows. Some people take time to notify you of the issue that they are facing in your website but many don’t bother and simply stop visiting your site.

 Health Monitoring is a process which allows you to proactively monitor the health of your website that is running in production without waiting for the end user to come back and say that the website is not working as expected. There can be multiple reasons for your website not to perform as expected and they may look like they’re working perfectly fine in the development environment. Some of them could be thread dead locks, memory leaks, edge cases that are not handled by your code, etc.

In this article I will explain the Health Monitoring feature of Asp.Net and also about how to implement it in Asp.Net MVC applications.

Asp.Net Health Monitoring Feature

Asp.Net health monitoring is a powerful application monitoring feature introduced with Asp.Net 2.0 by Microsoft. It can be configured directly through the web.config entries and does not require any code level changes. The key thing is the amount of information provided by each health monitoring event.

Asp.Net health monitoring can be customized in such a way that any event can be monitored and the captured information can be sent to multiple sources based on the configuration. At a later point of time this data can be used by the experts to do the analysis.

Here is a brief description about the configuration tags.

  1. HealthMonitoring – This is the parent tag in the configuration file and has the enable attribute, which allows the entire feature to be enabled or disabled for a particular application.
  2. EventMappings – List of events that are to be monitored can be listed out in this section with unique names. Following are a few in-built health monitoring events under System.Web.Management.
    1. WebHeartbeatEvent
    2. WebBaseErrorEvent
    3. WebRequestEvent
    4. WebRequestErrorEvent
    5. WebApplicationLifetimeEvent and so on.
  3. Providers – These are the handlers for handling the event scenarios and sending the captured data to a defined destination. It can either be a database logging provider, eventlog provider, email provider, etc. Following are some of the in-built providers.
    1. EventLogWebEventProvider
    2. SqlWebEventProvider
    3. TraceWebEventProvider
    4. SimpleMailWebEventProvider and so on.
  4. Roles – This where the eventMappings and providers are tied up together. Based on these roles, Asp.Net decides which providers to use for which events.

Implementing Health Monitoring in Asp.Net MVC

In this section let us implement health monitoring for a sample Asp.Net MVC application. Create an Asp.Net MVC application in .net framework 4.5 using Visual Studio 2012. The requirement of the health monitoring is to log all of the application heartbeats to the event log and capture all of the exception details to a SqlDatabase. The following code does exactly what is required.

<healthMonitoring enabled="true" heartbeatInterval="1000">
      <eventMappings>
        <clear/>
        <add name="MyApplicationHeartbeats" type="System.Web.Management.WebHeartbeatEvent,System.Web,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
        startEventCode="0" endEventCode="2147483647" />
        <add name="MyApplicationErrors" type="System.Web.Management.WebBaseErrorEvent,System.Web,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
          startEventCode="0" endEventCode="2147483647" />
      </eventMappings>
      <providers>
        <clear/>
        <add name="EventLogProvider" type="System.Web.Management.EventLogWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"/>
        <add name="DatabaseLogProvider" connectionStringName="MyLogDbConnectionString" maxEventDetailsLength="1073741823" buffer="false" bufferMode="Notification" 
             type="System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"/>
      </providers>
      <rules>
        <clear/>
        <add name="Rule For Heartbeats" eventName="MyApplicationHeartbeats" provider="EventLogProvider" minInstances="1" maxLimit="Infinite" minInterval="00:01:00"/>
        <add name="Rule For Errors" eventName="MyApplicationErrors" provider="DatabaseLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom=""/>
      </rules>
</healthMonitoring>

Run the application and you will see the event log capturing the heart beats as shown in Fig 1.0.

The event log capturing the heart beats
Fig 1.0 – The event log capturing the heart beats

You will notice the connection string has been configured in the sql provider, the exceptions will get logged to the database specified in the connection string. It uses the table aspnet_WebEvent_LogEvent table and a specific stored procedure to log the details into the configured database. You don’t have to worry much as running aspnet_regsql.exe will take care of creating them in the destined database.

Workaround for Exception Logging with CustomErrors On in MVC

One thing to note in Asp.Net MVC health monitoring is that the exception health monitoring will stop working if the custom errors section in web.config is set to On/RemoteOnly. There is a work around where a custom HandleErrorAttribute can be created and applied in the FilterConfig.cs as shown in the following code.

namespace MvcHealthMonitoring
{
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new MyExceptionHandleErrorAttribute());
        }
    }
 
    public class MyExceptionHandleErrorAttribute : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            if (!filterContext.HttpContext.IsCustomErrorEnabled)
                return;
 
            CustomErrorEvent errorEvent = new CustomErrorEvent("MyApplication encountered an error!", this, WebEventCodes.WebExtendedBase + 5, filterContext.Exception);
            errorEvent.Raise();
        }
    }
 
    public class CustomErrorEvent : WebErrorEvent
    {
        public CustomErrorEvent(
          string msg, object eventSource,
          int eventCode, Exception exception)
            : base(msg, eventSource, eventCode, exception)
        {
        }
    }
}

I hope this article has provided good insight about implementing health monitoring for an Asp.Net MVC application. Happy reading!

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read