When deploying Umbraco into an Azure WebApp the Umbraco documentation has a word of warning around the performance of the underlying disc/storage for the Umbraco webroot:

"The first important thing to know about Azure Web Apps is that it uses a remote file share. This means that the files being used to run your website do not exist locally to the server that is serving your website. In many cases this isn't an issue but it can become an issue if you have a large amount of IO operations like Lucene indexing due to IO latency of the remote file share."

There is subsequent advice on how to configure Umbraco so that the cache file and Examine Indexes are written to local temporary storage on the underlying machine that is hosting the Azure WebApp.

Logging Levels

Umbraco 7 logging is based on Log4Net - and elsewhere in Umbraco documentation there is sound advice to ensure that your root logger is set to a Threshold of WARN or ERROR to avoid excessive disc writes to the remote file share - as by default Umbraco logging writes to the ~/App_Data folder - which is hosted on that share. Configuring the logging threshold is as simple as modifying it in your ~/config/log4net.config configuration file.

<root>
        <priority value="WARN"/>
        <appender-ref ref="AsynchronousLog4NetAppender" />
</root>

A common issue that we see is that a developer will temporarily set this threshold to DEBUG - while working on a project, so it is also a good idea to use a .net configuration transform to set this value on deployment to your production environment. An example configuration transform to do this is as follows:

<?xml version="1.0"?>
<log4net xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <root>
        <priority xdt:Transform="Replace" value="WARN"/>
    </root>
</log4net>

Logging to local storage

Just as Examine and the Umbraco cache are written to the faster local storage of the underlying machine that the web app is running on, we can do the same with log files for faster storage writes. Log4Net allows the use of tokens in configuration and the token %env{TEMP} will resolve to the environment temporary directory. In our log4net appenders - we can tokenise the path as follows:

<appender name="rollingFile" type="log4net.Appender.RollingFileAppender">

        <file type="log4net.Util.PatternString" value="%env{TEMP}\UmbracoLogs\UmbracoTraceLog.%property{log4net:HostName}.txt" />

How do i see my logs

You may be used to viewing your log files, using the Azure app service editor - but this only exposes the web root, so we'll need to go and look at our log files using Kudu. You can access Kudu using:

  • https://my-app-name.scm.azurewebsites.net/DebugConsole/?shell=powershell

By default, you'll be at the webroot of your application so issue the command "cd .." to change directory up a level to the root of the D:\ drive.

You can now click into the d:\local\temp directory which is where our logs will now be written.

I can't see the logs!

By default Azure runs the Kudu application and your website in separate processes - so you can't see the files written to the temp folder by the main website application. To disable this you can set a web app setting - called WEBSITE_DISABLE_SCM_SEPARATION with a value of true (see https://github.com/projectkudu/kudu/wiki/Configurable-settings).

With this setting in place, you'll now be able to see the Umbraco log files in d:\local\temp along with the Umbraco cache file and Examine indexes.

It is advisable to only have this setting in place when you are browsing the log files.

Won't my log files get lost on App Service failover?

Yes - Azure periodically replaces the machine running your app with another, this happens routinely - from my observation about once a month - or sometimes in the event of an App Service scale event.

As your log files reside on the machine itself, rather than shared network storage you'd lose access to your logs.

If it is important that you retain access to these logs, then you may want to write something that hooks into the ASP.NET application OnApplicationEnd event. This could copy your log files to Azure blob storage for persistence.

In .NET code you can access the local temp folder using the following piece of code:

Environment.ExpandEnvironmentVariables("%temp%")

Any other performance tips?

Yes! plenty. I'll try to blog here - other the coming weeks with other tuning tips that we've discovered.

Other things to consider when deploying into Azure app service include:

  • Pre compiling your Razor Views
  • Generating your preview cache XML file to local temp storage
  • Backing up and restoring the Umbraco cache file on app recycle
  • Avoid excessive operations in Application startup - deferring until necessary.

Can you help me set this up?

Yes! Moriyama support customers have optimisations applied to their sites in Azure Webapps automatically as part of our managed devops service. Give us a call for more details.

Send us a message

If you would prefer to speak to someone, please give us a call on 020 3745 4285