So you’ve installed or upgraded to the Windows Azure SDK 1.3 and you decided to use the new feature that allows you to host multiple sites in one web role. Unfortunately, if you are using azure diagnostics, when you run your web role in the azure fabric (locally or in the cloud), you get an exception similar to this:
A secondary issue is that you may receive an exception similar to this -
That sucks, doesn’t it? No worries, below I have the solution on how to make it all work.
How to fix the errors “[UnauthorizedAccessException: Access to the path '[{Guid}-mswapd-lock' is denied.]” or “"Response is not available in this context"" when using Azure Diagnostics 1.3 in a web role hosted in full IIS with multiple sites.
With the windows azure SDK 1.3, when you are hosting your web role in full IIS, Microsoft introduced a module that simplifies how you work with azure diagnostics. The module name is ‘Diagnostics’ and you’ll see it defined in your ServiceDefinition.csdef file like this -
In your ServiceConfiguration.cscfg you can now define the azure storage connection string that is used by the diagnostics module, like this -
The Problems
If you don’t make any changes to how you initialize your azure diagnostics, you may see the exception below -
Server Error in '/' Application.
Access to the path 'fd96b10b-a304-48c9-9faa-18d2dfa5682f-mswapd-lock' is denied.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Access to the path 'fd96b10b-a304-48c9-9faa-18d2dfa5682f-mswapd-lock' is denied.
ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, and the configured application pool identity on IIS 7.5) that is used if the application is not impersonating. If the application is impersonating via <identity impersonate="true"/>, the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user.
To grant ASP.NET access to a file, right-click the file in Explorer, choose "Properties" and select the Security tab. Click "Add" to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[UnauthorizedAccessException: Access to the path 'fd96b10b-a304-48c9-9faa-18d2dfa5682f-mswapd-lock' is denied.]
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +12892935
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) +201
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
[...]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +3988565
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +325
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375
[HttpException (0x80004005): Access to the path 'fd96b10b-a304-48c9-9faa-18d2dfa5682f-mswapd-lock' is denied.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11529072
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4784373
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
Pasted from <https://advertiserwc.dev-lslightning.com/User/Login?ReturnUrl=%2f>
[UnauthorizedAccessException: Access to the path 'fd96b10b-a304-48c9-9faa-18d2dfa5682f-mswapd-lock' is denied.]
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +12892935
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) +201
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
MYNAMESPACE.Azure.Diagnostics.DiagnosticsSetup.Start() in C:\MYSOURCE\Development\Source\MYNAMESPACE.Azure\Diagnostics\Diagnostics.cs:231
MYNAMESPACE.Azure.Diagnostics.DiagnosticsSetup.All() in C:\MYSOURCE\Development\Source\MYNAMESPACE.Azure\Diagnostics\Diagnostics.cs:47
MYNAMESPACE.Web.MvcApplication.Application_Start() in C:\MYSOURCE\Development\Source\MYNAMESPACE.Web.Advertiser\Global.asax.cs:114
[HttpException (0x80004005): Access to the path 'fd96b10b-a304-48c9-9faa-18d2dfa5682f-mswapd-lock' is denied.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +3988565
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +325
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375
[HttpException (0x80004005): Access to the path 'fd96b10b-a304-48c9-9faa-18d2dfa5682f-mswapd-lock' is denied.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11529072
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4784373
Neil Mackenzie has more details on how this works here.
At the same time, you read up on the changes in how azure configuration works, and you realize you need to move your configuration initialization code to Global.asax Application_Start() – Steve Marx has details on how this works here.
The ‘Full IIS’ model with the Windows Azure SDK 1.3 from Steve Marx’s blog enty
But as you move code from your WebRole.cs OnStart() event to your Global.asax Application_Start() event, you now get the error -
Server Error in '/' Application.
Response is not available in this context.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: Response is not available in this context.
Source Error:
Line 248: CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));
Line 249:
Line 250: DeploymentDiagnosticManager deploymentDiagnosticManager =
Line 251: new DeploymentDiagnosticManager(cloudStorageAccount, RoleEnvironment.DeploymentId);
Line 252:
Source File: C:\MYSOURCECODE\Development\Source\MYPROJECT.Azure\Diagnostics\Diagnostics.cs Line: 250
Stack Trace:
[HttpException (0x80004005): Response is not available in this context.]
Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.get_Result() +95
Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.ExecuteAndWait() +201
Microsoft.WindowsAzure.StorageClient.CloudBlobContainer.CreateIfNotExist(BlobRequestOptions options) +213
Microsoft.WindowsAzure.Diagnostics.Management.DeploymentDiagnosticManager.EnsureContainer() +70
MYPROJECT.Azure.Diagnostics.DiagnosticsSetup13.ConfigureDiagnostics(Int32 transferPeriod, Int32 performanceSampleRate) in C:\MYSOURCECODE\Development\Source\MYPROJECT.Azure\Diagnostics\Diagnostics.cs:250
MYPROJECT.Web.MvcApplication.Application_Start() in C:\MYSOURCECODE\Development\Source\MYPROJECT.Web.MYSITE1\Global.asax.cs:115
[HttpException (0x80004005): Response is not available in this context.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +3988565
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +325
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375
[HttpException (0x80004005): Response is not available in this context.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11529072
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4784373
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
This is due to a .NET 4 issue where the response context is not available in the Application_Start() event, but it is being called in the azure diagnostics manager constructor.
The Solution
The solution is to move both your configuration and azure diagnostics initialization to your Global.asax Application_BeginRequest() event. Since this occurs on every single request, you can setup a static variable to make sure your initialization code runs only once -
Below I have the full code listing for both the Application_BeginRequest() event and the azure diagnostics calls I wrote to setup my favorite performance counters.
Please note the above fix is needed for web roles hosted in Full IIS – you won’t have these problems on the azure 1.3 sdk if your web roles run under the old ‘hosted web core’ or if you are running worker roles.
Code Listing
To make sure your initialization code is called only once, setup your static variables in your Global.asax.cs class -
public class MvcApplication : System.Web.HttpApplication
{
#region Privates
private static object _gate = new object();
private static bool _initialized = false;
#endregion
...
}
Then in your site’s Application_BeginRequest() do this -
protected void Application_BeginRequest()
{
// Had to move azure role initialization here
// See http://social.msdn.microsoft.com/Forums/en-US/windowsazuredevelopment/thread/10d042da-50b1-4930-b0c0-aff22e4144f9
// and http://social.msdn.microsoft.com/Forums/en-US/windowsazuredevelopment/thread/ab6d56dc-154d-4aba-8bde-2b7f7df121c1/#89264b8c-7e25-455a-8fd6-20f547ab545b
if (_initialized)
{
return;
}
lock (_gate)
{
if (!_initialized)
{
// Moved all this diagnostics and configuration setup from WebRole.cs
// See http://blog.smarx.com/posts/how-to-resolve-setconfigurationsettingpublisher-needs-to-be-called-before-fromconfigurationsetting-can-be-used-after-moving-to-windows-azure-sdk-1-3
#region Setup CloudStorageAccount Configuration and Azure Diagnostics
if (RoleEnvironment.IsAvailable)
{
// This code sets up a handler to update CloudStorageAccount instances when their corresponding
// configuration settings change in the service configuration file.
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
// Provide the configSetter with the initial value
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
RoleEnvironment.Changed += (sender, arg) =>
{
if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
.Any((change) => (change.ConfigurationSettingName == configName)))
{
// The corresponding configuration setting has changed, propagate the value
if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
{
// In this case, the change to the storage account credentials in the
// service configuration is significant enough that the role needs to be
// recycled in order to use the latest settings. (for example, the
// endpoint has changed)
RoleEnvironment.RequestRecycle();
}
}
};
});
// Adding the listener here instead of the Web.config because the Azure trace listener will cause
// problems when running in IIS, so loading it here will ensure it is only active when running in Azure.
Trace.Listeners.Add(new DiagnosticMonitorTraceListener());
DiagnosticsSetup13.ConfigureDiagnostics(1, 1);
//If you have some logging class, call it here to show your configuration and diagnostics are initialized
//LightningEventLog.LogMessage("Role started - Azure Diagnostics and Lightning email alerts initialized.", EventLogEntryType.Information);
}
#endregion
_initialized = true;
}
}
}
And here’s the class responsible for initializing the azure diagnostics, with some of my favorites performance counters (notice that we don’t need to start the diagnostics agent, like we did without the diagnostics module/plug-in, but we still need to define what we want the diagnostics manager to capture) -
using System;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.Diagnostics.Management;
using Microsoft.WindowsAzure.ServiceRuntime;
namespace MYPROJECT.Azure.Diagnostics
{
// See http://convective.wordpress.com/2010/12/01/configuration-changes-to-windows-azure-diagnostics-in-azure-sdk-v1-3/
// For now implementing it static as per sample code, later to follow up to do it in a more elegant way
public
static class DiagnosticsSetup13
{
static public void ConfigureDiagnostics(int transferPeriod, int performanceSampleRate)
{
String wadConnectionString =
"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));
// Do not call the next line from Application_Start() - there's a bug in .NET 4.0 that will cause a "System.Web.HttpException: Response is not available in this context."
// See http://social.msdn.microsoft.com/Forums/en-US/windowsazuredevelopment/thread/10d042da-50b1-4930-b0c0-aff22e4144f9
// and http://social.msdn.microsoft.com/Forums/en-US/windowsazuredevelopment/thread/ab6d56dc-154d-4aba-8bde-2b7f7df121c1/#89264b8c-7e25-455a-8fd6-20f547ab545b
// This was not used in Neil McKenzie's sampel code, so I commented it out
//DeploymentDiagnosticManager deploymentDiagnosticManager =
// new DeploymentDiagnosticManager(cloudStorageAccount, RoleEnvironment.DeploymentId);
RoleInstanceDiagnosticManager roleInstanceDiagnosticManager =
cloudStorageAccount.CreateRoleInstanceDiagnosticManager(
RoleEnvironment.DeploymentId,
RoleEnvironment.CurrentRoleInstance.Role.Name,
RoleEnvironment.CurrentRoleInstance.Id);
DiagnosticMonitorConfiguration diagnosticMonitorConfiguration =
roleInstanceDiagnosticManager.GetCurrentConfiguration();
diagnosticMonitorConfiguration.Directories.ScheduledTransferPeriod =
TimeSpan.FromMinutes(transferPeriod);
diagnosticMonitorConfiguration.Logs.ScheduledTransferPeriod =
TimeSpan.FromMinutes(transferPeriod);
diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add("Application!*");
diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add("System!*");
diagnosticMonitorConfiguration.WindowsEventLog.ScheduledTransferPeriod =
TimeSpan.FromMinutes(transferPeriod);
PerformanceCounterConfiguration performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\Processor(_Total)\% Processor Time";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\Memory\Available MBytes";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET Applications(__Total__)\Requests/Sec";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\WFPv4\Active Outbound Connections";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\Network Interface(*)\Bytes Sent/sec";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\Network Interface(*)\Bytes Received/sec";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET\Request Execution Time";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET\Request Wait Time";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET\Requests Queued";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET\Requests Rejected";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET Applications(__Total__)\Cache % Machine Memory Limit Used";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET Applications(__Total__)\Cache Total Entries";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET Applications(__Total__)\Cache Total Hit Ratio";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
performanceCounterConfiguration = new PerformanceCounterConfiguration();
performanceCounterConfiguration.CounterSpecifier = @"\ASP.NET Applications(__Total__)\Cache Total Turnover Rate";
performanceCounterConfiguration.SampleRate = TimeSpan.FromSeconds(performanceSampleRate);
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
diagnosticMonitorConfiguration.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(transferPeriod);
roleInstanceDiagnosticManager.SetCurrentConfiguration(diagnosticMonitorConfiguration);
}
}
}
References
Here are are a bunch of links from windows azure forum threads and blog entries that helped me get to the solution above -
Two sites in a web role: one gets
System.UnauthorizedAccessException when Azure diagnostics is initialized
Issues with v1.3 SDK
http://social.msdn.microsoft.com/Forums/en-US/windowsazuredevelopment/thread/ab6d56dc-154d-4aba-8bde-2b7f7df121c1/
Configuration Changes to Windows Azure Diagnostics in Azure SDK v1.3
http://convective.wordpress.com/2010/12/01/configuration-changes-to-windows-azure-diagnostics-in-azure-sdk-v1-3/
How to Resolve “SetConfigurationSettingPublisher needs to be called before FromConfigurationSetting can be used” After Moving to Windows Azure SDK 1.3
http://blog.smarx.com/posts/how-to-resolve-setconfigurationsettingpublisher-needs-to-be-called-before-fromconfigurationsetting-can-be-used-after-moving-to-windows-azure-sdk-1-3
Good times!
Comments