【问题标题】:Configure .net core logging to log request and response配置 .net 核心日志记录以记录请求和响应
【发布时间】:2018-12-20 16:32:50
【问题描述】:

我正在开发 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 in 174605.9201ms。

有没有办法配置 asp.net 以记录响应和请求的跟踪 body

【问题讨论】:

    标签: .net asp.net-web-api logging asp.net-core


    【解决方案1】:

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

    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方法中将其添加到application Builder中:

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

    【讨论】:

    • 1) 在您的示例中,我必须从“context.Request.Body = body;”更改到“context.Request.Body.Position = 0;”,否则控制器 2 中的请求为空)没关系,我可能会使用它。但是可能有一种方法可以配置标准的 asp 记录器来做到这一点?
    • @TimurLemeshko,不幸的是,没有办法配置记录器来做到这一点。
    • 这不会记录拨出电话
    • 不适用于Transfer-Encoding: chunked ,因为Content-Length 标头被省略,所以context.Request.ContentLength 不可用。 EnableBuffering 扩展是可能的解决方法。 docs.microsoft.com/en-us/dotnet/api/…
    • EnableRewind 是来自内部 Asp 网络命名空间的方法,AFAIU 不能保证它会公开工作。例如,我收到错误 System.TypeLoadException: Could not load type 'Microsoft.AspNetCore.Http.Internal.BufferingHelper' from assembly 'Microsoft.AspNetCore.Http ...' 我建议使用具有同义:“确保请求正文可以被多次读取。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多