Compartilhar via


Windows Azure Diagnostics – Upgrading from Azure SDK 2.4 to Azure SDK 2.5

Overview

Windows Azure SDK 2.4 and prior used Windows Azure Diagnostics 1.0 which provided multiple options for configuring diagnostics collection, including code based configuration using the Microsoft.WindowsAzure.Diagnostics classes. Windows Azure SDK 2.5 introduces Windows Azure Diagnostics 1.2 which streamlines the configuration and adds enhanced capabilities for post-deployment enablement, however it removes the code based configuration capabilities. This blog post will describe how to convert your older code based diagnostics configuration to the new WAD 1.2 XML based configuration model.

 

For more information about WAD 1.2 see https://azure.microsoft.com/en-us/documentation/articles/cloud-services-dotnet-diagnostics/.

Specifying diagnostics Configuration in XML

In Azure SDK 2.4 it was possible to configure diagnostics through code as well as xml configuration (the diagnostics.wadcfg file) and developers needed to understand the precedence rules of how the diagnostics agent picks up the configuration settings (see here for more information). Azure SDK 2.5 removes this complexity and the diagnostics agent will now always use the xml configuration. This has some implications when you migrate your Azure SDK 2.4 project to Azure SDK 2.5. If your Azure SDK 2.4 project already uses the xml based diagnostics configuration then when you upgrade the project in Visual Studio to target Azure SDK 2.5, Visual Studio will automatically update the xml based configuration to the new format (diagnostics.wadcfgx). If you project continued to use the code based configuration (for example, using the API in Microsoft.WindowsAzure.Diagnostics and Microsoft.WindowsAzure.Diagnostics.Management) then when its upgraded to SDK 2.5, you will get build warnings which will inform you of the deprecated APIs. The diagnostics data will not be collected unless you configure your diagnostics using the XML file (diagnostics.wadcfgx) or through the Visual Studio diagnostics configuration UI.

 

Let’s look at an example- In Azure SDK 2.4 you could be using the code below to update the diagnostics configuration for the diagnostics infrastructure logs. In this particular example the code is setting the Loglevel for the diagnostics infrastructure logs to Error and the Transfer Period to 5 minutes. When you migrate this project to SDK 2.5 you will get a build warning around this code with the message that the API is deprecated – “Warning: ‘Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor’ is obsolete: “This API is deprecated””. The project will still build and deploy but it won’t update the diagnostics configuration.

 

clip_image002[6]

 

To configure the diagnostics infrastructure logs in Azure SDK 2.5 you must remove that code based configuration and update the diagnostics configuration xml file (diagnostics.wadcfgx) associated with your role. Visual Studio provides a configuration UI to let you specify these diagnostics settings. To configure the diagnostics through Visual Studio you can Right click on the Role and select Properties to display the Role Designer. On the Configuration tab make sure Enable Diagnostics is selected and click Configure. This will bring up the Diagnostics configuration UI where you can go to the Infrastructure Logs Tab and select Enable transfer of Diagnostics Infrastructure Logs and set the Transfer Period and Log Level Appropriately.

 

clip_image004[6]

 

Behind the scenes Visual Studio is updating the diagnostics.wadcfgx file with the appropriate xml to configure the infrastructure logs. See highlighted as an example:

<?xml version="1.0" encoding="utf-8"?>

<DiagnosticsConfiguration xmlns="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">

  <PublicConfig xmlns="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">

    <WadCfg>

      <DiagnosticMonitorConfiguration overallQuotaInMB="4096">

        <DiagnosticInfrastructureLogs scheduledTransferPeriod="PT5M" scheduledTransferLogLevelFilter="Error" />

      </DiagnosticMonitorConfiguration>

    </WadCfg>

  </PublicConfig>

  <PrivateConfig xmlns="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">

    <StorageAccount name="" endpoint="" />

  </PrivateConfig>

  <IsEnabled>true</IsEnabled>
</DiagnosticsConfiguration>

 

The diagnostics configuration dialog in Visual Studio lets you configure other settings like Application Logs, Windows Event Logs, Performance Counters, Infrastructure Logs, Log Directories, ETW Logs and Crash Dumps.

