2

hi I am trying to use Http target to send the log to an API.

nlog.config:

<targets>
   <target name='HTTP'
        type='HTTP'
        URL='https://localhost:44331/api/logs'
        Method='POST'
        BatchSize='1'
        MaxQueueSize='2147483647'
        IgnoreSslErrors='true'
        FlushBeforeShutdown='true'
        ContentType='application/json'
        Accept='application/json'
        DefaultConnectionLimit='2'
        Expect100Continue='false'
        UseNagleAlgorithm='true'
        ConnectTimeout='30000' 
        InMemoryCompression='true'>
            <layout type='JsonLayout'>
                <attribute name='sourcetype' layout='_json' />
                <attribute name='host' layout='${machinename}' />

                <attribute name='RequestBody' layout='${aspnet-request-posted-body}' />
                <attribute name='event' encode='false'>
                    <layout type='JsonLayout'>
                        <attribute name='level' layout='${level:upperCase=true}' />
                        <attribute name='source' layout='${logger}' />
                        <attribute name='thread' layout='${threadid}' />
                        <attribute name='message' layout='${message}' />
                        <attribute name='utc' layout='${date:universalTime=true:format=yyyy-MM-dd HH\:mm\:ss.fff}' />
                    </layout>
                </attribute>
            </layout>
    </target>

I got every attribute I added except for RequestBody. Also logging to file and database is working fine as well as http it is being called but without the request body data. Any thing I am missing?

Julian
  • 33,915
  • 22
  • 119
  • 174
hussein shaib
  • 108
  • 1
  • 9
  • The same as GitHub ;) without platform (asp.net, asp.net core) and versions of used platforms and NLog components this just guessing. – Julian Apr 19 '20 at 16:11

3 Answers3

2

Probably you're missing the proper setup.

I will list the options:

ASP.NET (non-core)

You need to have the package NLog.Web installed

Then it should work out of the box, but I you have still issues, then force to include NLog.Web like this:

<nlog> 
  <extensions> 
    <add assembly="NLog.Web"/> 
  </extensions> 
  ...

See docs

ASP.NET Core

For ASP.NET Core it depends on the version.

First of all you need the package NLog.Web.AspNetCore installed.

Also add to your config:

<extensions>
   <!--enable NLog.Web for ASP.NET Core-->
   <add assembly="NLog.Web.AspNetCore"/>
</extensions>

And the Setup need to call NLog.Web.AspNetCore. I would recommend to check: Use NLog in ASP.NET Core application

Make sure you have called .AddNLogWeb(); / .UseNLog() (dependent on the ASP.NET Core version)

Still issues?

Still issues? There could be various other reasons and for now that's guessing. The target you used could choke on the length of the value etc.

I would recommend: Test it with a FileTarget or ConsoleTarget and as check the internal log! - that will show a good error message if there is something wrong.

Julian
  • 33,915
  • 22
  • 119
  • 174
1

I faced the same and solution is in few github issues and thanks to Julian.

1.https://github.com/NLog/NLog.Web/issues/548

FilePath=C:\Users\user\myapp\bin\Debug\netcoreapp3.1\nlog.development.config
2020-07-21 11:05:29.1792 Warn Exception in layout renderer. Exception: System.InvalidOperationException: Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
   at Microsoft.AspNetCore.Server.IIS.Core.HttpRequestStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at Microsoft.AspNetCore.Server.IIS.Core.WrappingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.ReadToEnd()
   at NLog.Web.LayoutRenderers.AspNetRequestPostedBody.BodyToString(Stream body)
   at NLog.Web.LayoutRenderers.AspNetRequestPostedBody.DoAppend(StringBuilder builder, LogEventInfo logEvent)
   at NLog.LayoutRenderers.LayoutRenderer.RenderAppendBuilder(LogEventInfo logEvent, StringBuilder builder)
  1. https://github.com/NLog/NLog.Web/pull/549
  2. https://github.com/NLog/NLog.Web/issues/556

Adding below finally fixed the issue.

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

to here and Must be before app.UseEndpoints

public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env)
cdev
  • 5,043
  • 2
  • 33
  • 32
1

NLog.Web.AspNetCore v5.1 changes ${aspnet-request-posted-body} so it requires middleware to work:

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

The middleware will ensure context.Request.EnableBuffering(); is called when necesary, so one doesn't have to call it explictly.

See also: https://github.com/NLog/NLog.Web/wiki/HTTP-Request-Logging

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