Bare metal logging – Trace with AzureDiagnosticsTraceFilter
Following the principle of “do the simplest possible thing that works” for diagnostics is to just instrument you application using .NET’s System.Diagnostic.Trace feature. Just use Trace.WriteLine to log information as your application is executing, for example:
Trace.WriteLine(“Trace information goes here”, “Category goes here”);
The category information is optional but can help provide context or filtering information
For an application running in Azure you can add the following to your web.config or app.config to cause your trace information to be written to a an Azure Table:
type=“Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=18.104.22.168, Culture=neutral, PublicKeyToken=31bf3856ad364e35”
This will cause all of the trace information to be written to an Azure Table called WADLogsTable. The storage account that gets used is configured as part of the diagnostic configuration.
This approach is the absolute easiest and fastest way to instrument your application for diagnostics. It’s no frills but done properly it is extremely effective. With the addition of the Azure trace listener you have the convenience of being able to review the logging information in a table. It would be really easy to write a tool to make reading the logs easier.
Enterprise Library – Custom Trace Listener for Azure Table Storage
While just using the Diagnostic Trace object will get the job done most applications benefit from something a little more sophisticated. This is where libraries like Log4Net, NLog and Logging Application Block (refered to as LAB from here on) come in to the picture.
My practice is to use the Enterprise Library in my projects so logging is performed through LAB. However, at this time LAB does not have a built in way to write messages to Azure Storage. There are some tricks involving configuring Azure Diagnostics local resources that are supposed to copy the text files in to Azure Blob storage, however I’ve not been able to make them work. Rather than continuing to hack my way through the mystery it was actually easier to just write my own TraceListener that writes what I want to Azure Table storage in the way I want it written.
In order to create the trace listener you first have to get the LAB from NUGet. Create a class library project and add references to the LAB assemblies (see the sample). You’ll also need to get the Windows Azure Storage package from NuGet and add references to it.
Inside your class library project create a class that inherits from CustomTraceListener and override TraceData, Write, and WriteLine.
You’ll need to create an entity that inherits from Azure Storage’s TableEntity. The benefit of this is that you can shape your log table to look anyway you want. The TableEntry object I created has a subset of the properties from LAB’s LogEntry object. In the constructor I set the PartitionKey and RowKey using a date time string.
For the trace listener to work it will need to be configured with information about the storage account, account key and the name of the table to write entries to. This is done as part of the TraceListener’s configuration. You can either use the EntLib configuration utility or just hand write the configuration yourself. The resulting configuration information looks like this:
<add ListenerDataType=”Microsoft….CustomTraceListenerData, Microsoft….Logging”
AccountName=”account goes here” AccountKey=”[key goes here”
Once you have your TraceListener put together and added to your project you can then write a tool to view the log in whatever way you want. Because the partition key cuts off by the day you easily filter the log to view just a day at a time if you wish.
Inside you application you simply use LAB as usual. In fact if you have existing application that use LAB you can just throw in the new trace listener and start benefiting from it.
The sample code can be downloaded here. The packages will have to be restored from NuGet before it can be built.
Where to next?
What I’ve outlined here is very simple logging. I did not address strategies or anything else. Just plain old – I need to know what my application is doing logging. Nothing else. At this time I’m looking at the Semantic Logging Application Block to see what it offers. I’m also exploring ways to introduce Aspect Orient Programming (AOP) in to existing applications in order to add logging aspects without having to make major refactoring changing to them. New applications may be worth starting off with AOP in place from the very begging, but I need to look at how well Unity supports AOP.