Setting Up Performance Counters In Your Azure Web and Worker Roles

For those wondering how to setup performance counters on your web or worker roles when you deploy your Azure applications, wonder no more, as this post will help to get you started. Azure does not automatically setup performance counters for you from your Azure roles.  You must set them up yourself in the OnStart method in your web or worker role, where Azure will store this diagnostic data in the storage account that you specify in your service configuration, provided that you setup the transfer of Azure logs to storage.  There is a syntax for specifying counter paths that you need to follow, which you can find here.  In order to determine the various default performance counters available to you, the best thing is to RDP into an existing Windows Server 2008 server in your lab and launch Performance Monitor (perfmon.exe), or alternatively you can create a Remote Desktop Connection (RDC) into your web or worker role (you will have to setup RDC in the Visual Studio solution Deploy dialog), and bring up perfmon from the Run dialog. The screen shot below demonstrates this:

SNAGHTML1e712af

Figure 1: Web Role RDP Session Running Perfmon

For your edification (and to spare you from staring at boring syntax), below is an example of the OnStart method in a web role that I setup for a recent project. Please note that I am using the .NET 3.5 counters below for a .NET 3.5 application, whose performance counters map to v2.0.50727. If you are using .NET 4, then you will have to use the counters specific to that version of .NET (again, you can find these in perfmon when you RDP into your Azure role). The code below leverages Mike Kelly's code sample from his Take Control of Logging and Tracing in Windows Azure blog post (which includes the WebDiagnostics helper class with the WriteDiagnosticInfo method). In the download at the bottom of this post, I made significant modifications to the code you see below, which includes a base set of counters that I use (the code has been modified a bit for clarity).

public override bool OnStart()

{

    DiagnosticMonitorConfiguration dmConfig =

        DiagnosticMonitor.GetDefaultInitialConfiguration();

    // Add Azure logs to storage every x minutes.

    TimeSpan tsLogXfer = TimeSpan.FromMinutes(2);

    // Add System and Application Windows Event Logs to transfer every x minutes.

    dmConfig.WindowsEventLog.DataSources.Add("System!*");

    dmConfig.WindowsEventLog.DataSources.Add("Application!*");

    TimeSpan tsEventLogXfer = TimeSpan.FromMinutes(2);

    // Setup sample rate for performance counters.

    TimeSpan perfSampleRate = System.TimeSpan.FromSeconds(5);

    // Change to Error in production!

    dmConfig.WindowsEventLog.ScheduledTransferLogLevelFilter =

        LogLevel.Verbose;

    dmConfig.Logs.ScheduledTransferLogLevelFilter =

        LogLevel.Verbose;

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\Processor(_Total)\% Processor Time",

          SampleRate = perfSampleRate });

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\Memory\Available MBytes",

          SampleRate = perfSampleRate });

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\ASP.NET Apps v2.0.50727(__Total__)\Requests Total",

          SampleRate = perfSampleRate });

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\ASP.NET Apps v2.0.50727(__Total__)\Requests/Sec",

          SampleRate = perfSampleRate });

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\ASP.NET v2.0.50727\Requests Queued",

            SampleRate = perfSampleRate });

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\ASP.NET v2.0.50727\Requests Rejected",

          SampleRate = perfSampleRate });

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\ASP.NET v2.0.50727\Request Execution Time",

          SampleRate = perfSampleRate });

    dmConfig.PerformanceCounters.ScheduledTransferPeriod = tsEventLogXfer;

    dmConfig.Logs.ScheduledTransferPeriod = tsLogXfer;

    dmConfig.WindowsEventLog.ScheduledTransferPeriod = tsEventLogXfer;

    // Start up the diagnostic manager with the given configuration.

    try

    {

        DiagnosticMonitor.Start("DiagnosticsConnectionString", dmConfig);

    }

    catch (Exception exp)

    {

// Handle any exceptions

    } 

   

    return base.OnStart();

}

  

For a worker role, I currently use these (at least for now, but will be adding custom counters in the near future):

 

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\Processor(_Total)\% Processor Time",

            SampleRate = perfSampleRate });

    dmConfig.PerformanceCounters.DataSources.Add(

        new PerformanceCounterConfiguration()

        { CounterSpecifier = @"\Memory\Available MBytes",

            SampleRate = perfSampleRate });

 

In order to visualize the performance counters as well as other diagnostic data, I use the Cerebrata Azure Diagnostics Manager, which can connect to your local Azure development storage as well as your Azure storage in the cloud.  You can get a 30-day free trial at their site, whose URL is here. In order to learn more about custom counters, you can take a look at Mike Kelly's blog here.

AzurePerfCtrSampleCode.zip