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.
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:
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>
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: