NewRelic (http://newrelic.com) is a great performance monitoring tool. We use it for nearly all of our clients and it provides a wealth of information on things like page speed, server responsiveness, .NET errors, database connectivity, and more.
The only problem from our perspective is that it requires the installation of software on the server (the “server agent” and monitoring tools).
In Azure, this can be a problem, because every time Azure instances disappear they are reimaged from scratch based on the most recent “package” that was deployed to them. This can and does happen, and there is no warning as to when this might occur. You’ll simply arrive one morning to find your monitoring is gone.
If this deployment package that you sent to the server didn’t include the NewRelic installation, then you can kiss your monitoring goodbye. You’ll have to reinstall it manually.
Installing NewRelic in Visual Studio
NewRelic’s default installation instructions for Azure can be found here: https://docs.newrelic.com/docs/agents/net-agent/azure-installation/azure-cloud-services
Effectively, the crux of this is:
- Install Nuget package for NewRelic in your VS.NET solution.
- Enter licence key and application name.
- Deploy to Azure using VS.NET.
This is great if you’re using Visual Studio.NET to deploy directly to Azure.
It is also worth noting that in order to do this, you need the Azure SDK on your machine and you need to be using an Azure .NET “Cloud Service Project”, not a regular web application project.
Unfortunately when using Sitecore’s Azure module, this process is abstracted through the module itself. The module handles deployment – you don’t deploy anything at all through Visual Studio. What you do instead is create deployment packages and deploy your code to a particular deployment (on-premises) server, then kick off an “Upgrade Files” from there to push your changes up to Azure.
In fact, if you run the command as per the NewRelic instructions and install the Nuget package, it will download the files correctly into the “packages” folder on your development environment, but will then spit out errors that look like this:
***Updating the Windows Azure ServiceDefinition.csdef with the newrelic.cmd Startup task***
Unable to find the ServiceDefinition.csdef file in your solution, please make sure your solution contains an Azure deployment project and try again.
***Updating the Windows Azure ServiceConfiguration.*.cscfg files with the license key***
Unable to find any ServiceConfiguration.cscfg files in your solution, please make sure your solution contains an Azure deployment project and try again.
***Updating the projects .config file with the NewRelic.AppName***
These errors are occurring because I’m using a regular web application project in Visual Studio, not an Azure SDK “Cloud Service Project” instead.
Picking Up The Slack
NewRelic got us part of the way there. It provided us, as part of the package, with a batch file (newrelic.cmd) and a couple of installer files.
With a bit of digging (thanks to: https://discuss.newrelic.com/t/nuget-doesnt-work-with-cloud-service-project-in-visual-studio-2013/5550/13), I was able to find the snippets of code that NewRelic actually uses to run said startup script. These snippets failed to install during the Nuget package install (see above) because, as I said, I’m using a regular web application and not an Azure SDK-style project.
For those of you who’ve delved a bit deeper into Sitecore Azure module, you’ll know that it generates the ServiceDefinition.csdef and ServiceConfiguration.cscfg files automatically from fields within Sitecore. You’ll find these fields on the relevant “Production” or “Staging” nodes in your content tree on the system -> modules -> Azure -> Environment -> Region -> Farm -> Role -> Deployment node.
For example, if you want to modify the fields for the Australia East production deployment, you’d look for the node:
… Australia East -> Delivery01 -> Role01 -> Production
Step 1 – The Installer & Script
The first step is to get Sitecore to include the batch file (newrelic.cmd) and the two installers in the upload process. This will include them as part of the website itself, so that you can then kick off an install once the system has processed the deployment package itself.
In order to do this, first, copy the files from the packages\NewRelicWindowsAzure.126.96.36.199\content folder on your machine (or the location where your Nuget packages get installed). In my case, these files are:
Place these files on the deployment
server in the folder: %wwwroot%\App_Data\AzureOverrideFiles\bin. This will ensure they are uploaded to the bin folder on any new Azure instance along with your actual website files.
Step 2 – Modify the Config
You’d then modify the two fields to incorporate snippets.
Note that you should include the NewRelic task after the default Sitecore startup task. These snippets tell Azure:
- to run the newrelic.cmd batch file, which installs the two installers that are included with your deployment; and,
- to look for a configuration setting in the ServiceConfiguration.cscfg file for the NewRelic license key
<?xml version="1.0" encoding="utf-16"?> <ServiceDefinition ... > <WebRole name="SitecoreWebRole" enableNativeCodeExecution="false" vmsize="ExtraLarge"> ... <Startup> ... <Task commandLine="newrelic.cmd" executionContext="elevated" taskType="simple"> <Environment> <Variable name="EMULATED"> <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" /> </Variable> <Variable name="IsWorkerRole" value="false" /> <Variable name="LICENSE_KEY"> <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/ConfigurationSettings/ConfigurationSetting[@name='NewRelic.LicenseKey']/@value" /> </Variable> </Environment> </Task> </Startup> <ConfigurationSettings> ... <Setting name="NewRelic.LicenseKey" /> </ConfigurationSettings> ... </WebRole> </ServiceDefinition>
This minor change defines the NewRelic licence key (you should have your own or use your client’s key) so that it can be referred to by the installers.
<?xml version="1.0" encoding="utf-16"?> <ServiceConfiguration ...> <Role name="SitecoreWebRole"> <ConfigurationSettings> ... <Setting name="NewRelic.LicenseKey" value="xxxxxxxxxxxxx" /> </ConfigurationSettings> ... </Role> </ServiceConfiguration>
Step 3 – Setting the Application Name
Finally, you need to modify the Web.config of your application to include the name of the application that you’d like to appear in NewRelic.
By default, NewRelic’s Nuget installation would have added the name to your Web.config.
You may want to alter this. If you just want to change it for your entire application, then by all means, just go and change it in the Web.config file.
However, if you want to do it on a per-region basis, for example, or even have a separate application name for Editing, for example, then you can’t just modify the Web.config because Sitecore’s Azure module will deploy the same Web.config to all instances regardless.
In order to deploy a server- or region-specific application name (or otherwise), you’ll need to again make use of the fields Sitecore has available on the “Production” or “Staging” nodes in the Content Editor.
In this case, you update the Custom Web Config Patch field to include the following XSLT transform snippet:
<xsl:template match="/configuration/appSettings"> <xsl:copy> <xsl:apply-templates select="node()|@*" /> <xsl:element name="add"> <xsl:attribute name="key">NewRelic.AppName</xsl:attribute> <xsl:attribute name="value">My Application Name</xsl:attribute> </xsl:element> </xsl:copy> </xsl:template>
This will add the relevant application key to the generated Web.config. Because this is done on each deployment node, you can have a different name for each deployment if you want.
Deploy It And You’re Away
I’m not going to pretend this will all work perfectly the first time around, but I just tried it and it seemed to work quite seamlessly. Clearly there are some issues, like leaving a batch file and two installers in your website’s bin folder, but presumably you could get rid of these through some other startup mechanism if you really had to.
For the time being, though, this is a small price to pay to have monitoring installed automatically on the server instances.
If you have any thoughts or comments about this process, or you’d just like to thank us for posting it, feel free to reply with a comment.
Written by Christian Brenner
Head of Technology