Retrieving Resource Metrics via the Azure Insights API

 

There are many options for configuring monitoring and alerting for Azure resources. The Azure portal will show some default metrics. It is also possible to enable more advanced or custom diagnostic settings. The links below provide additional details on enabling diagnostics and monitoring for two popular Azure compute resources, Azure Web Apps and Azure Virtual Machines. Visual Studio Application Insights can also be leveraged to monitor the usage and performance of applications.

As previously mentioned, the Azure portal will show some default metrics for many Azure resources. For example, the screenshot below shows the monitoring tile for an Azure Web App, which has been configured to display three key values: Average Response Time, CPU Time, and Requests.

azure_web_app_default_metric_tile

 

The metric values displayed on this tile are not retained indefinitely. For an Azure Web App, the retention policy is as follows:

  • Minute granularity – 24 hour retention
  • Hour granularity – 7 day retention
  • Daily granularity – 30 day retention

By using the Azure Insights API it is possible to programmatically retrieve the available default metric definitions (the type of metric such as CPU Time, Requests, etc.), granularity, and metric values. With the ability to programmatically retrieve the data, comes the ability to save the data in a data store of your choosing. For example, that data could be persisted to Azure SQL Database, DocumentDB, or Azure Data Lake. From there you could perform whatever additional analysis is desired.

It should be noted that the Azure Insights API is not the same as Application Insights.

Besides working with various metric data points, the Insights API allows you to manage things like alerts, autoscale settings, usage quotas, and more. Check out the full list via the Azure Insights REST API Reference documentation.

The remainder of this post will discuss using the Insights API to learn more about the default metrics available for Azure resources.

Investigating Available Metrics via the Insights REST API

There are three basic steps for working with the Insights REST API:

  1. Authenticate the Azure Insights request
  2. Retrieve the available metric definitions
  3. Retrieve the metric values

The first step is to authenticate the Azure Insights API request. As the Azure Insights API is an Azure Resource Manager based API, it requires authentication via Azure Active Directory (Azure AD). The easiest way (in my opinion at least) to set up authentication is by creating an Azure AD service principal and retrieve the authentication (JWT) token. The sample script below demonstrates creating an Azure AD service principle via PowerShell. For a more detailed walkthrough, please reference the guidance at https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/#authenticate-service-principal-with-password—powershell. It is also possible to create a service principle via the Azure portal.

Create a Service Principle
  1. # Instructions at https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/
  2. $pwd = “[your-service-principle-password]”
  3. $subscriptionId = “[your-azure-subscription-id]”
  4. Login-AzureRmAccount
  5. Select-AzureRmSubscription -SubscriptionId $subscriptionId
  6. $azureAdApplication = New-AzureRmADApplication `
  7.                         -DisplayName “Collier Web Metrics Demo” `
  8.                         -HomePage https://localhost/webmetricdemo” `
  9.                         -IdentifierUris https://localhost/webmetricdemo” `
  10.                         -Password $pwd
  11. New-AzureRmADServicePrincipal -ApplicationId $azureAdApplication.ApplicationId
  12. New-AzureRmRoleAssignment -RoleDefinitionName Reader -ServicePrincipalName $azureAdApplication.ApplicationId
  13. $subscription = Get-AzureRmSubscription -SubscriptionId $subscriptionId
  14. $creds = Get-Credential -UserName $azureAdApplication.ApplicationId -Message “Please use your service principle credentials”
  15. Login-AzureRmAccount -Credential $creds -ServicePrincipal -TenantId $subscription.TenantId

Once the authentication setup step is complete, it is possible to execute queries against the Azure Insights REST API. There are two helpful queries:

  1. List the metric definitions for a resource
  2. Retrieve the metric values

Details on listing the metric definitions for a resource is documented at https://msdn.microsoft.com/en-us/library/azure/dn931939.aspx. For an Azure Web App, the metric definitions should look similar to example screenshot below.

azure_web_app_metric_definitions_with_pointers

 

Once the available metric definitions are known, it is easy to retrieve the required metric values. Use the metric’s name ‘value’ (not the ‘localizedValue’) for any filtering requests (e.g. retrieve the ‘CpuTime’ and ‘Requests’ metric data points). The request / response information for this API call do not appear as an available task at https://msdn.microsoft.com/en-us/library/azure/dn931930.aspx. However, it is possible to do so, and the request URI is very similar to that of listing the metric definitions.

Method Request URI
GET https://management.azure.com/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider-namespace}/{resource-type}/{resource-name}/metrics?api-version=2014-04-01&$filter={filter}

For example, to retrieve just the Average Response Time and Requests metric data points for an Azure Web App for the 1 hour period from 2016-02-18 20:26:00 to 2016-02-18 21:26:00, with a granularity of 1 minute, the request URI would be as follows:

https://management.azure.com/subscriptions/{subscription-id}/resourceGroups/collierwebapi2016/providers/Microsoft.Web/sites/collierwebapi2016/metrics?api-version=2014-04-01&$filter=%28name.value%20eq%20%27AverageResponseTime%27%20or%20name.value%20eq%20%27Requests%27%29%20and%20timeGrain%20eq%20duration%27PT1M%27%20and%20startTime%20eq%202016-02-18T20%3A26%3A00.0000000Z%20and%20endTime%20eq%202016-02-18T21%3A26%3A00.0000000Z

The result should be similar to that of the screenshot below.

azure_web_app_metric_values

 

Using the REST API is very helpful in terms of understand the available metric definitions, granularity, and related values. This information can be very helpful when using the Azure Insights Management Library.

Retrieving Metrics via the Insights Management Library

Just like working with the REST API, there are three basic steps for working with the Insights Management Library:

  1. Authenticate the Azure Insights request
  2. Retrieve the available metric definitions
  3. Retrieve the metric values

The first step is to authenticate by retrieving the JWT token from Azure AD. Assuming the Azure AD service principle is already configured, retrieving the token can be as simple as shown in the code sample below.

Get Auth Token
  1. private static string GetAccessToken()
  2. {
  3.     var authenticationContext = new AuthenticationContext(string.Format(“https://login.windows.net/{0}”, _tenantId));
  4.     var credential = new ClientCredential(clientId: _applicationId, clientSecret: _applicationPwd);
  5.     var result = authenticationContext.AcquireToken(resource: “https://management.core.windows.net/”, clientCredential: credential);
  6.     if (result == null)
  7.     {
  8.         throw new InvalidOperationException(“Failed to obtain the JWT token”);
  9.     }
  10.     string token = result.AccessToken;
  11.     return token;
  12. }

 

The primary class for working with the Insights API is the InsightsClient. This class exposes functionality to retrieve the available metric definitions and metric values, as seen in the sample code below:

Get Metric Data
  1. private static MetricListResponse GetResourceMetrics(TokenCloudCredentials credentials, string resourceUri, string filter, TimeSpan period, string duration)
  2. {
  3.     var dateTimeFormat = “yyy-MM-ddTHH:mmZ”;
  4.     string start = DateTime.UtcNow.Subtract(period).ToString(dateTimeFormat);
  5.     string end = DateTime.UtcNow.ToString(dateTimeFormat);
  6.     StringBuilder sb = new StringBuilder(filter);
  7.     if (!string.IsNullOrEmpty(filter))
  8.     {
  9.         sb.Append(” and “);
  10.     }
  11.     sb.AppendFormat(“startTime eq {0} and endTime eq {1}”, start, end);
  12.     sb.AppendFormat(” and timeGrain eq duration'{0}'”, duration);
  13.     using (var client = new InsightsClient(credentials))
  14.     {
  15.         return client.MetricOperations.GetMetrics(resourceUri, sb.ToString());
  16.     }
  17. }
  18. private static MetricDefinitionListResponse GetAvailableMetricDefinitions(TokenCloudCredentials credentials, string resourceUri)
  19. {
  20.     using (var client = new InsightsClient(credentials))
  21.     {
  22.         return client.MetricDefinitionOperations.GetMetricDefinitions(resourceUri, null);
  23.     }
  24. }

 

For the above code, the resource URI to use is the full path to the desired Azure resource. For example, to query against an Azure Web App, the resource URI would be:

/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.Web/sites/{site-name}/

 

It is also possible to query the metric data for a classic Azure Virtual Machine – just change the request URI to be appropriate for the classic VM:

/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/microsoft.classiccompute/virtualmachines/{vm-name}/

 

To find the resource URI for a desired resource, one approach is to use the https://resources.azure.com tool. Simply browse to the desired resource and then look at the URI shown, as in the screenshot below.

resource_explorer

 

For the full code sample, please see my GitHub repository available at https://github.com/mcollier/microsoft-azure-insights-demo/.

Thanks to Yossi Dahan’s blog post at https://yossidahan.wordpress.com/2015/02/13/reading-metric-data-from-azure-using-the-azure-insights-library/ for the inspiration.

azure_web_app_metric_value_listing

DevLink 2014 Presentations

Last week I had the privilege to speak at DevLink in Chattanooga, TN.  I had a great time!  It was fun to present.  I was also was able to attend some great sessions.  DevLink is always a top notch event to attend.

I had a full load of presentations – four in three days!  Overall I think the sessions came together very well.  If you attended any of my sessions, I would greatly appreciate any feedback. You can find a copy of all my presentations below and on SlideShare.net

  1. Programming Azure Active Directory
  2. Inside Azure Diagnostics
  3. Automating Your Azure Environment
  4. More Cache for Less Cash

BUILD 2014 Downloads

I don’t know about you, but I’m still trying to catch up on all the Azure hotness Microsoft dropped at BUILD a few weeks ago.  On day 2 of BUILD I was sitting a few rows from the front in the keynote hall at BUILD.  As Scott Guthrie continued with his keynote address, I just kept thinking that the hits just keep coming (in a good way).  Plus, it’s going to take a while to digest and really learn all these great new Azure features.  Exciting!

WP_20140403_08_05_12_Pro

I love the fact that Microsoft makes pretty much all the BUILD sessions available to watch via Channel 9.  This is just a great resource for those that either couldn’t make it to BUILD, or if there, couldn’t attend all the sessions in person (you’d have to clone yourself to make that happen).

I travel a lot and being connected to the internet to watch all the sessions sometimes just isn’t possible.  For me, it is very handy to have the session videos and related PowerPoint slides downloaded to my local PC.  Downloading video and slides for each session would be quite painful.  PowerShell to the rescue!

The PowerShell script below is one that I’ve been using for a few years now to download material from BUILD, TechEd, and other major Microsoft events that have content hosted on Channel 9.  I made a few recent tweaks to handle some quirks with the way BUILD 2014 slides were being shared. There’s still some room for improvement, but for the most part it gets the job done.  And that job is downloading all the Azure related sessions and supporting videos to my local computer.

[gist https://gist.github.com/mcollier/10097074]

 

Getting the Windows Azure PowerShell Cmdlets

I’m a big fan of using the Windows Azure PowerShell cmdlets for managing my Windows Azure resources.  They’re incredibly helpful, especially when I need to repeatedly take care of multiple tasks.

There are two ways to get the Windows Azure PowerShell cmdlets – the heavy way and the light way.

Get All the Things!

I would assume most people get the Windows Azure PowerShell cmdlets by taking the path of least resistance.  They go to the Windows Azure downloads page, click the link to “Install” the cmdlet, and let the Web Platform Installer (WebPI) do its thing.  That’s all fine, but it does a lot.  What’s a lot?  Let’s see . . .

Azure PowerShell Web PI

Trying to install the cmdlets via WebPI will also attempt to install a bunch of other software you might not expect, such as:

  • Windows Azure Emulator
  • Microsoft SQL Express LocalDB Edition
  • IIS 8.0 Express
  • Windows Azure Storage Tools
  • Windows Azure Authoring Tools
  • Windows Azure SDK

If you’re an IT Pro / systems admin type of person, that’s probably more than you would expect, or need.

Get Just the One Thing!

If you want just the Windows Azure PowerShell cmdlets, the path of absolute least resistance is to download the latest release from GitHub – https://github.com/WindowsAzure/azure-sdk-tools/releases.  From here you can find links to download via Web PI (we already know what that will bring with it), or get the MSI by itself.

powershell_github

Download and run the MSI and you start off with something pretty familiar and basic.

powershell_msi

Windows Azure AD authentication support for PowerShell

Last week Microsoft announced several fantastic updates to Windows Azure.

One of the updates I’m really excited about is the new Windows Azure Active Directory authentication support in PowerShell.  Previously to allow the Windows Azure PowerShell cmdlets to authenticate with Windows Azure, you’re only choice was via a management certificate.  There were two options to get that certificate:

  1. Download a .publishsettings file and import the file (Get-AzurePublishSettingsFile and Import-AzurePublishSettingsFile)
  2. Create a cert yourself and configure it in PowerShell (see my previous post)

While not a bad way to go, they came with the overhead of deal with management certs.

Configuring Windows Azure Active Directory authentication in PowerShell

1) Get-AzureAccount – To start with, let’s run the Get-AzureAccount cmdlet to see what accounts are already configured.  Since this is my first time, there shouldn’t be any listed.

get_azureaccount

2) Add-AzureAccount – this will open a browser dialog prompting me to authenticate with the Microsoft Account (formerly Live ID) that I want to use for managing my Windows Azure subscriptions.  For me, this one Microsoft Account is a co-admin on multiple subscriptions, and just happens to be a user in multiple Windows Azure AD tenants.

add_azureaccount_login_1

add_azureaccount_login_2

3)  That’s pretty much it.  If I try to list all my subscriptions, I’ll can easily do that with Get-AzureSubscription.  Notice how there is a “ActiveDirectoryUserId” field.

add_azureaccount

get_azuresubscription

What did this actually do?

If I browse to my user profile directory (C:\Users\<username>\AppData\Roaming\Windows Azure Powershell), I can view the WindowsAzureProfile.xml file.  This is the file that was updated as a result of the Add-AzureAccount cmdlet.  It is basically what gets dumped when executing the Get-AzureSubscription cmdlet.

As noted here, the Windows Azure AD credentials available to PowerShell are good only for 12 hours.

See the most recent Windows Azure PowerShell change log at https://raw.github.com/WindowsAzure/azure-sdk-tools/master/ChangeLog.txt.

Billable Size of Windows Azure Blobs

I recently came across a PowerShell script that I think will be very handy for many Windows Azure users. The script calculates the billable size of Windows Azure blobs in a container, or the entire storage account. You can get the script at http://gallery.technet.microsoft.com/Get-Billable-Size-of-32175802.

Let’s walk through using this script:

0. Prerequisites

  • Windows Azure subscription. If you have MSDN, you can activate your Windows Azure benefits at http://bit.ly/140uAMt
  • Windows Azure storage account
  • Windows Azure PowerShell cmdlets (download and configure)

msdn-azure-banner-728x90

1. Select Your Windows Azure Subscription

Select-AzureSubscription -SubscriptionName "MySubscription"

2. Update PowerShell Execution Policy
You should only need to do this if your PowerShell execution policy prohibits running unsigned scripts. More on execution policy.

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

3. Calculate Blob Size for an Entire Storage Account

.\CalculateBlobCost.ps1 -StorageAccountName mystorageaccountname

VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.SqlDatabase.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.ServiceManagement.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.Storage.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.dll’.
VERBOSE: 12:16:39 PM – Begin Operation: Get-AzureStorageAccount
VERBOSE: 12:16:42 PM – Completed Operation: Get-AzureStorageAccount
VERBOSE: 12:16:42 PM – Begin Operation: Get-AzureStorageKey
VERBOSE: 12:16:45 PM – Completed Operation: Get-AzureStorageKey
VERBOSE: Container ‘deployments’ with 4 blobs has a size of 15.01MB.
VERBOSE: Container ‘guestbook’ with 4 blobs has a size of 0.00MB.
VERBOSE: Container ‘mydeployments’ with 1 blobs has a size of 12.55MB.
VERBOSE: Container ‘test123’ with 1 blobs has a size of 0.00MB.
VERBOSE: Container ‘vsdeploy’ with 0 blobs has a size of 0.00MB.
VERBOSE: Container ‘wad-control-container’ with 19 blobs has a size of 0.00MB.
VERBOSE: Container ‘wad-iis-logfiles’ with 15 blobs has a size of 0.01MB.
Total size calculated for 7 containers is 0.03GB.

4. Calculate Blob Size for a Specific Container within a Storage Account

.\CalculateBlobCost.ps1 -StorageAccountName mystorageaccountname `
-ContainerName deployments

VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.SqlDatabase.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.ServiceManagement.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.Storage.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.dll’.
VERBOSE: 12:12:48 PM – Begin Operation: Get-AzureStorageAccount
VERBOSE: 12:12:52 PM – Completed Operation: Get-AzureStorageAccount
VERBOSE: 12:12:52 PM – Begin Operation: Get-AzureStorageKey
VERBOSE: 12:12:54 PM – Completed Operation: Get-AzureStorageKey
VERBOSE: Container ‘deployments’ with 4 blobs has a size of 15.01MB.
Total size calculated for 1 containers is 0.01GB.

5. Calculate the Cost

The Windows Azure pricing calculator page should open immediately after the script executes. From there you can adjust the slider to the desired storage size, and view the standard price. The current price is $0.095 per GB for geo-redundant storage.  So this one storage account is costing me only $0.0027 per month. I can handle that.

azure storage cost

The Case of the Latest Windows Azure VM Image

When creating new Windows Azure VMs, an Operating System (OS) image needs to be specified.  Microsoft maintains a repository of images that are available to be used when creating a new VM.  These images could be regular Windows Server 2012 or Windows Server 2008 images, server images with software like SQL Server or BizTalk server installed, or even various Linux distributions.

To get a list of all available images, execute the Get-AzureVMImage cmdlet.  This will return a list of all possible images and details for each.

get-azurevmimage

Sometimes there may be multiple versions of a particular type of image.  For example, Microsoft will maintain a few versions of Window Server images – these very by patch level.

Notice the properties available (Location, Label, OS, ImageFamily, etc.) for each image.  These can be very helpful in narrowing the list of images.

Find the Image Type

In order to find a particular type of image, the ImageFamily property can be used.


Get-AzureVMImage `
| where { $_.ImageFamily -eq “Windows Server 2012 Datacenter” }

This returns details of only the Windows Server 2012 Datacenter images.

get-azurevmimage - imagefamily

Find the Latest Image

In order to find the most recent version of a particular type of image, the PublishDate property can be used to enhance the query.


$images = Get-AzureVMImage `
| where { $_.ImageFamily -eq “Windows Server 2012 Datacenter” } `
| Sort-Object -Descending -Property PublishedDate

$latestImage = $images[0]
$latestImage

Using the above snippet, only the most recent version of the “Windows Server 2012 Datacenter” image will be returned.

Images Aren’t Always Available

Take another look at the properties returned by Get-AzureVMImage.  Notice there is a Location property.  This specifies in which Windows Azure data centers the particular image is available.  All images may not be available in all data centers.  I’ve only seen this happen a few times, and it seemed to be related to a new OS image rolling out to the various data centers.  If trying to create a new VM with an image that is not supported in the target data center, the Windows Azure service management interface will return a 400 error related to a location constraint:

New-AzureVM : “An exception occurred when calling the ServiceManagement API. HTTP Status Code: 400. Service
Management Error Code: BadRequest. Message: The location constraint is not valid. Operation Tracking ID:
0ba6c633f3xxxxxxxxxxxxxxxxxxxxxx.”

To remedy this, slightly modify the script to include logic to select images that are only available in the desired data center location.


$images = Get-AzureVMImage `
| where { $_.ImageFamily -eq "Windows Server 2012 Datacenter" } `
	| where { $_.Location.Split(";") -contains "West US"} `
	| Sort-Object -Descending -Property PublishedDate

Using the above snippet, only the most recent version of the “Windows Server 2012 Datacenter” image that is supported in the “West US” datacenter will be returned.

Create the Virtual Machine

Now that the desired VM OS image has been found, the New-AzureVMConfig and New-AzureVM cmdlets can be used to create the new Virtual Machine.


# Get the latest version of the Windows Server 2012 Datacenter image.
$images = Get-AzureVMImage `
| where { $_.ImageFamily -eq $imageFamily } `
	| where { $_.Location.Split(";") -contains $location} `
	| Sort-Object -Descending -Property PublishedDate
$myVM = New-AzureVMConfig -Name “myvm01” -InstanceSize “Small” -ImageName $images[0].ImageName -DiskLabel "OS" `
| Add-AzureProvisioningConfig -Windows -Password $password -AdminUsername $username -DisableAutomaticUpdates

New-AzureVM -ServiceName “myvmservice” -VMs $myVM -Location “West US” -WaitForBoot