50 lines
1.8 KiB
C#
50 lines
1.8 KiB
C#
using System.Diagnostics;
|
|
using Jiaowu.Api.Infrastructure.Observability;
|
|
|
|
namespace Jiaowu.Api.Infrastructure.Middleware;
|
|
|
|
public sealed class SlowRequestLoggingMiddleware(
|
|
RequestDelegate next,
|
|
ObservabilityOptions options,
|
|
ILogger<SlowRequestLoggingMiddleware> logger)
|
|
{
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
if (!options.Enabled ||
|
|
!context.Request.Path.StartsWithSegments("/api"))
|
|
{
|
|
await next(context);
|
|
return;
|
|
}
|
|
|
|
var startedAt = Stopwatch.GetTimestamp();
|
|
await next(context);
|
|
|
|
var durationMilliseconds = Stopwatch.GetElapsedTime(startedAt).TotalMilliseconds;
|
|
var endpoint = context.GetEndpoint()?.DisplayName ?? context.Request.Path.Value ?? "/api";
|
|
if (durationMilliseconds >= options.SlowRequestThresholdMilliseconds ||
|
|
context.Response.StatusCode >= StatusCodes.Status500InternalServerError)
|
|
{
|
|
logger.LogWarning(
|
|
"Slow API request completed: {Method} {Path} ({Endpoint}) returned {StatusCode} in {DurationMs:F1} ms, request {RequestId}.",
|
|
context.Request.Method,
|
|
context.Request.Path.Value,
|
|
endpoint,
|
|
context.Response.StatusCode,
|
|
durationMilliseconds,
|
|
context.TraceIdentifier);
|
|
}
|
|
else if (options.LogAllApiRequests)
|
|
{
|
|
logger.LogInformation(
|
|
"API request completed: {Method} {Path} ({Endpoint}) returned {StatusCode} in {DurationMs:F1} ms, request {RequestId}.",
|
|
context.Request.Method,
|
|
context.Request.Path.Value,
|
|
endpoint,
|
|
context.Response.StatusCode,
|
|
durationMilliseconds,
|
|
context.TraceIdentifier);
|
|
}
|
|
}
|
|
}
|