locked
Azure Diagnostics: Access to the path '(GUID)-mswapd-lock' is denied? RRS feed

  • Question

  • Code and configuration:

    I've enabled Diagnostics per the official tutorial at https://www.windowsazure.com/en-us/develop/net/common-tasks/diagnostics/. My diagnostic initializer is invoked from Global.asax (no WebRole.cs for this WCF ported to Azure WebRole) and its quite simple like:

    public bool Initialize()
    {
        DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();
        config.WindowsEventLog.DataSources.Add("Application!*");
        config.WindowsEventLog.ScheduledTransferPeriod = System.TimeSpan.FromMinutes(1.0);
        DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);
    
        return true;
    }
    
    

    Cloud and Local strings same:

    I'm using the SAME cloud based diagnostic connection string for local and cloud configurations.

    <?xml version="1.0" encoding="utf-8"?>
    <ServiceConfiguration serviceName="MyApp.API.Azure1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="2" osVersion="*" schemaVersion="2012-05.1.7">
      <Role name="MyApp.API">
        <Instances count="1" />
        <ConfigurationSettings>
          ...
          <Setting name="Microsoft.WindowsAzure.Plugins.Caching.ConfigStoreConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myapi;AccountKey=MyVeryLongStringHereWhichIsActuallyAKeyForAPlaceInTheCloudWhereUnicornsDanceUnderDoubleRainbows" />
        </ConfigurationSettings>
        <Certificates>
          <Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" thumbprint="ThumbPrintStringsAreBiggerThanPinkiePrintString" thumbprintAlgorithm="sha1" />
        </Certificates>
      </Role>
    </ServiceConfiguration>
    

    Error:

    When I run the above within Azure Emulator (local compute) I do not get the error (despite the cloud connection string for diagnostics). When I run the webrole on Azure (with same diagnostic sting and of course, code), I get the following error:

        [UnauthorizedAccessException: Access to the path '05d5e525-e1bc-4a37-8bfb-010bb2941301-mswapd-lock' is denied.]
       System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +12895415
       System.Threading.MutexTryCodeHelper.MutexTryCode(Object userData) +229
       System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) +0
       System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew, MutexSecurity mutexSecurity) +629
       System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew) +18
       Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.StartDiagnosticsMonitorProcess(DiagnosticMonitorStartupInfo info) +171
       Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.ReconfigureMonitoringProcess(ConfigRequest req) +209
       Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.UpdateState(DiagnosticMonitorStartupInfo startupInfo) +207
       Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.StartWithExplicitConfiguration(DiagnosticMonitorStartupInfo startupInfo, DiagnosticMonitorConfiguration initialConfiguration) +643
       Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.Start(CloudStorageAccount storageAccount, DiagnosticMonitorConfiguration initialConfiguration) +47
       Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.Start(String diagnosticsStorageAccountConfigurationSettingName, DiagnosticMonitorConfiguration initialConfiguration) +108
       myApp.api.Diag.Diagnostics.Initialize() in c:\Work\MyApp.API\source\Diag\Diagnostics.cs:42
       Global.Application_Start(Object sender, EventArgs e) in c:\Work\MyApp.API\source\Global.asax.cs:30

    Attempts: None worked

    • Disabled all Azure monitoring and logging (from portal) for this storage account in case Azure's own monitoring/logging mechanisms were locking it down
    • Replaced UseDevelopmentStorage=true with real cloud connection string for diagnostics even for local configuration (local compute/Azure emulator).
    • Simplified diagnostic initializer to bare minimum (seen above). However, DiagnosticMonitor.Start(...) always fails.
    • Created another diagnostic connection string in .cscfg file (with reference in .csdef too) so that if the original Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString is also used by Azure infrastructure, I have another string for it. No help, same error.

    I've burnt many hours trying to debug this but I always get this error on Azure.

    Question:

    Can someone help me get rid of this error? I can try a few ideas you may have. I'm disappointed by the MS tutorial but disappointment doesn't help.


    • Edited by Sid.S Monday, September 10, 2012 7:03 PM formatting
    Monday, September 10, 2012 7:01 PM

Answers

  • Akorch, unlike that blog entry, I'm already handling everything in global.asax. However studying his example I was able to get it working. It seems that diagnostic monitor is already running by the time my global.asax start method is called. Why is is already running? Unfortunately, I don't know ...

    Anyway, since it's running, instead of 'starting' it I'm now only modifying the configuration (SetCurrentConfiguration like you said) as follows:

    public bool Initialize()
    {
      // This is from your ServiceConfiguration.Cloud.cscfg file
      String wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
      
      CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));
      
      RoleInstanceDiagnosticManager roleInstanceDiagnosticManager = cloudStorageAccount.CreateRoleInstanceDiagnosticManager(RoleEnvironment.DeploymentId,RoleEnvironment.CurrentRoleInstance.Role.Name, RoleEnvironment.CurrentRoleInstance.Id);
      
      config = roleInstanceDiagnosticManager.GetCurrentConfiguration();
      
      if (!config.WindowsEventLog.DataSources.Contains("Application!*"))
      	config.WindowsEventLog.DataSources.Add("Application!*");
      
      config.WindowsEventLog.ScheduledTransferPeriod = System.TimeSpan.FromMinutes(1.0);
      
      roleInstanceDiagnosticManager.SetCurrentConfiguration(config); 
      
      return true;
    }
    
    

    I see the above configuration ("Application!*") in the file named "<staging ID>/<appname>/<instance id>" within the wad-control-container blob. Plus I see the actual logs populate inside the WADWindowsEventLogsTable table too.

    I'm now facing a different problem where my custom logs are causing a security exception :/ That's a separate post ...

    Why Microsoft doesn't address Windows Azure Diagnostics as a first class citizen I don't know. All the work done by the WAD team is bottlenecked if there is little usable, working documentation for using the features.

    • Marked as answer by Sid.S Thursday, September 20, 2012 12:53 AM
    Thursday, September 20, 2012 12:53 AM

All replies

  • No solution for this from me unfortunately, just wanted to say I'm having exactly the same issue - have you been able to work around it?

    Cheers

    Wednesday, September 12, 2012 11:29 AM
  • Hi Tony,

    Sorry, no workaround so far. I'm surprised that nobody from MSFT's team has looked into this either considering the push MS is giving to Azure - and that diagnostics is such a key integral component of the overall platform. So far it just seems that the official tutorial is broken. MSFT support used to be a lot more responsive before.

    If nothing happens over the next few days, I'm afraid we will go down the ELMAH route. That's a shame because we did want to keep everything "in-platform" but honestly, from a business perspective the show much go on.

    If you do figure out a solution, please do post back - it will help the rest of us!

    Regards!

    Wednesday, September 12, 2012 5:31 PM
  • Here's a suggestion that worked for me.

    http://blog.ehuna.org/2011/02/how_to_fix_the_errors_unauthor.html

    The diagnostics class expects the context to be available, but with IIS + .net 4 the context is not available in the start method. You need to change where the diagnostics initialization code is run. 

    Don't use the start method, use SetCurrentConfiguration instead. 

    • Marked as answer by Jiang Yun Wednesday, September 19, 2012 2:12 AM
    • Unmarked as answer by Sid.S Wednesday, September 19, 2012 7:37 PM
    Wednesday, September 12, 2012 6:16 PM
  • So, I did solve this by not calling the start method as suggested, and instead using set current configuration - letting the diagnostics module do the starting for me.

    And all was well.

    Except, 3 days later, with the app in use, the same symptom came back - users suddenly started getting the above exception, and all was not well.

    Almost as though my app pool recycled, diagnostics is still running and it tries to start it again.

    Starting to get a bit infuriated with this now, need MSFT to give us the final word on using the diagnostic module in a web app, reliably!

    Thanks for answers though.

    Wednesday, September 19, 2012 12:57 PM
  • Oh, one more thing Sid, we are using Elmah with Azure table storage too - we use elmah to record user experienced exceptions, and we're using diagnostics for all general logging (trace logs, debug info, etc, which elmah doesn't tell us).

    Getting elmah working with table storage is a bit of a pain, and not the best solution, but if you clear the log often enough, it's workable.

    Cheers

    Wednesday, September 19, 2012 12:59 PM
  • Akorch, unlike that blog entry, I'm already handling everything in global.asax. However studying his example I was able to get it working. It seems that diagnostic monitor is already running by the time my global.asax start method is called. Why is is already running? Unfortunately, I don't know ...

    Anyway, since it's running, instead of 'starting' it I'm now only modifying the configuration (SetCurrentConfiguration like you said) as follows:

    public bool Initialize()
    {
      // This is from your ServiceConfiguration.Cloud.cscfg file
      String wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
      
      CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));
      
      RoleInstanceDiagnosticManager roleInstanceDiagnosticManager = cloudStorageAccount.CreateRoleInstanceDiagnosticManager(RoleEnvironment.DeploymentId,RoleEnvironment.CurrentRoleInstance.Role.Name, RoleEnvironment.CurrentRoleInstance.Id);
      
      config = roleInstanceDiagnosticManager.GetCurrentConfiguration();
      
      if (!config.WindowsEventLog.DataSources.Contains("Application!*"))
      	config.WindowsEventLog.DataSources.Add("Application!*");
      
      config.WindowsEventLog.ScheduledTransferPeriod = System.TimeSpan.FromMinutes(1.0);
      
      roleInstanceDiagnosticManager.SetCurrentConfiguration(config); 
      
      return true;
    }
    
    

    I see the above configuration ("Application!*") in the file named "<staging ID>/<appname>/<instance id>" within the wad-control-container blob. Plus I see the actual logs populate inside the WADWindowsEventLogsTable table too.

    I'm now facing a different problem where my custom logs are causing a security exception :/ That's a separate post ...

    Why Microsoft doesn't address Windows Azure Diagnostics as a first class citizen I don't know. All the work done by the WAD team is bottlenecked if there is little usable, working documentation for using the features.

    • Marked as answer by Sid.S Thursday, September 20, 2012 12:53 AM
    Thursday, September 20, 2012 12:53 AM
  • It seems that this problem occurred to me because Azure Diagnostics settings were set in web.config. Then I attempted to change them as you described inside Application_Start method a similar exception was thrown.

    Removing lines bellow from web.config:

    <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">

    <filter type="" />

    </add>

     fixed the problem. Still I'm thinking if it is a good decision because I wan't to adjust diagnostics settings provided in web.config and not set-up them during the app start. There might be some events that won't be logged because of lack of configuration before application started so having logging configured is better option in my opinion.

    Wednesday, November 7, 2012 10:35 AM