Let’s look at another example for Performance Counters. With Azure SDK 2.4 (and prior) you would have to do the following in code:
clip_image006[6]

 

With Azure SDK 2.5 you can use the diagnostics configuration UI to enable the default performance counters:

clip_image008[6]

 

For Custom Performance counters you still have to instrument your code to create the custom performance category and counters as earlier. Once you have instrumented your code you can enable transferring these custom performance counters to storage by adding them to the list of performance counters in the diagnostics configuration UI. Eg. For a custom performance counter you can enter the category and name “\SampleCustomCategory\Total Button1 Clicks” in the text box and click Add.

 

Visual Studio will automatically add the performance counters selected in the UI to the diagnostics configuration file diagnostics.wadcfgx:

<?xml version="1.0" encoding="utf-8"?>

<DiagnosticsConfiguration xmlns="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">

  <PublicConfig xmlns="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">

    <WadCfg>

      <DiagnosticMonitorConfiguration overallQuotaInMB="4096">

        <PerformanceCounters scheduledTransferPeriod="PT1M">

          <PerformanceCounterConfiguration counterSpecifier="\Processor(_Total)\% Processor Time" sampleRate="PT3M" />

          <PerformanceCounterConfiguration counterSpecifier="\Memory\Available MBytes" sampleRate="PT3M" />

        </PerformanceCounters>

      </DiagnosticMonitorConfiguration>

    </WadCfg>

  </PublicConfig>

  <PrivateConfig xmlns="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">

    <StorageAccount name="" endpoint="" />

  </PrivateConfig>

  <IsEnabled>true</IsEnabled>
</DiagnosticsConfiguration>

 

For WindowsEventLog data you can enable transfer of logs for common data sources directly from the diagnostics configuration UI.

clip_image010[6]

 

For custom event logs that you define in your code for example ->

 

EventLog.CreateEventSource("GuestBookSource", "Application");

EventLog.WriteEntry("GuestBookSource", "WebRole Started", EventLogEntryType.Error, 9191);

 

You have to manually add the custom source to the wadcfgx XML file under the WindowsEventLog node. Make sure the name matches the name specified in code:

 

<WindowsEventLog scheduledTransferPeriod="PT1M">

   <DataSource name="Application!*" />

   <DataSource name="GuestBookSource!*" />

</WindowsEventLog>

 

 

Enabling diagnostics extension through PowerShell

 

Since Azure SDK 2.5 uses the extension model the diagnostics extension, the configuration and the connection string to the diagnostic storage are no longer part of the deployment package and cscfg. All the diagnostics configuration is contained within the wadcfgx. The advantage with this approach is that diagnostics agent and settings are decoupled from the project and can be dynamically enabled and updated even after your application is deployed.

 

Due to this change some existing workflows need to be rethought – instead of configuring the diagnostics as part of the application that gets deployed to each environment you can first deploy the application to the environment and then apply the diagnostics configuration for it. When you publish the application from Visual Studio this process is done automatically for you. However if you were deploying your application outside of VS using PowerShell then you have to install the extension separately through PowerShell.

 

There PowerShell cmdlets for managing the diagnostics extensions on a Cloud Service are -

· Set-AzureServiceDiagnosticsExtension

· Get-AzureServiceDiagnosticsExtension

· Remove-AzureServiceDiagnosticsExtension

You can use the Set-AzureServiceDiagnosticsExtension method to enable diagnostics extension on a cloud service. One of the parameters on this cmdlet is the XML configuration file. This file is slightly different from the diagnostics.wadcfgx file. You can create this file from scratch as described here or you can modify the wadcfgx file and pass in the modified file as a parameter to the powershell cmdlet.

 

To modify the wadcfgx file –

1. Make a copy the .wadcfgx.

2. Remove the following elements from the Copy:

<DiagnosticsConfiguration xmlns="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">

   <PrivateConfig xmlns="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">

     <StorageAccount name=" " endpoint="https://core.windows.net/" />

   </PrivateConfig>

   <IsEnabled>false</IsEnabled>

</DiagnosticsConfiguration>

3. Make sure the top of the file still has xml version and encoding –

<?xml version="1.0" encoding="utf-8"?>

 

