Azure Websites, EPiServer 7.5, log4net

EPiServer, Azure Websites and simple logging with log4net

So you are an EPiServer developer and have build many fancy sites using EPiServer CMS. You are used to use the default log4net logging on your sites and have configured the logging to log to a certain location on disk. Now you are going to host your EPiServer site on Azure Websites but what about logging? You already know that with Azure Websites you basically don’t have access to the underlying virtual machines disks. You might know there exists the log4net appender for Azure Table and Blob storage. Unfortunately that can’t be used currently as we are stuck with log4net version 1.2.10 because of (current) EPiServer dependencies.

So the solution is to write your own Azure table or blob storage appender but wait does the Azure Websites infrastructure actually provide us a way to log to a file(s)? Yes it does. Short version you always have d:\home\ folder (environment variable %HOME% refers to this) which is mapped to your Azure Websites hosting virtual machine. Read the Operating System Functionality Available to Applications on Azure Websites or see the Q&A on social forum or the diagnostics logging documentation.

On the Azure management portal if you choose your Azure Websites site and navigate to the dashboard you can see on the right hand side (not using the preview dashboard) you can see your site FTP/FTPS login information. Use WinSCP or some other FTP/FTPS client to connect and browse the structure. If you navigate to the root you should see /data, /LogFiles and /site folders. LogFiles folder sounds a good place to place our web site logs too.

I will use log4net RollingFileAppender so my configuration looks like this for the appender:

<appender name="errorFileLogAppender" type="log4net.Appender.RollingFileAppender" >
	<!-- log to azure websites LogFiles folder -->
	<file value="..\..\LogFiles\EPiErrors.log" />
	<encoding value="utf-8" />
	<staticLogFileName value="true"/>
	<!-- roll files based on size -->
	<rollingStyle value="Size" />
	<!-- roll the file when the size reaches 50MB -->
	<maximumFileSize value="50MB" />
	<!-- keep at maximum 7 log files before deleting them -->
	<maxSizeRollBackups value="7" />
	<threshold value="Error" />
	<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
	<appendToFile value="true" />
	<layout type="log4net.Layout.PatternLayout">
		<conversionPattern value="%date [%thread] %level %logger: %message%n" />
	</layout>
</appender>

So I use relative path for the log file based on knowing how the structure is in Azure Websites.

All great case closed but wait.. what about if I scale my site to use more than one instances? I don’t want the situation where both instances of the web site try to log to the same file (you do remember that / you did read that all instances have the folders mapped from an UNC). So we need a dynamic way of defining the log file name to have separate log files per site instance. This is easily accomplished with log4net. So I changed my configuration a bit:

<file type="log4net.Util.PatternString" value="..\..\LogFiles\EPiErrors-%property{log4net:HostName}.log" />

Adding the type to the file element we can use log4net properties (%property{XXXX}). By default the log4net:HostName property is set to the name of machine on which the event was originally logged. So this solves the need to be able to dynamically define the log file name per machine and now I get separate files per machine when scaling out the site.

So is there a catch somewhere? Yes. If using the Free or Shared plan you have 1GB of disk which is shared with all your web sites on that plan. If using basic plan you have 10GB and with standard plan you have 50GB disk so with these plans you have more room to spend disk for logging. So keep in mind what plan you are using and how you should configure the rolling of log files.