In my attempts to purge the DiagnosticMonitorConfiguration
I have tried the following:
But I still see extra copies of DirectoryConfiguration
members inside the DiagnosticMonitorConfiguration's Directory data sources. These extra copies were accidentally added when the global.asax's Application_Start()
was called everytime the IIS thread would be retired (20 min idle time). I've copy-pasted the BUGGY code showing how they were added (eventually I got an exception like OverallQuotaInMB is 150MB but sum of requested sub-quotas is 850MB
).
Question: I understand why there are duplicated. However, despite trying the actions in the above bullet list, why isn't the DiagnosticMonitorConfiguration getting purged? Exactly how is it's state being persisted? I can only think it's gotta be Azure table or Azure SQL - but that's just a guess.
// called from global.asax's Application_Start()
public bool Initialize()
{
RoleInstanceDiagnosticManager roleInstanceDiagnosticManager = getRoleInstanceDiagnosticManager();
config = roleInstanceDiagnosticManager.GetCurrentConfiguration();
if (config == null)
config = DiagnosticMonitor.GetDefaultInitialConfiguration();
LocalResource localResource = RoleEnvironment.GetLocalResource("MyAppLogFolder");
DirectoryConfiguration dirConfig = new DirectoryConfiguration();
dirConfig.Container = "myapplog-blob";
dirConfig.DirectoryQuotaInMB = localResource.MaximumSizeInMegabytes;
dirConfig.Path = localResource.RootPath;
// This is a BUG, keeps adding duplicate entries
config.Directories.DataSources.Add(dirConfig);
limitOtherDefaultDirSizes(config); // limits overall quota to 150MB
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(10.0);
roleInstanceDiagnosticManager.SetCurrentConfiguration(config);
return true;
}
Remote debugging shows the DiagnosticMonitorConfiguration data structure to be as below. You can clearly see the dups here, warranting the exception.
- config {Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorConfiguration}
- Directories {Microsoft.WindowsAzure.Diagnostics.DirectoriesBufferConfiguration}
- DataSources Count = 85 System.Collections.Generic.IList<Microsoft.WindowsAzure.Diagnostics.DirectoryConfiguration>
+ [0] {Microsoft.WindowsAzure.Diagnostics.DirectoryConfiguration}
+ [1] {Microsoft.WindowsAzure.Diagnostics.DirectoryConfiguration}
+ [2] {Microsoft.WindowsAzure.Diagnostics.DirectoryConfiguration}
- [3] {Microsoft.WindowsAzure.Diagnostics.DirectoryConfiguration}
Container "myapplog-blob" string
DirectoryQuotaInMB 10 int
Path "C:\\Resources\\directory\\73c8a6bf9a5e434ab3d0c44034e7b7e9.MyAPP.API.MyAppLogFolder\\" string
- [4] {Microsoft.WindowsAzure.Diagnostics.DirectoryConfiguration}
Container "myapplog-blob" string
DirectoryQuotaInMB 10 int
Path "C:\\Resources\\directory\\73c8a6bf9a5e434ab3d0c44034e7b7e9.MyAPP.API.MyAppLogFolder\\" string
+ [5] {Microsoft.WindowsAzure.Diagnostics.DirectoryConfiguration}
...
+ [84] {Microsoft.WindowsAzure.Diagnostics.DirectoryConfiguration}
Take a look at the following article on MSDN: Overview of Windows Azure Diagnostics
You should consider the following when implementing Windows Azure Diagnostics:
- The configuration information is stored in an XML file in Windows Azure blob storage under /wad-control-container/deploymentID/rolename/roleinstance
The configuration is persisted in an XML file in blob storage for the current deployment. In your code you're calling GetCurrentConfiguration
which will load this XML file. And then you'll keep appending the directory over and over again (which means each recycle will try to add a directory to the current configuration).
GetCurrentConfiguration
is great when you're trying to modify the settings remote (ie: you want to add some performance counters after the app has been deployed). If you always call GetDefaultInitialConfiguration(); you'll start with a clean slate.
PS: Try putting this code in the WebRole.cs, that way it will only execute once when your instance starts, and not slow down the application pool each time it starts.