Skip to content

HTTP Request Logging

Rolf Kristensen edited this page Oct 8, 2022 · 21 revisions

⚠️ HTTP Logging can potentially log personally identifiable information (PII). Consider the risk and avoid logging sensitive information.

Contents

UseHttpLogging introduced with NET6

.NET 6 includes a middleware implementation that captures HTTP request context as LogEvent Properties.

The logger category-name become Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpLogging();

}

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpLogging(logging =>
    {
        // Customize HTTP logging here.
        logging.LoggingFields = HttpLoggingFields.All;
        logging.RequestHeaders.Add("My-Request-Header");
        logging.ResponseHeaders.Add("My-Response-Header");
        logging.MediaTypeOptions.AddText("application/javascript");
        logging.RequestBodyLogLimit = 4096;
        logging.ResponseBodyLogLimit = 4096;
    });
}

This can be combined with NLog JsonLayout to output the HTTP-request/response in structured format:

<nlog>
     <targets>
         <target type="file" name="http-file" filename="HttpRequests-JSON.log">
             <layout type="JsonLayout" includeEventProperties="true" includeScopeProperties="true" excludeProperties="${originalformat}" />
         </target>
     </target>
     <rules>
         <rule logger="Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware" minLevel="Trace" writeTo="http-file" />
     </rules>
</nlog>

Notice the Microsoft HttpLoggingMiddleware outputs both a request-LogEvent and response-LogEvent for each HttpRequest.

See also: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-logging/?view=aspnetcore-6.0

UseW3CLogging introduced with NET6

.NET 6 includes a middleware implementation that captures HTTP request context and writes to LogFile in W3C Extended Log Format.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseW3CLogging();

}

public void ConfigureServices(IServiceCollection services)
{
    services.AddW3CLogging(logging =>
    {
       // Log all W3C fields
       logging.LoggingFields = W3CLoggingFields.All;
       logging.FileSizeLimit = 5 * 1024 * 1024;
       logging.RetainedFileCountLimit = 2;
       logging.FileName = "MyLogFile";
       logging.LogDirectory = @"C:\logs";
       logging.FlushInterval = TimeSpan.FromSeconds(2);
    });
}

See also: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/w3c-logger/?view=aspnetcore-6.0

Request Logging Middleware introduced with NLog5

Install NLog.Web.AspNetCore nuget-package and activate the middleware like this (Startup.cs):

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
   app.UseMiddleware<NLog.Web.NLogRequestLoggingMiddleware>();
}

Configure W3C Log-File with W3CExtendedLogLayout like this in NLog.config:

<nlog throwConfigExceptions="true">
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>
  <targets>
    <target type="file" name="w3c-file" filename="HttpRequests-W3C.log">
         <layout type="W3CExtendedLogLayout"/>
    </target>
  </targets>
  <rules>
     <logger name="NLogRequestLogging" minLevel="Debug" writeTo="w3c-file" final="true" />
  </rules>
</nlog>

Configure JSON Log-File with JsonLayout like this in NLog.config:

<nlog throwConfigExceptions="true">
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>
  <targets>
    <target type="file" name="http-file" filename="HttpRequests-JSON.log">
        <layout xsi:type="JsonLayout" includeAllProperties="true" maxRecursionLimit="1">
          <attribute name="timestamp" layout="${date:format=o}" />
          <attribute name="loglevel" layout="${level}" />
          <attribute name="url" layout="${aspnet-request-url}" />
          <attribute name="exception" layout="${exception:format=tostring}" />
        </layout>
    </target>
  </targets>
  <rules>
     <logger name="NLogRequestLogging" minLevel="Debug" writeTo="http-file" final="true" />
  </rules>
</nlog>

Note to include the HTTP Posted Body, then one can use ${aspnet-request-posted-body} together with NLogRequestPostedBodyMiddleware.

Request Logging HttpModule introduced with NLog5

Install NLog.Web nuget-package for classic ASP.NET and activate like this (Global.asax)

  public class MyGlobalApplication : System.Web.HttpApplication
  {
     public static IHttpModule NLogRequestLogging = new NLog.Web.NLogRequestLoggingModule();

     public override void Init()
     {
         base.Init();
         NLogRequestLogging.Init(this);
     }
  }

Alternative can implement HTTP-request-logging using Action Filters.

Configure W3C Log-File with W3CExtendedLogLayout like this in NLog.config:

<nlog throwConfigExceptions="true">
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>
  <targets>
    <target type="file" name="w3c-file" filename="HttpRequests-W3C.log">
         <layout type="W3CExtendedLogLayout"/>
    </target>
  </targets>
  <rules>
     <logger name="NLogRequestLogging" minLevel="Debug" writeTo="w3c-file" final="true" />
  </rules>
</nlog>

Configure JSON Log-File with JsonLayout like this in NLog.config:

<nlog throwConfigExceptions="true">
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>
  <targets>
    <target type="file" name="http-file" filename="HttpRequests-JSON.log">
        <layout xsi:type="JsonLayout" includeAllProperties="true" maxRecursionLimit="1">
          <attribute name="timestamp" layout="${date:format=o}" />
          <attribute name="loglevel" layout="${level}" />
          <attribute name="url" layout="${aspnet-request-url}" />
          <attribute name="exception" layout="${exception:format=tostring}" />
        </layout>
    </target>
  </targets>
  <rules>
     <logger name="NLogRequestLogging" minLevel="Debug" writeTo="http-file" final="true" />
  </rules>
</nlog>

Note to include the HTTP Posted Body, then one can use ${aspnet-request-posted-body} together with NLogRequestPostedBodyModule.