Diagnostics of Azure Web Sites – Custom Logging


In the first part of these series, I talked about built-in diagnostics features of Windows Azure platform and mentioned that it gives high-level diagnostic information; for detail troubleshooting information a custom logging capability is recommended. In this post, I will propose a solution that writes custom/detail logs to Azure storage tables.  Please note that this post is only relevant to web sites – web sites that are hosted in Windows Azure platform.


This post is not going to be about discussing “Everything is going to cloud?” or “Public vs Private Cloud” thing. However, in order to give you the solution standing, I would like to give you the big picture; and there it isSmile 


Source: http://www.notsotrivial.net/blog/image.axd?picture=image_38.png


Windows Azure SDK 1.0 and 2.0 editions comes with Microsoft.WindowsAzure.Diagnostics API that is built on top of ETW (Event Tracing for Windows) let’s write diagnostic information through the listeners. However, I could not use it for the web site, I was getting this exception when configure to use Azure diagnostics:

"SecurityException: The source was not found, but some or all event logs could not be searched. To create the source, you need permission to read all event logs to make sure that the new source name is unique. Inaccessible logs: Security"

As the message implies, I need to change permission levels as discussed here. But, that can’t be used for the web sites, but for Windows Azure cloud services (web and worker roles). For underlying design difference, please visit here. By design, you can’t run web sites with elevated permissions and can not RDP.

Proposed Solution

Ok, that should be enough background info. Let’s action.

Step 1: Create a storage account 

  1. Login into Azure portal
  2. Click on ‘Storage’ link on the left navigation
  3. Click on ‘ + New’ icon
  4. Provide information on the pop up, reference the image on the right
  5. Once, the storage service created, note Account name, primary and secondary keys as seen on the image located on right bottom.


Step 2: Write custom logging component

  • In order to use storage table, we need a service context object. To construct it, we need at least those:

    1. Account name -defined above
    2. Account key (Primary or Secondary) -defined above
    3. Table name Add connection string – your wish
  • Construct the service context
   1: static Logger()

   2: {

   3:     var storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(accountName, accountKey), true);

   4:     var tableClient = storageAccount.CreateCloudTableClient();


   6:     tableName = "LogTrace";

   7:     tableClient.CreateTableIfNotExist(tableName);

   8:     serviceContext = tableClient.GetDataServiceContext();

   9: }

  • Create an entity holds log properties, sample here
   1: public class TraceLog : TableServiceEntity

   2: {

   3:     public string Message { get; set; }

   4:     public string Type { get; set; }

   5:     public int Code { get; set; }

   6:     public DateTime TimeStamp { get; set; }

   7: }

  • And the method for log functionality
   1: public static void LogTrace(string message, EventLogEntryType type)

   2: {

   3:     LogEntry(message, type, 7018);

   4: }


   6: private static void LogEntry(string message, EventLogEntryType etype, int eCode)

   7: {

   8:     string type = etype == EventLogEntryType.Error

   9:                       ? "Error"

  10:                       : etype == EventLogEntryType.Warning ? "Warning" : "Information";

  11:     string pkey = string.Format("{0:D10}", DateTime.Now.Ticks >> 30);

  12:     string rkey = string.Format("{0:D19}", DateTime.Now.Ticks);


  14:     serviceContext.AddObject(tableName, new TraceLog { PartitionKey = pkey, RowKey = rkey, Message = message, Type = type, Code = eCode, TimeStamp = DateTime.Now });

  15:     serviceContext.SaveChanges(SaveChangesOptions.ContinueOnError);

  16: }


Step 3: Validation

Now, to test the solution, all we need to call the method; here I am calling from Application_Start() in the global.asax to trace when the application starts

   1: protected void Application_Start()

   2: {

   3:     AreaRegistration.RegisterAllAreas();


   5:     WebApiConfig.Register(GlobalConfiguration.Configuration);

   6:     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

   7:     RouteConfig.RegisterRoutes(RouteTable.Routes);

   8:     BundleConfig.RegisterBundles(BundleTable.Bundles);

   9:     AuthConfig.RegisterAuth();


  11:     Helpers.Logger.LogTrace("Web site started on server", EventLogEntryType.Information);

  12: }

Press F5:), voila! I am able to see the entry in the storage table from the Storage Explorer tool as seen below (table name set to ‘TraceLog’):




In this post, I stated that Azure diagnostic API is not usable for web sites and then shared a solution that writes custom logs to Windows Azure storage table  with Geo-Replication capability. Hope you like it and happy clouding!



Troubleshooting in Windows Azure

Enabling Diagnostics in Windows Azure