Basic Logging within Web Jobs


When you are a developer it’s very easy to debug code, step through it and understand exactly what is happening at different parts of the code. When the code is finally shipped to a production environment, you are virtually blind to what is happening within your code unless you put sufficient logging within the code. (Or you are lucky enough to use Visual Studio to debug production environment, something that you probably shouldn’t do).

The basic way to log within WebJobs is using Console.Writeline or Trace from the System.Diagnostics.

Console.Writeline() logs

By using the Console.Writeline you only write to the Web Job logging window. These do not display as errors, warning or information. They are just plain print out to screen.

To get to the web job logging screen head to https://portal.azure.com then select your web app. On the All settings blade, select Web Jobs, then on the Web Jobs blade it will list all the web jobs currently assigned to this web app. The logs URL is stored on the right hand side of the screen. Click this link and it will take you through to your logs. Normally the URL is similar to the following https:// <WebAppName> .scm.azurewebsites.net/azurejobs/#/jobs/ <ContinuousOrTriggered> / <WebJobname>

Trace logs

The trace logs are stored within Azure Storage Blobs or Tables, which will need to be set up and configured. (This is shown later in this blog post). They do not show up in the Web Job window as described above for the Console.Writeline(). Please note that the Trace logs are not just for Web Jobs, you can use them in your web application, and most of this information will work for Web Apps.

Within your code, all you need to do is add a using statement to System.Diagnostics. Then you have a choice of logging an information, a warning, an error, or verbose message log.

System.Diagnostics.Trace.TraceInformation("This creates an information log");
System.Diagnostics.Trace.TraceWarning("This creates a warning log");
System.Diagnostics.Trace.TraceError("This creates an error log");
System.Diagnostics.Trace.WriteLine("This creates a verbose log");

Configuring Blob and Table logging.

Unfortunately I’m unable to find any way of doing this in the new Azure Portal. Therefore for these set of instructions I’m using the old Azure Portal https://manage.windowsazure.com

First you will need to create a Storage if you don’t already have one to use. In the old portal, you can do this just by clicking the New button at the bottom of the screen, and then selecting Data Services > Storage > Quick Create

Now head to your Web App, and click on the CONFIGURE tab, and on the CONFIGURE tab, scroll down until you reach the application diagnostics section.

In the Application Diagnostics section there are 3 different places you can set up logging.

  1. File System – This is written to the Web App file system, you can access these logs from the FTP share for this Web App. Please note: Application Logging is only enable for 12 hours. (Not part of this post)
  2. Table Storage – The logs are collected in the table storage that is specified. You can access the traces from the specified table in the storage account. Please note: These logs will remain in the Storage table increasing in size until someone clears the logs.
  3. Blob Storage – The logs are collected in the blob contain that is specified. You can access the traces from the specified container in the storage account. Please note: By default, application diagnostic logs are never deleted, however you have an option to set a retention period between 1 and 99999 days.

Configuring Blob Storage

Following on from the last section, to configure the Blob Storage click the ON button of the Application Logging (Blob Storage). Once you have clicked ON you will be presented with some other values.

The logging level options are Verbose, Error, Warning and Information. By setting the level at a given status, will depend which trace appear in the logs.

  • Verbose – Shows all logs.
  • Information – Shows Information, Warnings and Errors.
  • Warnings – Shows only Warnings and Errors.
  • Errors – Shows just Errors.

Next Click on manage blob storage, and you will be presented with a dialog. Select the Storage Account you created previously, and then Create a new blob container. Give your container a name, and then click the tick button.

Next you can set the retention in days to store the logs. Click Save on the page and the Blob Storage has been set up.

Configuring Table Storage

Configuring the Table Storage isn’t much different from configuring the Blob Storage. The only difference really is you are creating a new table instead of a new blob container. Click the ON button of the Application Logging (Table Storage). Once you have clicked ON you will be presented with some other values.

The logging level options are Verbose, Error, Warning and Information. By setting the level at a given status, will depend which trace appear in the logs.

  • Verbose – Shows all logs.
  • Information – Shows Information, Warnings and Errors.
  • Warnings – Shows only Warnings and Errors.
  • Errors – Shows just Errors.

Next Click on manage table storage, and you will be presented with a dialog. Select the Storage account you created previously, and then Create a new table. Give your table a name, and then click the tick button.

How to view the application diagnostic logs.

