Collect performance counters for your Azure Cloud Service (classic)
Important
Cloud Services (classic) is now deprecated for all customers as of September 1st, 2024. Any existing running deployments will be stopped and shut down by Microsoft and the data will be permanantly lost starting October 2024. New deployments should use the new Azure Resource Manager based deployment model Azure Cloud Services (extended support).
Performance counters provide a way for you to track how well your application and the host are performing. Windows Server provides many different performance counters related to hardware, applications, the operating system, and more. By collecting and sending performance counters to Azure, you can analyze this information to help make better decisions.
A performance counter is made up of two parts, a set name (also known as a category) and one or more counters. You can use PowerShell to get a list of available performance counters:
Get-Counter -ListSet * | Select-Object CounterSetName, Paths | Sort-Object CounterSetName
CounterSetName Paths
-------------- -----
.NET CLR Data {\.NET CLR Data(*)\SqlClient...
.NET CLR Exceptions {\.NET CLR Exceptions(*)\# o...
.NET CLR Interop {\.NET CLR Interop(*)\# of C...
.NET CLR Jit {\.NET CLR Jit(*)\# of Metho...
.NET Data Provider for Oracle {\.NET Data Provider for Ora...
.NET Data Provider for SqlServer {\.NET Data Provider for Sql...
.NET Memory Cache 4.0 {\.NET Memory Cache 4.0(*)\C...
AppV Client Streamed Data Percentage {\AppV Client Streamed Data ...
ASP.NET {\ASP.NET\Application Restar...
ASP.NET Apps v4.0.30319 {\ASP.NET Apps v4.0.30319(*)...
ASP.NET State Service {\ASP.NET State Service\Stat...
ASP.NET v2.0.50727 {\ASP.NET v2.0.50727\Applica...
ASP.NET v4.0.30319 {\ASP.NET v4.0.30319\Applica...
Authorization Manager Applications {\Authorization Manager Appl...
#... results cut to save space ...
The CounterSetName
property represents a set (or category), and is a good indicator of what the performance counters are related to. The Paths
property represents a collection of counters for a set. You could also get the Description
property for more information about the counter set.
To get all of the counters for a set, use the CounterSetName
value and expand the Paths
collection. Each path item is a counter you can query. For example, to get the available counters related to the Processor
set, expand the Paths
collection:
Get-Counter -ListSet * | Where-Object CounterSetName -eq "Processor" | Select -ExpandProperty Paths
\Processor(*)\% Processor Time
\Processor(*)\% User Time
\Processor(*)\% Privileged Time
\Processor(*)\Interrupts/sec
\Processor(*)\% DPC Time
\Processor(*)\% Interrupt Time
\Processor(*)\DPCs Queued/sec
\Processor(*)\DPC Rate
\Processor(*)\% Idle Time
\Processor(*)\% C1 Time
\Processor(*)\% C2 Time
\Processor(*)\% C3 Time
\Processor(*)\C1 Transitions/sec
\Processor(*)\C2 Transitions/sec
\Processor(*)\C3 Transitions/sec
These individual counter paths can be added to the diagnostics framework your cloud service uses. For more information about how a performance counter path is constructed, see Specifying a Counter Path.
A performance counter can be added to your cloud service for either Azure Diagnostics or Application Insights.
Azure Application Insights for Cloud Services allows you specify what performance counters you want to collect. After you add Application Insights to your project, a config file named ApplicationInsights.config is added to your Visual Studio project. This config file defines what type of information Application Insights collects and sends to Azure.
Open the ApplicationInsights.config file and find the ApplicationInsights > TelemetryModules element. Each <Add>
child-element defines a type of telemetry to collect, along with its configuration. The performance counter telemetry module type is Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector
. If this element is already defined, don't add it a second time. Each performance counter to collect is defined under a node named <Counters>
. Here's an example that collects drive performance counters:
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector">
<Counters>
<Add PerformanceCounter="\LogicalDisk(C:)\Disk Write Bytes/sec" ReportAs="Disk write (C:)" />
<Add PerformanceCounter="\LogicalDisk(C:)\Disk Read Bytes/sec" ReportAs="Disk read (C:)" />
</Counters>
</Add>
</TelemetryModules>
<!-- ... cut to save space ... -->
Each performance counter is represented as an <Add>
element under <Counters>
. The PerformanceCounter
attribute defines which performance counter to collect. The ReportAs
attribute is the title to display in the Azure portal for the performance counter. Any performance counter you collect is put into a category named Custom in the portal. Unlike Azure Diagnostics, you can't set the interval these performance counters are collected and sent to Azure. With Application Insights, performance counters are collected and sent every minute.
Application Insights automatically collects the following performance counters:
- \Process(??APP_WIN32_PROC??)% Processor Time
- \Memory\Available Bytes
- .NET CLR Exceptions(??APP_CLR_PROC??)# of Exceps Thrown / sec
- \Process(??APP_WIN32_PROC??)\Private Bytes
- \Process(??APP_WIN32_PROC??)\IO Data Bytes/sec
- \Processor(_Total)% Processor Time
For more information, see System performance counters in Application Insights and Application Insights for Azure Cloud Services.
Important
While all this data is aggregated into the storage account, the portal does not provide a native way to chart the data. It is highly recommended that you integrate another diagnostics service, like Application Insights, into your application.
The Azure Diagnostics extension for Cloud Services allows you specify what performance counters you want to collect. To set up Azure Diagnostics, see Cloud Service Monitoring Overview.
The performance counters you want to collect are defined in the diagnostics.wadcfgx file. Open this file in Visual Studio and find the DiagnosticsConfiguration > PublicConfig > WadCfg > DiagnosticMonitorConfiguration > PerformanceCounters element. Add a new PerformanceCounterConfiguration element as a child. This element has two attributes: counterSpecifier
and sampleRate
. The counterSpecifier
attribute defines which system performance counter set (outlined in the previous section) to collect. The sampleRate
value indicates how often that value is polled. As a whole, all performance counters are transferred to Azure according to the parent PerformanceCounters
element's scheduledTransferPeriod
attribute value.
For more information about the PerformanceCounters
schema element, see the Azure Diagnostics Schema.
The period defined by the sampleRate
attribute uses the XML duration data type to indicate how often the performance counter is polled. In the following example, the rate is set to PT3M
, which means [P]eriod[T]ime[3][M]inutes
: every three minutes.
For more information about how the sampleRate
and scheduledTransferPeriod
are defined, see the Duration Data Type section in the W3 XML Date and Time Date Types tutorial.
<?xml version="1.0" encoding="utf-8"?>
<DiagnosticsConfiguration xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
<PublicConfig>
<WadCfg>
<DiagnosticMonitorConfiguration overallQuotaInMB="4096">
<!-- ... cut to save space ... -->
<PerformanceCounters scheduledTransferPeriod="PT1M">
<PerformanceCounterConfiguration counterSpecifier="\Memory\Available MBytes" sampleRate="PT3M" />
<PerformanceCounterConfiguration counterSpecifier="\Web Service(_Total)\ISAPI Extension Requests/sec" sampleRate="PT3M" />
<PerformanceCounterConfiguration counterSpecifier="\Web Service(_Total)\Bytes Total/Sec" sampleRate="PT3M" />
<PerformanceCounterConfiguration counterSpecifier="\ASP.NET Applications(__Total__)\Requests/Sec" sampleRate="PT3M" />
<PerformanceCounterConfiguration counterSpecifier="\ASP.NET Applications(__Total__)\Errors Total/Sec" sampleRate="PT3M" />
<PerformanceCounterConfiguration counterSpecifier="\ASP.NET\Requests Queued" sampleRate="PT3M" />
<PerformanceCounterConfiguration counterSpecifier="\ASP.NET\Requests Rejected" sampleRate="PT3M" />
<PerformanceCounterConfiguration counterSpecifier="\Processor(_Total)\% Processor Time" sampleRate="PT3M" />
<!-- This is a new perf counter which will track the C: disk read activity in bytes per second, every minute -->
<PerformanceCounterConfiguration counterSpecifier="\LogicalDisk(C:)\Disk Read Bytes/sec" sampleRate="PT1M" />
</PerformanceCounters>
</DiagnosticMonitorConfiguration>
</WadCfg>
<!-- ... cut to save space ... -->
</PublicConfig>
</DiagnosticsConfiguration>
A new performance counter can be created and used by your code. Your code that creates a new performance counter must be running elevated, otherwise it fails. Your cloud service OnStart
startup code can create the performance counter, requiring you to run the role in an elevated context. Or you can create a startup task that runs elevated and creates the performance counter. For more information about startup tasks, see How to configure and run startup tasks for a cloud service.
To configure your role to run elevated, add a <Runtime>
element to the .csdef file.
<ServiceDefinition name="CloudServiceLoadTesting" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
<WorkerRole name="WorkerRoleWithSBQueue1" vmsize="Large">
<!-- ... cut to save space ... -->
<Runtime executionContext="elevated">
</Runtime>
<!-- ... cut to save space ... -->
</WorkerRole>
</ServiceDefinition>
You can create and register a new performance counter with a few lines of code. Use the System.Diagnostics.PerformanceCounterCategory.Create
method overload that creates both the category and the counter. The following code first checks if the category exists, and if missing, creates both the category and the counter.
using System.Diagnostics;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
namespace WorkerRoleWithSBQueue1
{
public class WorkerRole : RoleEntryPoint
{
// Perf counter variable representing times service was used.
private PerformanceCounter counterServiceUsed;
public override bool OnStart()
{
// ... Other startup code here ...
// Define the category and counter names.
string perfCounterCatName = "MyService";
string perfCounterName = "Times Used";
// Create the counter if needed. Our counter category only has a single counter.
// Both the category and counter are created in the same method call.
if (!PerformanceCounterCategory.Exists(perfCounterCatName))
{
PerformanceCounterCategory.Create(perfCounterCatName, "Collects information about the cloud service.",
PerformanceCounterCategoryType.SingleInstance,
perfCounterName, "How many times the cloud service was used.");
}
// Get reference to our counter
counterServiceUsed = new PerformanceCounter(perfCounterCatName, perfCounterName);
counterServiceUsed.ReadOnly = false;
return base.OnStart();
}
// ... cut class code to save space
}
}
When you want to use the counter, call the Increment
or IncrementBy
method.
// Increase the counter by 1
counterServiceUsed.Increment();
Now that your application uses your custom counter, you need to configure Azure Diagnostics or Application Insights to track the counter.
As previously stated, the performance counters for Application Insights are defined in the ApplicationInsights.config file. Open ApplicationInsights.config and find the ApplicationInsights > TelemetryModules > Add > Counters element. Create an <Add>
child element and set the PerformanceCounter
attribute to the category and name of the performance counter you created in your code. Set the ReportAs
attribute to a friendly name you want to see in the portal.
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector">
<Counters>
<!-- ... cut other perf counters to save space ... -->
<!-- This new perf counter matches the [category name]\[counter name] defined in your code -->
<Add PerformanceCounter="\MyService\Times Used" ReportAs="Service used counter" />
</Counters>
</Add>
</TelemetryModules>
<!-- ... cut to save space ... -->
As previously stated, the performance counters you want to collect are defined in the diagnostics.wadcfgx file. Open this file in Visual Studio and find the DiagnosticsConfiguration > PublicConfig > WadCfg > DiagnosticMonitorConfiguration > PerformanceCounters element. Add a new PerformanceCounterConfiguration element as a child. Set the counterSpecifier
attribute to the category and name of the performance counter you created in your code.
<?xml version="1.0" encoding="utf-8"?>
<DiagnosticsConfiguration xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
<PublicConfig>
<WadCfg>
<DiagnosticMonitorConfiguration overallQuotaInMB="4096">
<!-- ... cut to save space ... -->
<PerformanceCounters scheduledTransferPeriod="PT1M">
<!-- ... cut other perf counters to save space ... -->
<!-- This new perf counter matches the [category name]\[counter name] defined in your code -->
<PerformanceCounterConfiguration counterSpecifier="\MyService\Times Used" sampleRate="PT1M" />
</PerformanceCounters>
</DiagnosticMonitorConfiguration>
</WadCfg>
<!-- ... cut to save space ... -->
</PublicConfig>
</DiagnosticsConfiguration>