Sitecore performance analysis with New Relic

logo_NR-twFor several years already an application performance monitoring tool called New Relic is the default instrument to get detailed performance metrics from many of our web platforms we develop at Valtech.

We use it to gather detailed insights in the inner workings of many of our applications, even in real-time when they run in a production environment. It allows us to find and troubleshoot performance related issues fast. Not only in the .NET backend logic with the APM product but also in the logic happening on the frontend with the Browser product.

A small bump in the road

One of the technologies we implement at Valtech is the Sitecore Experience Platform. Wouldn’t it be great if you could get detailed performance metrics from your running Sitecore instances on production? I took on the task to find a suitable tool to make this a reality. After evaluating AppDynamics and LeanSentry I found the most suitable tool in New Relic. Although New Relic had great features and a very easy to use web dashboard it didn’t have support for Sitecore out of the box. As you can read on the compatibility page New Relic only supports Umbraco and Episerver CMS technologies but not Sitecore. The main issue is that all transaction (web requests) are reported in New Relic with their physical layout file, layout.aspx for example, and not with the requested URL. Which in turn makes the transaction and web request overview pretty useless.

Challenge accepted

I like a good challenge so this challenge was accepted! The nice thing of New Relic is that it also provides a SDK which you can implement in your web app. As it turned out, this SDK can be used to change the behavior of New Relic at run-time. One method grabbed my interest, the SetTransactionName method. This method can be used to set any transaction name for the current request. Exactly what we need but when to set it? After lots of trial and error I discovered that the only reliable point in time was during application initialization and to be precise, during the ASP.NET OnAuthenticateRequest life cycle event. To learn more about all the life cycle events see:

At this point in time we also have a Sitecore context to play with. The Sitecore context is essential to grab the current site and current item being requested. In this particular case the New Relic implementation had to support a platform hosting +20 different websites. So, during the OnAuthenticateRequest we grab the current site and item and use this to construct a correct and friendly transaction name.

You are also able to ignore particular requests passing to New Relic. For example requests to static resources or images from the Sitecore media library. The IgnoreTransaction method can be used to achieve this.

A module was born

The final solution was the implementation of a custom NewRelicHttpModule which you can download from the Sitecore Marketplace.

Custom Sitecore tasks

Although New Relic is great for profiling the .NET framework and your own custom code it will need a hand if you are doing fancy stuff like starting new threads during run-time. If you create custom Sitecore tasks which run in the background then the Sitecore task runner system will create a new thread to run your task in. In this case your background task will not be picked up automatically by New Relic. The solution is to tell New Relic about your task by specifying your classes and methods in a custom New Relic instrumentation file. The extensive New Relic documentation will tell you in great detail how you can accomplish this.

A Sitecore task can be seen as a non-web transaction. By implementing custom instrumentation all your Sitecore tasks can also be made visible in the New Relic dashboards.

A broken Sitecore Rich Text Editor

When you also use New Relic to measure the frontend performance with the Browser product and when you also have this running on your Sitecore CMS instance then you might run into issues with the Sitecore Rich Text Editor, it will break. The reason is because New Relic by default automatically injects a piece of Javascript in any page to be able to measure all operations in the browser, which conflicts with Sitecore.

The solution is simple, you can disable the frontend performance monitoring per application and thus for the CMS instance. See the documentation on how to disable the browser monitoring feature.