4 out of 5 rated this helpful - Rate this topic

Real World: Creating Custom Performance Counters for Windows Azure Applications with PowerShell

Updated: October 5, 2011

Author: http://msdn.microsoft.com/en-us/library/windowsazure/hh307529.aspx

Referenced Image

Learn more about RBA Consulting.

Summary: This article describes how you can create custom performance counters for a Windows Azure web application using PowerShell scripts.

Windows Azure provides applications with the same set of performance counters that traditional, on-premises applications use. These counters are part of the Windows Server® 2008 operating system. Counters such as % Processor Time and Requests/Sec gather metrics that can help you to determine the health of your application. However, applications often require additional metrics that are specific to themselves. For example, if you have an application that uploads images, you may want to know the average number of kilobytes that users upload. Custom counters present a particular problem for Windows Azure applications because Windows Azure does not directly provide sufficient privileges for you to create them from your role. This article describes how to create custom performance counters for a Windows Azure web application using PowerShell.

Reviewing Windows Performance Counters

Along with providing information about performance, counters can help you to find system bottlenecks. You can analyze performance data with graphical tools such as Windows Performance Counter to help you determine how your application is performing. Each performance counter is created using a performance counter type. The following is a list of some commonly used performance counter types.

  • NumberOfItems32

  • NumbersOfItems64

  • RateOfCountsPerSecond32

  • RateOfCountsPerSecond64

  • AverageTimer32

  • AverageBase

The full list of counter types can be viewed on MSDN's PerformanceCounterType Enumeration, located at (http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecountertype.aspx).

Performance counters that are averages require an additional base counter. For example, an AverageTimer32 counter requires the AverageBase counter.

Performance counters are stored in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services registry folder which is why writing custom counters is a challenge. Although Web and Worker roles run under full trust, these elevated permissions are limited to read-only access of the HKEY_LOCAL_MACHINE registry location. To create a performance counter, this registry location must be written to and therefore requires sufficient permission to do so.

The Proxy Application

Although it is possible to use the Remote Desktop to access your instances and manually create custom counters, you must repeat the process for each instance of each deployment. There is also a race condition where you must create the counters before your application begins using them. The better approach is to create them programmatically.

Because a Windows Azure application does not have permission to write to the registry, it must bootstrap another application that does have sufficient permissions to the registry location to create the performance counters. This type of application is known as a proxy application. You can write the proxy application as an executable, such as a C# console application, or as a PowerShell script. Whether you write the proxy application as a console application or as PowerShell script, the logic is similar and only differs in syntax. However, it may be easier to convert from a PowerShell script to a C# application. The following sections discusses how to write the proxy application as a PowerShell script.

Writing the Proxy Application as a PowerShell Script

Writing the proxy application as PowerShell script provides a few advantages over a console application. They are extremely lightweight since the PowerShell scripts do not need to be compiled and can be edited by most text editors. PowerShell scripts are executed by the PowerShell application (powershell.exe). If you are familiar with the C# programming language, then you will find that the PowerShell syntax is similar. You can reference any .NET class within a PowerShell script, such as the ones in the System.Diagnostics namespace. The System.Diagnostics namespace contains the performance counter classes that you will need to use to create your custom counters. The following example implements the logic to create several custom performance counters. The script is saved as New-PerfCounters.ps1.

$categoryName = "Our Custom Performance Counters"
 
$exists = [System.Diagnostics.PerformanceCounterCategory]::Exists($categoryName)
if ($exists)
{
[System.Diagnostics.PerformanceCounterCategory]::Delete($categoryName)
}
 
$counterData = new-object System.Diagnostics.CounterCreationDataCollection
 
$counter = new-object  System.Diagnostics.CounterCreationData
$counter.CounterType = [System.Diagnostics.PerformanceCounterType]::AverageCount64
$counter.CounterName = "Avg Bytes Uploaded"
$counterData.Add($counter)
 
$counter = new-object  System.Diagnostics.CounterCreationData
$counter.CounterType = [System.Diagnostics.PerformanceCounterType]::AverageBase
$counter.CounterName = "Avg Bytes Uploaded Base"
$counterData.Add($counter)
 
$counter = new-object  System.Diagnostics.CounterCreationData
$counter.CounterType = [System.Diagnostics.PerformanceCounterType]::AverageCount64
$counter.CounterName = "Avg KBytes Uploaded"
$counterData.Add($counter)
 
$counter = new-object  System.Diagnostics.CounterCreationData
$counter.CounterType = [System.Diagnostics.PerformanceCounterType]::AverageBase
$counter.CounterName = "Avg KBytes Uploaded Base"
$counterData.Add($counter)
 
[System.Diagnostics.PerformanceCounterCategory]::Create($categoryName, $categoryName, [System.Diagnostics.PerformanceCounterCategoryType]::SingleInstance, $counterData)

Executing the Proxy Application

The proxy application must run when the Web role or Worker role starts. This ensures that the performance counters are available to the web application immediately. In addition, the proxy application must have administrative privileges so that it can write to the registry. Windows Azure 1.3(and later) includes the Startup Task feature, which allows both Web and Worker roles to run applications at startup. Use this feature to launch the proxy application with the necessary privileges.

