How to detect slow responses in Umbraco API

Unearth slow responses in Umbraco v8 API using ActionFilters. Dive into a step-by-step guide to set up performance tracking and enhance your site's speed.

Why Address Slow API Responses?#

Performance issues can tarnish your users’ experience and your site’s reputation.

Tackling slow responses benefits you by:

1. Spotting delays: Quickly identify slow API calls.

2. Improving efficiency: Pinpoint bottlenecks and optimize them.

3. Streamlining integrations: Eliminate glitches for smoother operations.

4. Boosting user satisfaction: Faster responses equal happier users.

The Concept: Benchmarking API Performance#

To detect slow responses, we use a custom ActionFilterAttribute that tracks how long each API request takes.

If a response exceeds the predefined threshold, we log it for analysis.

How It Works:

  1. Track the start time when the API action begins.
  2. Measure the elapsed time once the action is completed.
  3. Log any responses that exceed the defined threshold.

This approach ensures efficient monitoring without adding unnecessary overhead.

Step 1: Implementing the API Performance Tracking Filter#

Here’s the code for a custom filter to monitor API performance:

public sealed class UmbracoApiPerformanceTrackingAttribute : ActionFilterAttribute
{
   public override void OnActionExecuting(HttpActionContext actionContext)
   {
      //We start measuring the request

      base.OnActionExecuting(actionContext);
   }

   public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
   {
      //We finish the measurement and log the information when the request is slow

      return base.OnActionExecutedAsync(actionExecutedContext, cancellationToken);
   }
}

For our filter to function effectively, we'll integrate specific components:

  • Stopwatch: Enables precise time measurement between the start and end of actions.
  • HttpContext.Current.Items: Useful for temporarily storing the Stopwatch.
  • Logger: Essential for recording details of slow requests.
  • Configurable parameters: ProfilingModeEnabled and SlowResponseMinTimeInMilliseconds.

Here, ProfilingModeEnabled is a switch for our profiler, while SlowResponseMinTimeInMilliseconds establishes our threshold for a 'slow' request.

public sealed class UmbracoApiPerformanceTrackingAttribute : ActionFilterAttribute
{
   private const string StopWatchCacheKey = "UmbracoPerformanceTracking_Stopwatch";

   public override void OnActionExecuting(HttpActionContext actionContext)
   {
      if (AppConfigProvider.ProfilingModeEnabled)
      {
         var stopwatch = Stopwatch.StartNew();

         HttpContext.Current.Items[StopWatchCacheKey] = stopwatch;
      }

      base.OnActionExecuting(actionContext);
   }

   public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
   {
      if (AppConfigProvider.ProfilingModeEnabled)
      {
         Stopwatch stopwatch = (Stopwatch)HttpContext.Current.Items[StopWatchCacheKey];

         stopwatch.Stop();

         if (stopwatch.ElapsedMilliseconds >= AppConfigProvider.SlowResponseMinTimeInMilliseconds)
         {   
            Current.Logger.Warn(typeof(UmbracoCustomLoggingAttribute), $"SLOW RESPONSE (took more than {AppConfigProvider.SlowResponseMinTimeInMilliseconds}): {stopwatch.ElapsedMilliseconds} [ms] - {actionExecutedContext.Request.Method} {actionExecutedContext.Request.RequestUri}");
         }
      }

      return base.OnActionExecutedAsync(actionExecutedContext, cancellationToken);
   }
}

Step 2: Applying the Filter#

You can apply this filter to specific API methods or entire controllers.

This flexibility allows targeted performance monitoring.

Example:

[UmbracoApiPerformanceTracking]
public class SlowUmbracoApiController : UmbracoApiController
{
   public IHttpActionResult SlowEndpointA(string id)
   {
      return Json("Hello from Endpoint A");
   }

   public IHttpActionResult SlowEndpointB(string id)
   {
      return Json("Hello from Endpoint B");
   }
}

Use this attribute wherever you suspect performance issues to start collecting actionable data.

Step 3: Optimizing Logging for Production#

Logging slow responses is critical, but excessive logs in production can overwhelm your system.

Use Serilog to fine-tune logging levels for better performance.

Configure Serilog for Production:

  1. Navigate to the \config directory.
  2. Open serilog.config.
  3. Locate <appSettings>.
  4. Set the serilog:minimum-level to Warning to log only important events.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <!-- VALID Values: Verbose, Debug, Information, Warning, Error, Fatal -->
        <add key="serilog:minimum-level" value="Warning" />
    </appSettings>
</configuration>

Conclusion: Make Your API Fast and Reliable#

Detecting slow responses is just the start.

By implementing this guide, you’ll gain the tools to optimize your API’s performance, delivering a smoother user experience.

Here’s why you should take action now:

  • Enhance performance: Speed up your API responses.
  • Gain insights: Understand where your site struggles.
  • Delight users: Fast sites keep visitors coming back.

Need Help? Contact our expert team for personalized support.

We’ll help you unlock the full potential of your Umbraco website.

Further Reading#

  • Explore Phil Haack’s article, HttpModule For Timing Requests, for a deep dive into ASP.NET request timing.
  • Check out more performance tips and best practices on our blog.
↑ Top ↑