配置 .Net Core 日志以记录请求和响应

8

我正在开发一个asp .net core 2.1 WEB-API应用程序。

我使用ILogger并配置如下:

"Logging": {
"LogLevel": {
  "Default": "Debug",
  "System": "Information",
  "Microsoft": "Information"
}

请求时,我看到了日志:

信息:Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] 正在执行动作方法 ActivationService.Controllers.ActivationController.Post (ActivationService),参数为 (ActivationService.Contracts.ActivationRequest) - 验证状态: 有效

已执行动作方法 ActivationService.Controllers.ActivationController.Post (ActivationService),返回结果为 Microsoft.AspNetCore.Mvc.ObjectResult ,用时174605.9201毫秒。

有没有办法配置asp.net以记录响应和请求的正文

1个回答

6

是的,您可以实现日志中间件:

public class RequestResponseLoggingMiddleware
    {
        private readonly RequestDelegate next;
        private readonly ILogger logger;

        public RequestResponseLoggingMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
        {
            this.next = next;
            logger = loggerFactory.CreateLogger<RequestResponseLoggingMiddleware>();
        }

        public async Task Invoke(HttpContext context)
        {
            context.Request.EnableRewind();

            var buffer = new byte[Convert.ToInt32(context.Request.ContentLength)];
            await context.Request.Body.ReadAsync(buffer, 0, buffer.Length);
            var requestBody = Encoding.UTF8.GetString(buffer);
            context.Request.Body.Seek(0, SeekOrigin.Begin);

            logger.LogInformation(requestBody);

            var originalBodyStream = context.Response.Body;

            using (var responseBody = new MemoryStream())
            {
                context.Response.Body = responseBody;

                await next(context);

                context.Response.Body.Seek(0, SeekOrigin.Begin);
                var response = await new StreamReader(context.Response.Body).ReadToEndAsync();
                context.Response.Body.Seek(0, SeekOrigin.Begin);

                logger.LogInformation(response);
                await responseBody.CopyToAsync(originalBodyStream);
            }
        }
    }

然后在 Configure 方法中将其添加到应用程序构建器中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ....
    app.UseMiddleware<RequestResponseLoggingMiddleware>();
}

2
  1. 在你的示例中,我需要将“context.Request.Body = body;”更改为“context.Request.Body.Position = 0;”,否则请求在控制器中为空。
  2. 没问题,我可能会使用它。但是也许有一种方法可以配置标准的ASP记录器来完成这个任务?
- Timur Lemeshko
@TimurLemeshko,不幸的是,没有办法配置记录器来做到这一点。 - Alex Riabov
这不会记录外拨电话。 - JJCV
由于省略了“Content-Length”头,所以无法使用“Transfer-Encoding: chunked”,因此不起作用,因此“context.Request.ContentLength”不可用。“EnableBuffering”扩展是可能的解决方法。https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.httprequestrewindextensions.enablebuffering?view=aspnetcore-3.1 - lorond
2
EnableRewind是来自Internal Asp net命名空间的方法,据我所知,它不能保证在公共环境下正常工作。例如,我会收到一个错误System.TypeLoadException: Could not load type 'Microsoft.AspNetCore.Http.Internal.BufferingHelper' from assembly 'Microsoft.AspNetCore.Http...'。我建议使用具有相同含义的"EnableBuffering()"方法:"确保请求主体可以被多次读取。" - ademchenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接