Windows Azure Startup Tasks

A task is defined by the command (executable), the task's permissions, and the task's type. A command can be anything that the operating system can run. Including a command in a task is analogous to executing commands from the command prompt. The permissions for the task can be either "elevated" or "limited." Elevated permissions execute the command under the NT AUTHORITY\SYSTEM account, which provides full administrative privileges. This includes permission to write to any location in the registry. Running as "limited" will start the command with the same privileges as the hosting process, which is the scenario we're trying to avoid.

To define startup tasks, add Task elements to the ServiceDefinition/WebRole/Startup section in the ServiceDefinition.csdef file. The following code shows how to define a task.

<ServiceDefinition ...>
  <WebRole name="MvcWebRole1">
    <Startup>
      <Task commandLine="StartupTasks\create-counters.cmd" executionContext="elevated" taskType="simple">
      </Task>
    </Startup>
</ServiceDefinition>

The commandLine attribute specifies a relative path to a batch file named create-counters.cmd, which executes the startup task. The path must be relative to the approot\bin directory for Web roles, or just the approot directory for Worker roles. The batch file is specified to be in a subdirectory named Startup Tasks. Therefore, the ASP.NET MVC project must have a folder with that name that contains the create-counters.cmd file. The following illustration shows the directory structure of the web application.

Referenced Screen

The taskType attribute defines the timing of execution of the Windows Azure role in relation to the startup task. The value of "simple" that is used in the example above indicates that the role is not started until the startup task completes. You can also specify a "background" and "foreground" values for the taskType attribute. A background task type means that the role will execute immediately after invoking the startup task, and does not wait for such task to complete. A foreground task type is similar to a background one with the exception that the role cannot be restarted until the startup task is completed. If you use a background task type, you can benefit with relatively faster deploy times since your role will start right away. However, using a background task type may introduce a race condition in your application with the creation of the performance counters and code using such counters. Instead, it is recommended that you use a simple task type so that the performance counters can be fully created prior to your code starting up. In addition, if your startup task contains errors, your role will fail with it, and cause your deployment to fail. This will provide immediate visibility into the error in the startup task.

Creating the Batch File

An easy way to create the batch file is to use a text editor such as Notepad. After you save the file, you can include it in your project. If you create the batch file with Visual Studio, you must remove the default bytes that Visual Studio includes. (Windows Azure cannot process them.) These three bytes are 0xEF, 0xBB, and 0xBF. To delete the bytes, right-click on the batch file, select the Visual Studio Open With command, and then select Binary Editor. The following illustration shows how to choose the Binary Editor, and the bytes that you must remove from the file.

Referenced Screen

Referenced Screen

To include the batch file in the deployment, set the Copy to Output Directory build action either to the Copy if newer or Copy Always value. The following illustration shows how to set the build action.

Referenced Screen

After you have removed the extraneous bytes and set the build action, you can include the appropriate commands in the file. The content of the create-counters command file depends on whether the proxy application is a console application or a PowerShell script. A console application is started directly. A PowerShell script requires that the PowerShell.exe be invoked in order to run the script. The following sections explain both options.

Executing a PowerShell Script

Executing a Windows PowerShell script is simpler than executing a console application because there are no assembly references to manage. In fact, there is no project to reference at all. The only requirement is to save the script with the project, and ensure that it is published with the Copy to Output Directory value, just as the batch file is. The content of the create-counters.cmd file will execute the PowerShell application, and provide it with the appropriate parameters. The following code shows how to execute the PowerShell script.

powershell -ExecutionPolicy Unrestricted .\StartupTasks\new-perfcounters.ps1
noteNote
Even though the batch file is located within the StartupTasks directory, along with the new-perfcounters.ps1 file, it still executes relative to the approot\bin directory. For this reason, the path to new-perfcounters.ps1 must include the StartupTasks directory name.

The ExecutionPolicy Unrestricted switch and value indicates that the script can be run without any restrictions. This switch requires that the osFamily value in the ServiceConfiguration.cscfg file is set to 2.

Verifying the Custom Counters

After deploying the application, you can verify that your custom performance counters were created simply by using them in your web application, and inspecting the WADPerformanceCountersTable table for data. However, in some cases, you may want to see the counters immediately after deployment, but before the application is under load. To do this, configure your Windows Azure application for Remote Desktop. You can then remotely access your Windows Azure instance from the Windows Azure Portal and view the performance counters just as you would on your local machine. The following illustration shows the newly created performance counters, as seen in a Remote Desktop session.

Referenced Screen

You can also use Remote Desktop to inspect the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services registry folder. The folder will have a subfolder with the same name as the category, which in this example is "Our Custom Performance Counters."

Referenced Screen

Summary

Although Windows Azure applications execute with limited system permissions, and do not have the necessary privileges to write to the registry, they can still be instrumented with custom performance counters. The new Startup Tasks feature in Windows Azure 1.3 (and later) allows a proxy application to be bootstrapped with elevated permissions that consequently allow it to create the counters. The proxy application can either be a console application or PowerShell script. The ability to create custom counters means that your applications are not constrained to the default set of performance counters, and that they can log application-specific metrics.

Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.
facebook page visit twitter rss feed newsletter