Friday, 27 January 2012

Windows Azure and type initializer for 'System.ServiceModel.Diagnostics.TraceUtility' threw an Exception

I've been working on a new product that I'm with Windows Azure and today whilst I came to debug a WCF service within it stumbled apon an error that at first glance doesn't make a whole lot of sence, but with a bit of working backwards turns out is quite simple to fix.

The scenario: I have a WCF service setup to run in a WorkerRole as part of an Azure solution, pretty simple.

To enable me to see what was going on clearer with my service i decided to configure my system.diagnostic listeners and added the default AzureLocalStorage listener, which is created automatically for you, to my service model and message logging.
<system.diagnostics>    
    <sharedListeners>
      <add name="AzureLocalStorage" type="ServiceAuthenticationGatewayWorkerRole.AzureLocalStorageTraceListener, ServiceAuthenticationGatewayWorkerRole"/>
    </sharedListeners>
    <sources>
      <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing">
        <listeners>
          <add name="AzureLocalStorage"/>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
        <listeners>
          <add name="AzureLocalStorage"/>
        </listeners>
      </source>
    </sources>
   </system.diagnostics>
However upon running the application nothing would happen for around 30 - 60 seconds and then I was greeted with a nice TypeInitializationException.

Viewing the detail of this and the inner exceptions eventually led me to the following message:
{"Could not create xxxxxWorkerRole.AzureLocalStorageTraceListener, xxxxxxxx."}

So the AzureLocalStorageTraceListener was blowing up on type initialisation, popping open the code you see that the constructor does some work, specifically it gets the log directory of the WCF log file and combines the filename and path etc.

This looked normal, I put a breakpoint in and stepped through the GetLogDirectory method to find which line threw, my guess would be its where it calls into the RoleEnvironment and gets the local resource. Turns out this is exactly where it threw.

I had a quick gander at MSDN and found that you pass the local resource name to the method you want to load. This led me to think that the resource wasn't defined so next up was the storage configuration.

With Azure you configure local storage per role, to change the settings right click the worker role within the main Azure project, it will be in a folder called roles and open properties. You will then get a screen similar to what I had.
You will note, as I did, considering I thought I had local storage and was accessing it via the key, it wasn't setup within the role properties :(

Simply using the Add Local Storage button and entering the correct details let the project startup and start logging correctly.

What I found here is another case where the framework gives you the generic error message and not the exception that was really being thrown, RoleEnvironmentException which would have made me look at the local storage settings a lot quicker.

Any way there it is, I hope this helps :)

No comments:

Post a Comment