One of the most useful health-related services offered by ASP.NET is the Web Events feature. By modifying the Web.config file, you can use the health monitoring system to log unhandled exceptions, expired forms, authentication tickets, and any other data you want logged in your application. If you want to get more information about this, you can read this KB article http://support.microsoft.com/kb/893664.

This said, in Windows Azure Cloud Services (PaaS), some of this is pre-configured for you, and all unhandled errors and audit failures are written to the Windows Event Log within the Application folder as shown:

ASP.NET Exception in Application event log

For WAD (Windows Azure Diagnostics) to capture the health event you can either configure WAD to read from the event log. If you are monitoring Azure with the Azure management pack (either the old one, or the new preview one which was released last week and that I showed at MMS 2013) you are probably already doing this.

So, if those exceptions are in the event log, we can pull them thru management packs rules to our Operations Manager management group, and alert on them, right? Right. Piece of cake. Here I have written an example rule that does just that (XML for the MP attached below):

ASP.NET Exception Alert from Azure

 

Here’s the XML of the MP I wrote for this – this is referencing the new Azure Fabric Management Pack PREVIEW that was released last week:

 

<?xml version="1.0" encoding="utf-8"?>
< ManagementPack SchemaVersion="2.0" ContentReadable="true" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Manifest>
    <Identity>
      <ID>Azure.AddOn</ID>
      <Version>1.0.0.20</Version>
    </Identity>
    <Name>Azure.AddOn</Name>
    <References>
      <Reference Alias="AzureMP">
        <ID>Microsoft.SystemCenter.WindowsAzure</ID>
        <Version>1.0.0.0</Version>
        < PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Health">
        <ID>System.Health.Library</ID>
        <Version>7.0.8427.0</Version>
        < PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>7.5.8501.0</Version>
        < PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <Monitoring>
     <Rules>
      <Rule ID="Azure.AddOn.ASP.NET.Exception.AlertRule" Target="AzureMP!Microsoft.SystemCenter.WindowsAzure.RoleInstance" Enabled="true" Remotable="true" Priority="Normal" ConfirmDelivery="false">
        <Category>Alert</Category>
        < DataSources>
          < DataSource ID="DS" TypeID="AzureMP!Microsoft.SystemCenter.WindowsAzure.RoleInstance.EventLog.CollectData.DS">
            < IntervalSeconds>300</IntervalSeconds>
            < TimeoutSeconds>60</TimeoutSeconds>
          </DataSource>
        </DataSources>
        < ConditionDetection ID="CD" TypeID="System!System.ExpressionFilter">
          <Expression>
            <And>
              <Expression>
                < SimpleExpression>
                  < ValueExpression>
                    < XPathQuery>EventNumber</XPathQuery>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  < ValueExpression>
                    <Value Type="String">1309</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <Or>
                  <Expression>
                    < SimpleExpression>
                      < ValueExpression>
                        < XPathQuery>PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      < ValueExpression>
                        <Value Type="String">ASP.NET 2.0.50727.0</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                  <Expression>
                    < SimpleExpression>
                      < ValueExpression>
                        < XPathQuery>PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      < ValueExpression>
                        <Value Type="String">ASP.NET 4.0.30319.0</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                </Or>
              </Expression>
            </And>
          </Expression>
        </ConditionDetection>
        < WriteActions>
          < WriteAction ID="GenerateAlert" TypeID="Health!System.Health.GenerateAlert">
            <Priority>1</Priority>
            <Severity>1</Severity>
            < AlertName />
            < AlertDescription />
            < AlertMessageId>$MPElement[Name='Azure.AddOn.ASP.NET.Exception.AlertRule_AlertMessage']$</AlertMessageId>
            < AlertParameters>
              <AlertParameter1>$Data/EventDescription$</AlertParameter1>
            </AlertParameters>
            <Suppression>
              <SuppressionValue>$Data/EventData/*[local-name()='Event']/*[local-name()='EventData']/*[local-name()='Data'][19]$</SuppressionValue>
           </Suppression>
          </WriteAction>
        </WriteActions>
      </Rule>

    </Rules>
  </Monitoring>
  <Presentation>
    < StringResources>
      < StringResource ID="Azure.AddOn.ASP.NET.Exception.AlertRule_AlertMessage" />
    </StringResources>
  </Presentation>
  < LanguagePacks>
    < LanguagePack ID="ENU" IsDefault="false">
      < DisplayStrings>
        < DisplayString ElementID="Azure.AddOn">
          <Name>Azure MP AddOn for ASP.NET</Name>
          <Description>Azure MP AddOn for ASP.NET</Description>
        </DisplayString>
        < DisplayString ElementID="Azure.AddOn.ASP.NET.Exception.AlertRule">
          <Name>ASP.NET Exception</Name>
          <Description>ASP.NET Exception</Description>
        </DisplayString>
        < DisplayString ElementID="Azure.AddOn.ASP.NET.Exception.AlertRule_AlertMessage">
          <Name>ASP.NET Exception</Name>
          <Description>Event Description: {0}</Description>
        </DisplayString>
      </DisplayStrings>
      < KnowledgeArticles></KnowledgeArticles>
    </LanguagePack>
  </LanguagePacks>
< /ManagementPack>

 

 

Granted, it is not full-blown APM functionality, and you can’t convert to IntelliTrace format, but once you have those exceptions, you can route them to developers thru the TFS Connector like you would do for APM Exceptions:

Assign to Engineering 

 

Please also note that it is not easy to do “proper” alert suppression based on the exception message or call stack, because the “EventDescription” of those ASP.NET events contains timestamps which make the description unique every single time. Also, with the Azure event DataSource, since it reads events from WAD, parameters are lost. Hence I defaulted to do suppression based on the rule itself (this will hide multiple different exceptions that might be happening on the same role instance). But with some help from Marius and Marcin, I managed to write an XPath expression which does alert suppressions only based on the actual exception. Since I am not really explaining what I did here for the XPath expression, if you want to learn more about how to use those in events and how to deal with some of these complex ones, read this other blog post by Michael Repperger.

I hope it is helpful to see how you can extend the Azure MP (that focuses on the “fabric” layer by default) to also look at your application’s health!

Happy Azure monitoring!