The biggest issue with Blob and Table storage in Azure is that there isn’t a simple way within Azure to view the information stored within them. There are plenty of 3rd party tools out there, that allow you to view blob and table storage for free. Azure Storage Explorer 6 is a free Windows application that you can use. It’s available on CodePlex https://azurestorageexplorer.codeplex.com/ however as useful as it can be, it is a bit painful, as you need download blob file to view once found, or filter the table to find the logs you are looking for. Also it is a windows application viewer looking at your Azure storage. Meaning if you use multiple PC’s, you need to ensure this is installed on all PC’s you use.

I try not to suggest 3rd party apps/extensions in my blog post, however I do like the Azure Web Site Log Browser written by Amit Apple. Amit Apple blog site http://blog.amitapple.com/ seems to just live and breathe Web Jobs, and I have learnt many things about Web Jobs from his blog. To install his extension you can do this directly from the new Portal or going to Site Extensions within you website scm. I will show both ways below how to do this.

Installing Azure Web Site Log Browser via Azure Portal

  • Head to your Web App in the Azure new portal. https://portal.azure.com
  • In the Web-App blade, along the menu buttons, select Tools.
  • On the Tools blade, select Extensions from the bottom of the Develop section.
  • Then in the Installed web app extensions blade, click Add.

  • On the Add Web Extension blade, you can choose an extension from the Choose web app extension blade. At time of writing this, Azure Web Site logs Browser is the 5th extension from the list. Click Azure Web Site Logs Browser.

  • Then click the OK button to accept terms. Then lastly, click the OK button to add the extension to your site. It takes a few moments to install into your Web App. It will only be installed on this Web Application.

  • Lastly on the Web App blade Click the restart button. This will ensure the Azure Web Site Logs Browser has fully installed.
  • To ensure it has worked. Click on the extension within the Installed web app extensions blade, and then click on Browse button on the Azure Web Site Logs Browser blade.
  • This will take you to https://<YourWebApp>.scm.azurewebsites.net/websitelogs/#

Installing Azure Web Site Logs Browser via SCM website.

  • Click on the Gallery tab, this will display all available site extensions.

  • As you can see from the screen shot, Azure Web Site Logs Browser is the first item in the second row at the time of writing this. You could search for it, by typing Azure Web Site Logs in search box.
  • Click the + button and this will install Azure Web Site Logs Browser to your Web App.
  • After it has successfully install, click the Restart Site button in the top right hand corner of the screen. This will ensure everything has been loaded up correctly.
  • By clicking on the Installed tab of Site extensions and then clicking the play button.
  • This will take you to https://<YourWebApp>.scm.azurewebsites.net/websitelogs/#

Viewing Application Logs – Blob Storage.

In my web job which I have set up logs for both Blob and Table reporting, I have a simple loop that displays some trace informations, warnings and errors, with some sleep threading in between to make sure the webjob lasts more than 10 seconds.

Trace.WriteLine("We are about to loop."); 

for (int i = 0; i < 20; i++)
{
   Trace.TraceInformation(String.Format("This is an information message brought to you by BasicLogging Web Job, looping for the {0} time", i)); // Write an information message
   Thread.Sleep(2000);

   Trace.TraceWarning("I'm warning you, don't get me angry.");
   Thread.Sleep(2000);

   Trace.TraceError("That's it, I'm annoyed now!");
   Thread.Sleep(2000);

   Trace.TraceInformation("Ok, I'm sorry, I got a little mad I'm OK now.");
   Thread.Sleep(4000);
}
Trace.WriteLine("End of the loop.");

I have then run this web job once. Now I wish to view this in the Blob storage within my site extension. This you would think would be easy to find. Unfortunately it’s not, this is down to Azure, not the site extension. The location of the blob file is different depending on the name of the application, name of the web job, date/time, website instance and website process ID of the web job. Please note: If the web job runs from one hour into the next, it will create the same named file in two different hour folders.

Typical path would look like:

/blobapplication/<WebSiteName>-<TriggeredOrContinous>-<WebJobName>/<CurrentYear>/<CurrentMonth>/<CurrentDay>/<CurrentHour>/<InstanceIdFirst6Char>-<ProcessId>.applicationLog.csv

If you have a web job that runs every hour on the hour, then it’s not that difficult to find, but a web job that runs on demand can be difficult to find. Therefore I write to the WebJob Log using Console.WriteLine the location of the log, using code that calculates the location of the file. This way if there is a reason I need to look into the trace logs of a given web job instance, I just view the web job to get the link to the file.

var instanceID = Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID").Substring(0, 6);
var pid = Process.GetCurrentProcess().Id;
var currentTime = DateTime.UtcNow;
var filename = instanceID + "-" + pid + ".applicationLog.csv";

