0

Trying to log all API calls for an ASP.NET Web API 2 project. Created a DelegatingHandler and not able to get the aspnet-request-posted-body layout render to work.

Type: Bug (or maybe I'm missing something?)

NLog version: 5.0.1

NLog.Web version: 5.1.0

NLog.Extensions.Logging version: (not installed)

Platform: .Net 4.7.2 (working with a ASP.Net Web API 2)

Current NLog config (xml or C#, if relevant)

  <nlog autoReload="True"
        throwConfigExceptions="False"
        internalLogLevel="Trace"
        internalLogFile="${basedir}App_Data\Logs\internal-nlog.txt"
        xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <variable name="logDirectory" value="App_Data/Logs"/>
    <!-- enable ASP.NET layout renderers -->
    <extensions>
      <add assembly="NLog.Web"/>
    </extensions>
    <targets async="true">
      <target name="mainfile"
              xsi:type="File"
              fileName="${logDirectory}/main-${shortdate}.txt"
              layout="${longdate}|${aspnet-request-posted-body}" />
    </targets>
    <logger name="*" minlevel="Trace" writeTo="mainfile" />
  </nlog>
  • What is the current result?
  2022-07-27 17:19:21.5446|
  • What is the expected result?
  2022-07-27 17:19:21.5446|{"username":"xyz","password":"xyz"}
  • Did you checked the Internal log? Yes, the Internal Log had 0 (zero) errors
  • Please post full exception details (message, stacktrace, inner exceptions) None
  • Are there any workarounds? Not sure
  • Is there a version in which it did work? Have not tried
  • Can you help us by writing an unit test? Not sure how for this

Code:

using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Web.Api.Handlers {
    public class LogFilter : DelegatingHandler {
        private readonly NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
            if (request?.Content != null) {
                // Do stuff
            }

            var response = await base.SendAsync(request, cancellationToken);

            if (response?.Content != null) {
                // Do stuff
            }
            
            _logger.Info("test");
            
            return response;
        }
    }
}
RoLYroLLs
  • 3,113
  • 4
  • 38
  • 57

1 Answers1

1

There is a breaking change in NLog.Web v5 where ${aspnet-request-posted-body} was removed (because the implementation was not threadsafe).

Then with NLog.Web.AspNetCore v5.1 it was restored, but required that one replaced:

app.Use(async (context, next) => {
   context.Request.EnableBuffering();
   await next();
});

With (If using ASP.NET Core):

app.UseMiddleware<NLog.Web.NLogRequestPostedBodyMiddleware>();

Of if using ASP.NET MVC v4, then register HTTP module NLog.Web.NLogRequestPostedBodyModule.

Rolf Kristensen
  • 17,785
  • 1
  • 51
  • 70