【问题标题】:Logging request body and request headers with NLog使用 NLog 记录请求正文和请求标头
【发布时间】:2018-07-30 11:13:09
【问题描述】:

我正在使用 ASP .Net Core 2.1 WebAPI。是否可以使用 NLog 的配置记录当前的请求体和请求头?

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true">
  <extensions>
    <add prefix="custom" assembly="Pepper" />
  </extensions>
  <variable name="log-header" 
            value="Time: [${date}]${newline}
            Operation: ${aspnet-request-method} ${aspnet-request-url:IncludeHost=true:IncludePort=true:IncludeQueryString=true}${newline}
            Headers:${aspnet-request-headers}${newline}
            Body:${aspnet-request-body}"/>
  <targets>
    <target name="exceptionFile" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
      <target xsi:type="File" 
              encoding="utf-8" 
              fileName="exception_log.txt" 
              archiveAboveSize="10000000" 
              archiveNumbering="Sequence" 
              maxArchiveFiles="10" 
              layout="${log-header}${newline}${message}${newline}${newline}" />
    </target>
  </targets>
  <rules>
    <logger name="*" minlevel="Error" writeTo="exceptionFile" />
  </rules>
</nlog>

【问题讨论】:

  • 我强烈建议不要这样做,因为它是一个主要的安全问题(对性能和资源使用也不利)。如果你真的想调试它,请使用 wireshark 或其他转储流量的工具

标签: asp.net-core nlog asp.net-core-webapi


【解决方案1】:

您可以为此实现自定义中间件:

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

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

    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);

        var builder = new StringBuilder(Environment.NewLine);
        foreach (var header in context.Request.Headers)
        {
            builder.AppendLine($"{header.Key}:{header.Value}");
        }

        builder.AppendLine($"Request body:{requestBody}");

        logger.LogInformation(builder.ToString());

        await next(context);
    }
}

在Startup.cs注册Configure:

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

并更新 Program.cs 以使用 NLog,例如:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
        })
        .UseNLog()  // NLog: setup NLog for Dependency injection
        .Build();

【讨论】:

  • 我花了几个小时想我做错了什么,但我只查看我的“内部”nlog-log,而不是我的应用程序其余部分使用的调试输出文件夹中的日志。
  • 这看起来是一个很好的解决方案,我想了解这个调用什么时候被调用?是你在控制器中使用记录器的时候吗?你能举个例子吗?谢谢@Alex Riabov
【解决方案2】:

NLog 刚刚发布了日志请求正文的功能。

<layout type="SimpleLayout" text="${newline}Request body: ${aspnet-request-posted-body} " />

您可以在

中找到功能

及用法

感谢 Julian 和 NLog 团队 :)

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    相关资源
    最近更新 更多