//Location of the blob file path within the Azure Web Site logs extension
var filePath = "https://" + Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME") + 
                             ".scm.azurewebsites.net/WebSiteLogs/#/blobapplication/" + 
                             Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME") + 
                             "-triggered-" + Environment.GetEnvironmentVariable("WEBJOBS_NAME") + "/" +
                            currentTime.Year + "/" + currentTime.Month.ToString().PadLeft(2,'0') + "/"  + 
                           currentTime.Day.ToString().PadLeft(2, '0') + "/" +
                           currentTime.Hour.ToString().PadLeft(2, '0') + "/" ;

//Location of the blob file to download within the Azure Web Site log Extension
var linkToDownload = "https://" + Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME") + 
                     ".scm.azurewebsites.net/WebSiteLogs/api/log?path=/blobapplication/" +
                     Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME") + 
                     "-triggered-" + Environment.GetEnvironmentVariable("WEBJOBS_NAME") + "/" +
                     currentTime.Year + "/" + currentTime.Month.ToString().PadLeft(2,'0') + "/"  +
                     currentTime.Day.ToString().PadLeft(2, '0') + "/" +
                     currentTime.Hour.ToString().PadLeft(2, '0') + "/" + filename + "&download=true";

Console.WriteLine(String.Format("FilePath Link: {0}", filepath));
Console.WriteLine(String.Format("Download csv file: {0}", linkToDownload));

Using the actual Azure Web Site Log Browser, you can view the csv log file directly in the browser. Using the filePath link that I’m displaying in the Web Job log window, this takes you to the Azure Web Site Log Browser.

By clicking on the file it opens the CSV in the browser.

Using this browser, you can view the logs. You can use Search to find key words within your application.

The columns available within a blob storage is defined by Azure, you cannot add or remove these columns. These columns provide you more granular information about the event. The following properties are used for each row in the CSV:

  • Date – The date and time that the event occurred
  • Level – The event Level (Verbose, Error, Warning, Information)
  • Application Name – The web app name, in our case the WebApp – TypeOfWebJob – WebJobName.
  • InstanceId – Instance of the Web app that the event occurred on.
  • EventTickCount – The date and time that the event occurred, in Tick format
  • EventId – The event ID of this event, defaults to 0 if none specified.
  • Pid – Process ID of the web job
  • Tid – The thread ID of the thread that produced the event.
  • Message – The event detail message
  • ActivityID – This is only included if you set up the Activity ID in the code. This can be useful especially for continuous webjobs as all the jobs processed will be entered into the same csv file.

Setting the Activity ID in code

//Add to the start of the code
var correlationGuid = Guid.NewGuid();
Trace.CorrelationManager.ActivityId = correlationGuid;
Console.WriteLine(String.Format("ActivityID for this job: {0}, correlationGuid"));

Viewing Application Logs – Table Storage.

The URL for table logs within the Azure Web Site Log Browser is https://<WebSiteName>.scm.azurewebsites.net/websitelogs/viewtable.cshtml

On landing on the page, it shows the last 20 items found within the table. However you can change the date, number of items, or what to search for using search. There is also sorting within the columns. I have put the ActivityID in search (see end of last section how to assign Activity ID in code), and this has brought back all log items for that web job.

The columns available within a table storage is defined by Azure, you cannot add or remove these columns. These columns provide you more granular information about the event. The following properties are used for each row in the table:

  • Date – The date and time that the event occurred
  • Level – The event Level (Verbose, Error, Warning, Information)
  • Instance – Instance of the Web app that the event occurred on.
  • Activity – This is only included if you set up the Activity ID in the code.
  • Message – The event detail message

If you open the row of information on the table using Visual Studio/Azure Storage 6 or another tool, there are additional columns that contains information that isn’t shown within the Azure Web Site Log Browser.

  • PartitionKey – The Date Time of the event in yyyyMMddHH format
  • RowKey – A GUID value that uniquely identifies this entity
  • Timestamp – The date and time that the event occurred
  • EventTickCount – The date and time that the event occurred, in Tick format
  • Application Name – The Web App Name
  • EventId – The event ID of this event, defaults to 0 if none specified.
  • InstanceId – Instance of the Web app that the event occurred on.
  • Pid – Process ID of the web job
  • Tid – The thread ID of the thread that produced the event.

References:

Amit Apple Blog – http://blog.amitapple.com/ (Creator of the Azure Web Site Log Browser)

Microsoft Azure – Enable diagnostics logging for web apps in Azure App Service – https://azure.microsoft.com/en-us/documentation/articles/web-sites-enable-diagnostic-log/

Advertisements