< Summary - Jellyfin

Information
Class: Jellyfin.Api.Middleware.ResponseTimeMiddleware
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/Middleware/ResponseTimeMiddleware.cs
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 68
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%

File(s)

/srv/git/jellyfin/Jellyfin.Api/Middleware/ResponseTimeMiddleware.cs

#LineLine coverage
 1using System.Diagnostics;
 2using System.Globalization;
 3using System.Threading.Tasks;
 4using MediaBrowser.Common.Extensions;
 5using MediaBrowser.Controller.Configuration;
 6using Microsoft.AspNetCore.Http;
 7using Microsoft.AspNetCore.Http.Extensions;
 8using Microsoft.Extensions.Logging;
 9
 10namespace Jellyfin.Api.Middleware;
 11
 12/// <summary>
 13/// Response time middleware.
 14/// </summary>
 15public class ResponseTimeMiddleware
 16{
 17    private const string ResponseHeaderResponseTime = "X-Response-Time-ms";
 18
 19    private readonly RequestDelegate _next;
 20    private readonly ILogger<ResponseTimeMiddleware> _logger;
 21
 22    /// <summary>
 23    /// Initializes a new instance of the <see cref="ResponseTimeMiddleware"/> class.
 24    /// </summary>
 25    /// <param name="next">Next request delegate.</param>
 26    /// <param name="logger">Instance of the <see cref="ILogger{ExceptionMiddleware}"/> interface.</param>
 27    public ResponseTimeMiddleware(
 28        RequestDelegate next,
 29        ILogger<ResponseTimeMiddleware> logger)
 30    {
 2231        _next = next;
 2232        _logger = logger;
 2233    }
 34
 35    /// <summary>
 36    /// Invoke request.
 37    /// </summary>
 38    /// <param name="context">Request context.</param>
 39    /// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</p
 40    /// <returns>Task.</returns>
 41    public async Task Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
 42    {
 43        var startTimestamp = Stopwatch.GetTimestamp();
 44
 45        var enableWarning = serverConfigurationManager.Configuration.EnableSlowResponseWarning;
 46        var warningThreshold = serverConfigurationManager.Configuration.SlowResponseThresholdMs;
 47        context.Response.OnStarting(() =>
 48        {
 49            var responseTime = Stopwatch.GetElapsedTime(startTimestamp);
 50            var responseTimeMs = responseTime.TotalMilliseconds;
 51            if (enableWarning && responseTimeMs > warningThreshold && _logger.IsEnabled(LogLevel.Debug))
 52            {
 53                _logger.LogDebug(
 54                    "Slow HTTP Response from {Url} to {RemoteIP} in {Elapsed:g} with Status Code {StatusCode}",
 55                    context.Request.GetDisplayUrl(),
 56                    context.GetNormalizedRemoteIP(),
 57                    responseTime,
 58                    context.Response.StatusCode);
 59            }
 60
 61            context.Response.Headers[ResponseHeaderResponseTime] = responseTimeMs.ToString(CultureInfo.InvariantCulture)
 62            return Task.CompletedTask;
 63        });
 64
 65        // Call the next delegate/middleware in the pipeline
 66        await this._next(context).ConfigureAwait(false);
 67    }
 68}