using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System.Diagnostics; using TakeoutSaaS.Shared.Abstractions.Diagnostics; namespace TakeoutSaaS.Shared.Web.Middleware; /// /// 基础请求日志(方法、路径、耗时、状态码、TraceId)。 /// public sealed class RequestLoggingMiddleware(RequestDelegate next, ILogger logger) { /// /// 记录请求日志并调用后续中间件。 /// /// HTTP 上下文。 public async Task InvokeAsync(HttpContext context) { // 1. 启动计时 var stopwatch = Stopwatch.StartNew(); try { await next(context); } finally { // 2. 结束计时并输出日志 stopwatch.Stop(); var traceId = TraceContext.TraceId ?? context.TraceIdentifier; var spanId = TraceContext.SpanId ?? Activity.Current?.SpanId.ToString() ?? string.Empty; logger.LogInformation( "HTTP {Method} {Path} => {StatusCode} ({Elapsed} ms) TraceId:{TraceId} SpanId:{SpanId}", context.Request.Method, context.Request.Path, context.Response.StatusCode, stopwatch.Elapsed.TotalMilliseconds, traceId, spanId); } } }