Nlog: MappedDiagnosticsLogicalContext issues with ASP.NET Core 2.2 InProcess hosting

Created on 11 May 2019  ·  14Comments  ·  Source: NLog/NLog

Hi,

Until recently, we were using NLog with our ASP.NET Core app without issue. We have configured log4jxmlevent using the MappedDiagnosticsLogicalContext. This has always worked for us.

Recently we switched to ASP.NET Core InProcess hosting and suddenly our log4jxmlevent layout renderer is no longer including data that we had initially set on the MappedDiagnosticsLogicalContext, because MappedDiagnosticsLogicalContext for some reason now gets cleared. The same goes for MappedDiagnosticsLogicalContext. More specifically, when we set them and log at startup it’s fine, but once the app is up and running and requests come in on different threads both these dictionaries get cleared.

The only one that doesn’t get cleared is GlobalDiagnosticsContext, however to my knowledge the log4jxmlevent does not attempt to GetNames() from here at any point.

Has anyone got any idea how to solve this problem please as I’ve been banging my head against this for a few days now and cannot find a satisfactory solution?

Thanks.

question

Most helpful comment

@SkinnySackboy NLog 4.6.4 has been released: https://www.nuget.org/packages/NLog/4.6.4

So now you can do the following with a pure NetworkTarget:

<target name="logFaces" xsi:type="Network" address="${var:logFacesUri}">
   <layout xsi:type="Log4JXmlEventLayout" includeMdlc="true" includeCallSite="true">
       <parameter layout="${gdc:item=MyGlobalVar}" name="GlobalParam"/>
   </layout>
</target>

All 14 comments

Hi! Thanks for opening your first issue here! Please make sure to follow the issue template - so we could help you better!

I guess the MappedDiagnosticsLogicalContext is difficult to use for global variables. Because ThreadPool-Threads will not inherit the AsyncLocal-context from the initial main-thread.

If you are using NLogViewer or Chainsaw-target then you can add <parameter>-items:

<target name="log4view" xsi:type="NLogViewer" address="tcp://127.0.0.1:878">
  <parameter layout="${gdc:item=MyGlobalVar}" name="GlobalParam"/>
</target>

We are currently doing this:

<target name="logFaces" xsi:type="Network" address="${var:logFacesUri}" layout="${var:logFacesLayout}" />

Where ${var:logFacesUri} and ${var:logFacesLayout} are set via code, something like this:

global::NLog.LogManager.Configuration.Variables["logFacesUri"] = logFacesUriBuilder.Uri.ToString(); global::NLog.LogManager.Configuration.Variables["logFacesLayout"] = $"${{log4jxmlevent:includeMdlc=true:includeCallSite=true:appInfo={softwareName}}}";

Is the nested parameter technique you described still supported for Log4JXMLEvent Layout Renderer?

Thanks for your quick response!

Is the nested parameter technique you described still supported for Log4JXMLEvent Layout Renderer?

NLogViewer or Chainsaw-target doesn't allow you to modify the layout. So you have to do it like this:

<target name="log4view" xsi:type="NLogViewer" address="${var:logFacesUri}" includeMdlc="true" includeCallSite="true">
  <parameter layout="${gdc:item=MyGlobalVar}" name="GlobalParam"/>
</target>

And stop using logFacesLayout.

Sadly enough then appInfo is not depending on NLog Layout, so it is "difficult" to modify at runtime. But you can do this:

c# NLog.LogManager.Configuration?.AllTargets.OfType<NLogViewer>().ToList().ForEach(t => t.AppInfo = softwareName);

Have created the following pull-requests:

  • #3388 - Log4JXmlEvent - Changed AppInfo to be Layout (For NLog 5.0)
  • #3389 - Log4JXmlEventLayout - Added support for configuration of Parameters (Could be included in a NLog 4.6 release)

I don't know how to thank you enough - it worked and is much cleaner than what I was doing before. Thank you so much!

Happy you found a working solution. When the above PullRequests becomes part of NLog, then the config should become even easier/cleaner.

Thanks again for your help.

@SkinnySackboy NLog 4.6.4 has been released: https://www.nuget.org/packages/NLog/4.6.4

So now you can do the following with a pure NetworkTarget:

<target name="logFaces" xsi:type="Network" address="${var:logFacesUri}">
   <layout xsi:type="Log4JXmlEventLayout" includeMdlc="true" includeCallSite="true">
       <parameter layout="${gdc:item=MyGlobalVar}" name="GlobalParam"/>
   </layout>
</target>

Thank you very much!

@snakefoot I now see the following error:

“Parameter includeCallSite not supported on Log4JXmlEventLayout”

Looks like I need to make another Pull Request to also add support for IncludeCallSite :) NLog 4.6.4 only added support for using Parameters.

Have now created #3442

@SkinnySackboy Maybe this might work while waiting for PR to be merged/released:

<target name="logFaces" xsi:type="Network" address="${var:logFacesUri}">
   <layout xsi:type="Log4JXmlEventLayout" includeMdlc="true">
       <renderer includeCallSite="true" />
       <parameter layout="${gdc:item=MyGlobalVar}" name="GlobalParam"/>
   </layout>
</target>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

geedsen picture geedsen  ·  3Comments

Sam13 picture Sam13  ·  3Comments

FaMouZx3 picture FaMouZx3  ·  3Comments

npandrei picture npandrei  ·  3Comments

BobSeu picture BobSeu  ·  3Comments