diff options
| author | Dominik <git@secnd.me> | 2023-06-15 19:38:42 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-15 19:38:42 +0200 |
| commit | 17f1e8d19b1fd693893d66d2275ed8ae2476344e (patch) | |
| tree | 7f48be975faa92042769870957587b3c7864f631 /Jellyfin.Api/Middleware/ResponseTimeMiddleware.cs | |
| parent | e8ae7e5c38e28f13fa8de295e26c930cb46d9b79 (diff) | |
| parent | 6771b5cabe96b4b3cbd1cd0c998d564f3dd17ed4 (diff) | |
Merge branch 'master' into segment-deletion
Diffstat (limited to 'Jellyfin.Api/Middleware/ResponseTimeMiddleware.cs')
| -rw-r--r-- | Jellyfin.Api/Middleware/ResponseTimeMiddleware.cs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/Jellyfin.Api/Middleware/ResponseTimeMiddleware.cs b/Jellyfin.Api/Middleware/ResponseTimeMiddleware.cs new file mode 100644 index 000000000..db3917743 --- /dev/null +++ b/Jellyfin.Api/Middleware/ResponseTimeMiddleware.cs @@ -0,0 +1,68 @@ +using System.Diagnostics; +using System.Globalization; +using System.Threading.Tasks; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Configuration; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Api.Middleware; + +/// <summary> +/// Response time middleware. +/// </summary> +public class ResponseTimeMiddleware +{ + private const string ResponseHeaderResponseTime = "X-Response-Time-ms"; + + private readonly RequestDelegate _next; + private readonly ILogger<ResponseTimeMiddleware> _logger; + + /// <summary> + /// Initializes a new instance of the <see cref="ResponseTimeMiddleware"/> class. + /// </summary> + /// <param name="next">Next request delegate.</param> + /// <param name="logger">Instance of the <see cref="ILogger{ExceptionMiddleware}"/> interface.</param> + public ResponseTimeMiddleware( + RequestDelegate next, + ILogger<ResponseTimeMiddleware> logger) + { + _next = next; + _logger = logger; + } + + /// <summary> + /// Invoke request. + /// </summary> + /// <param name="context">Request context.</param> + /// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param> + /// <returns>Task.</returns> + public async Task Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager) + { + var startTimestamp = Stopwatch.GetTimestamp(); + + var enableWarning = serverConfigurationManager.Configuration.EnableSlowResponseWarning; + var warningThreshold = serverConfigurationManager.Configuration.SlowResponseThresholdMs; + context.Response.OnStarting(() => + { + var responseTime = Stopwatch.GetElapsedTime(startTimestamp); + var responseTimeMs = responseTime.TotalMilliseconds; + if (enableWarning && responseTimeMs > warningThreshold && _logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug( + "Slow HTTP Response from {Url} to {RemoteIp} in {Elapsed:g} with Status Code {StatusCode}", + context.Request.GetDisplayUrl(), + context.GetNormalizedRemoteIp(), + responseTime, + context.Response.StatusCode); + } + + context.Response.Headers[ResponseHeaderResponseTime] = responseTimeMs.ToString(CultureInfo.InvariantCulture); + return Task.CompletedTask; + }); + + // Call the next delegate/middleware in the pipeline + await this._next(context).ConfigureAwait(false); + } +} |