Effectively you are stripping down the Wadcfgx to only contain the <PublicConfig> section and the <?xml> header. You can then call the PowerShell cmdlet along with the appropriate parameters for the staging slots and roles:

$storage_name = ‘<storagename>’

$key= ‘<key>’

$service_name = '<servicename>'

$public_config = '<thepublicconfigfrom_diagnostics.wadcfgx>'

 

$storageContext = New-AzureStorageContext –StorageAccountName $storage_name –StorageAccountKey $key

 

Set-AzureServiceDiagnosticsExtension -StorageContext $storageContext -DiagnosticsConfigurationPath $public_config –ServiceName $service_name -Slot ‘Staging’ -Role ‘WebRole1’

Comments

  • Anonymous
    December 02, 2014
    The comment has been removed

  • Anonymous
    December 02, 2014
    If I create a package from visual studio and then update the cloud service through the portal... The diagnostics.wadcfgx file is ignored, I would have to update the diagnostics settings with powershell as per your article above, but if I publish directly using my subscription then it is applied. Is this the correct behaviour?

  • Anonymous
    December 03, 2014
    The comment has been removed

  • Anonymous
    December 18, 2014
    The comment has been removed

  • Anonymous
    December 18, 2014
    Another question related to ETW log table. Is the PreciseTimestamp in the table means the exact time the event get raised? The Timestamp field seems to be the event get written into the log table.

  • Anonymous
    December 18, 2014
    What is the field TIMESTAMP mean for ETW log? There is another column Timestamp in the same table.

  • Anonymous
    December 19, 2014
    @Guangjie For the Powershell Script please make sure to explicitly pass in a -Role when you set the extension. If an extension already exists and if you don't pass in the role explicitly then you may see the error mentioned. Similarly when you remove the extension make sure to explicitly pass in the -role from which you want to remove the extension. If no diagnostic extension is present on any of the roles then you can call the set extension ps without the Role to set the extension on all roles. Thanks

  • Anonymous
    December 19, 2014
    Guangjie - TIMESTAMP is PreciseTimeStamp rounded down to the upload frequency boundary. So, if your upload frequency is 5 minutes and the event time 00:17:12, TIMESTAMP will be 00:15:00. PreciseTimeStamp is the ETW timestamp of the event; i.e., the time the event is logged from the client. Timestamp - This contains the timestamp at which the entity was created in the azure table. Thanks!

  • Anonymous
    January 01, 2015
    The comment has been removed

  • Anonymous
    January 05, 2015
    When all other Azure Services are available in Nuget, any particular reason why Diagnositic is dependent on SDK version?

  • Anonymous
    January 06, 2015
    The comment has been removed

  • Anonymous
    January 13, 2015
    @Kevin - Any update on the issue I was seeing with calling Set-AzureServiceDiagnosticsExtension using the Role parameter?

  • Anonymous
    January 13, 2015
    Hi Evan, thanks for the reminder to post back here.  The problem has been identified as an issue with the extension name code in the Powershell cmdlet.  The REST API that Powershell calls doesn't support dots in the extension name.  Visual Studio will correctly remove the dots from the role name, but Powershell preserves the full role name including dots.  We will fix the Powershell code, but in the meantime the workarounds are:

  1. Remove the '.' from your role name.
  2. Use Visual Studio to enable diagnostics.
  3. Instead of using Set-AzureServiceDiagnosticsExtension, use the generic New-AzureServiceExtensionConfig / Set-AzureServiceExtension methods.
  • Anonymous
    January 13, 2015
    Having the same issue as @Evan is having... @Kevin: is there any resolution is sight?  Remove-AzureServiceDeiagnosticsExtension workaround takes minutes for my web/worker roles.

  • Anonymous
    January 13, 2015
    The comment has been removed

  • Anonymous
    January 14, 2015
    @Evan, my apologies, I thought the Set-AzureServiceExtension method also accepted a name for the extension ID, but it only accepts the name of the extension itself.  It also uses the same code path as Set-AzureServiceDiagnosticsExtension to auto-generate the extension ID.  You could also use the REST APIs which do accept an extension ID, but this is not a trivial amount of work.  Another alternative is to use the code that Gaurav created at gauravmantri.com/.../windows-azure-sdk-2-0-for-net-taking-a-second-look-at-windows-azure-diagnostics, although I haven't tested any of this code. @Roman, are you sure you are having the same issue as Evan?  Remove-AzureServiceDeiagnosticsExtension isn't part of Evan's issue so I am thinking you are seeing something different.  Can you provide more details or an error message?

  • Anonymous
    January 14, 2015
    @Kevin: Yes, I think I have the same issue as my web and worker roles have period(s) in them.  Remove-AzureServiceDiagnosticsExtension is a part of the workaround to not being able to use -Role option of Set-AzureServiceDiagnosticsExtension.  The workaround of using Remove-AzureServiceDiagnosticsExtension for every role prior to using Set-AzureServiceDiagnosticsExtension w/o -Role option is something @Evan suggested earlier in the comments.  This workaround works for me, but the extra overhead of disabling/enabling diagnostics makes PS scripts run much longer than necessary.

  • Anonymous
    January 18, 2015
    The comment has been removed

  • Anonymous
    January 22, 2015
    Hi, its me again. I was able to use the REST API to do everything i wanted, but as always with microsoft : msdn documentation is so ... not there.. So i made the following discoveries when using the code samples from gauravmantri.com/.../windows-azure-sdk-2-0-for-net-taking-a-second-look-at-windows-azure-diagnostics When adding the DiagnosticsExtension for the first time the above code samples work flawless! However, if you want to update the extensions the stuff gets tricky. You cannot create a new configuration and just apply it to the current diagnostics Extension. It will throw a protocoll error. What you have to do is, everytime you wanna add a Diagnostics extension the ID of that extension must be different to all extensions already attached to the cloud service. Once you did this you can add the new extension and use it caling ChangeDeploymentConfiguration. However you may want to delete the old Diagnostics extension configuration from the cloudservice by calling deleteExtension. You can only delete extensions by ID, and you also can only delete extensions which are not currently active( Web Exception: Conflict ) So you need to call listExtensions to get to know the ID of the previous extension. So a good approach would be. create an extension with a GUID as an ID. Update the configuration. Get All extensions Remove the extension which has your current ID , and then foreach extension call DeleteExtension. It might probably be a good idea to  implement some PUT methods for the Azure API to be able to update an existing extension without all the overhead

  • Anonymous
    February 05, 2015
    Hi Kevin, could you please guide us on how to use encrypted storage connection string. Assume that in Azure 2.5, my application is used encrypted storage string and programmatically decrypted and connected to diagnostics with DiagnosticsMonitor.StartConnectionString. Could you please guide on how to use the same scenario in SDK2.5 thanks kiran

  • Anonymous
    February 05, 2015
    modifying my previous comment - Hi Kevin, could you please guide us on how to use encrypted storage connection string. Assume that in Azure 2.4, my application is used encrypted storage string and programmatically decrypted and connected to diagnostics with DiagnosticsMonitor.StartConnectionString. Could you please guide on how to use the same scenario in SDK2.5 thanks kiran

  • Anonymous
    February 09, 2015
    I'm not good with powershell. Is there anyway to get the   StorageAccountName and StorageAccountKey from the cscfg file after deployment? This new diagnostics stuffs is getting annoying and this is the reason why i'm still at sdk 2.4. if you answer Kiran's question, it would help me too.   why would azure team think  remove the "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" setting is a good idea? it was working so well. No i can't add it in diagnostics.wadcfgx because i don't have the connection string. Only the ops team has it. i hope they bring it back in 2.6

  • Anonymous
    February 11, 2015
    @Eile, you can get the storage account name from Visual Studio by opening server explorer and browsing to the role, right-clicking the role and selecting Update Diagnostics, and it will be in the 'General' tab.  You can also do it in Powershell, but it is not as easy.  You need to run $debugpreference='continue' to enable REST API output, then run Get-AzureServiceDiagnosticsExtension and base64 decode the <PublicConfiguration> data.  You can also do it via the REST API by calling the Get Extension API. @Kiran, the storage account key is already encrypted in the <PrivateConfiguration> portion of the extension.  Are you seeing it unencrypted somewhere?

  • Anonymous
    March 03, 2015
    The comment has been removed

  • Anonymous
    March 03, 2015
    @Ryan, thanks for reporting this, I will get a bug filed.  In the meantime, if the diagnostics config is the same between both staging and production then you can manually associate the "Default-PaaSDiagnostics-Staging-Ext-0" extension with your new staging service by doing a configuration update with that extension ID.

  • Anonymous
    March 04, 2015
    Thanks very much. this is very helpful.

  • Anonymous
    March 06, 2015
    @Kevin, thank you for the quick response! Your work around would actually work great for me; however, I dont see way to do this with the currently release of the PowerShell Azure Cmdlets or with the current Management Portal.  If I'm overlooking this, can you supply a quick example on how to associate an existing diagnostic extension with a different slot? I presume a direct call to the REST API is required? On a side note, I'd like to add a suggestion to the new diagnostic extension. I've noticed that when I enable MS AntiMalware for a given slot, either through the management portal or through PowerShell, that setting is retained even after I delete the deployment.  Next time I deploy code to that slot, AntiMalware is automatically applied. It'd be great if diagnostics followed the same pattern. I don't change my diagnostic XML that often... if I could set it up once for a given cloud service and have it applied for every deployment to that service, I'd be a very happy camper.

  • Anonymous
    April 13, 2015
    An update on the issue with dot ('.') in the role name.... arsnyder16 has submitted a fix to the Github repository at github.com/.../305.  I have tested this fix and it does resolve the issue, so for now you can download the Powershell cmdlet source code with this fix.  The Powershell dev team is aware of this fix and will be incorporating it into main branch, but I don't have a date for this.

  • Anonymous
    April 21, 2015
    Our deployment requires that all the steps including setting the diagnostics storage account is done automatically. Is it at all possible with 2.5 Or I have to go back to 2.4?

  • Anonymous
    April 21, 2015
    @Musfiqur, yes, all of this can be automated.  See the "Enabling diagnostics extension through PowerShell" section for more information.

  • Anonymous
    May 01, 2015
    Hi: I wanted everybody to know that SDK 2.6 is out and it has cleaned things up considerably.

  • Anonymous
    July 13, 2015
    The comment has been removed

  • Anonymous
    November 17, 2015
    Using Azure SDK 2.7 here.  I am trying to run the Set-AzureServiceDiagnosticsExtension -StorageContext $storageContext -DiagnosticsConfigurationPath $config_path -ServiceName $service_name -Slot Production -Role "MyCompany.WokerRole" command.  However I get this error: Set-AzureServiceDiagnosticsExtension : BadRequest : Published Asset Entry for Image Microsoft.Azure.Diagnostics_PaaSDiagnostics_usall_manifest.xml not found. Can you please help?  I tried to enable diagnostics via Visual Studio (2013 update 5) as well but it gives the same exact error.   Get-AzureServiceDiagnosticsExtension -ServiceName $service_name -Slot Production does not return anything btw. Also, I have deployed the same role to another cloud service.  On that cloud service I can enable diagnostics just fine.  The only difference is that the other service does not have anything in staging, while the one with the error does (although stopped).

  • Anonymous
    November 17, 2015
    The comment has been removed

  • Anonymous
    November 17, 2015
    @Kevin  Thank you for the explanation. That helps a lot. I really could not find anything on it via searching.  Indeed the failing cloud service was created many moons ago.  So I have a follow up question. If I create a new cloud service  and deploy to it instead wouldn't that change my endpoint address/IP and then break all my apps hitting the roles from Internet? Is it possible to move the VIP as well? Thanks again for your input.

  • Anonymous
    November 17, 2015
    @Hooman You can keep your IP by using Powershell to create a Reserved IP from your existing IP:       New-AzureReservedIP -ReservedIPName {new reserved IP name} -Location {location} -ServiceName {existing service name} Then when you deploy your new service you would specify that Reserved IP in the new CSCFG.  Note that this will incur a short period of downtime as you delete the old one and create the new one.   A better alternative, if you are able to utilize it, is to use CNAME mappings instead of IP address mappings.  In this case you would be able to simply deploy a new cloud service, update your CNAME, then wait for a bit until all clients are pointed over to the new cloud service.

  • Anonymous
    November 23, 2015
    @Kevin Thank you very much for the guidance.