Jump to Section
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:
- Track the start time when the API action begins.
- Measure the elapsed time once the action is completed.
- 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:
- Navigate to the \config directory.
- Open serilog.config.
- Locate <appSettings>.
- 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.