[UPDATE 1/27/2011] This post was during the SDK 1.1 timeframe. The current SDK version is 1.3, and this is no longer an issue.
If you’re using the cloud templates in Visual Studio, you’ll see a line in the
OnStart() method in
WorkerRole.cs that looks like this:
You might be tempted to put this line somewhere else (like in an ASP.NET page), but please resist that temptation. At the moment, if you call
DiagnosticMonitor.Start() more than once, you’ll end up with multiple copies of the Windows Azure Diagnostics process. Much like a memory leak, this will sneak up on you over time (as more processes get started), and you’ll eventually starve your role instance of resources.
We’ve seen this come up more than once in customers’ applications, and we have a bug open on our side to prevent duplicate calls to
DiagnosticMonitor.Start() from starting multiple copies of the process in the future.
What About Changing Diagnostics Settings Later?
One reason you might be tempted to call
DiagnosticMonitor.Start() again is to use different configuration settings. (Maybe based on an admin user’s actions or a specific error condition, you want to ramp up your logging.)
One of the nice things about Windows Azure Diagnostics is that it can be dynamically configured, and you don’t need to call
DiagnosticMonitor.Start() again to do that. Here’s some code that runs in an ASP.NET web page and changes the configuration settings for the current role instance:
using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.ServiceRuntime; using Microsoft.WindowsAzure.Diagnostics.Management; ... // same connection string used in the call to DiagnosticMonitor.Start() in WebRole.cs var account = CloudStorageAccount.Parse( RoleEnvironment.GetConfigurationSettingValue("DiagnosticsConnectionString")); // use the current deployment ID var diagnosticsManager = new DeploymentDiagnosticManager(account, RoleEnvironment.DeploymentId); // find the RoleInstanceDiagnosticManager for this role instance var thisInstance = RoleEnvironment.CurrentRoleInstance; var instanceManager = (from manager in diagnosticsManager.GetRoleInstanceDiagnosticManagersForRole(thisInstance.Role.Name) where manager.RoleInstanceId == thisInstance.Id select manager).Single(); var cfg = instanceManager.GetCurrentConfiguration(); cfg.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1); instanceManager.SetCurrentConfiguration(cfg);
Note that changes to your diagnostic configuration are picked up asynchronously by the diagnostic monitor, so you won’t see your changes take effect immediately. Take a look at
ConfigurationChangePollInterval to configure how often configuration changes are picked up.
The Bottom Line
If you’re going to use Windows Azure Diagnostics at all in your application, I recommend calling
DiagnosticMonitor.Start() exactly once, in your role’s
OnStart() method. Then use dynamic configuration to change settings at runtime.