Transform that preserve namespace prefixes - visual-studio-2012

I'm trying to insert an NLog custom config section into my Web.config using this XDT section:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" throwExceptions="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xdt:Transform="InsertIfMissing" >
<targets>
<target xsi:type="File" name="logfile" fileName="H:\testLog.txt" layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>
When I run the XDT transform, my Web.Debug.config contains:
<nlog throwExceptions="true" xmlns="http://www.nlog-project.org/schemas/NLog.xsd">
<targets>
<target d4p1:type="File" name="logfile" fileName="H:\testLog.txt" layout="${longdate} ${uppercase:${level}} ${message}" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>
Typically, a namespace prefix is arbitrary, so transforming xsi to d4p1 would cause no issues.
However, I get a runtime exception in my application from NLog when I use d4p1. Manually changing the instances of d4p1 to xsi fixes the issue, but it subverts the utility of config transformation for me if the user needs to manually alter the file afterward.
Is there a way to preserve namespace prefixes using XDT?

We had exactly the same issue. I'm not sure why it suddenly started happening with a particular project, but the solution for us was to add the xsi namespace to the top level of the original configuration file (ie the base file the transformations work on). So...
<configuration>
... would become...
<configuration xmlns:xsi="http://www.nlog-project.org/schemas/NLog.xsd">
This did the trick.
An alternative approach that also worked was to apply the transforms on child elements of the nlog element.
Hope that helps someone.

I started to see this problem when I moved my xdt:Transform attribute from the target and rule tags to nlog. Moving them back to the original tags like this solved it:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" throwExceptions="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets xdt:Transform="InsertIfMissing">
<target xsi:type="File" name="logfile" fileName="H:\testLog.txt" layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules xdt:Transform="InsertIfMissing">
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>

Related

NLog - create log file at specific directory in linux

I've a .net core application on linux server.also in application i used nlog for logging. my application path on linux is /var/www-ninja/html/finance.api.gurukul.ninja. but with use of nlog i want to store logs in other linux directory. which is like /var/log/api/ninja/finance. so can I store logs in that directory. how can i do that ? for more details
nlog.production.config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Info"
internalLogFile="c:\temp\internal-nlog.txt">
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
<add assembly="NLog.Extensions.Logging"/>
<add assembly="NLog"/>
</extensions>
<variable name="ExceptionLayout" value="${longdate} [${processid}] ${uppercase:${level}} ${logger:shortName=true} ${environment-user} ${local-ip} ${aspnet-request-url} ${aspnet-request-method} ${message}${exception:format=tostring,Stacktrace}"/>
<variable name="CommonLayout" value="${longdate} [${processid}] ${uppercase:${level}} ${logger:shortName=true} ${environment-user} ${local-ip} ${message} "/>
<variable name ="logDir" value="/var/log/api/ninja/finance" />
<targets async="true">
<target xsi:type="File" name="file" layout="${CommonLayout}" fileName="${logDir}\log-${shortdate}.log" />
<target name="fileAsException"
xsi:type="FilteringWrapper"
condition="length('${exception}')>0">
<target xsi:type="File"
fileName="${logDir}\log-${shortdate}.log"
layout="${ExceptionLayout}" />
</target>
</targets>
<rules>
<logger name="*" writeTo="file,fileAsException"/>
<logger name="Microsoft.*" maxlevel="Info" final="true" />
</rules>
</nlog>
Make sure to use Unix-path, so stop using backslash \
Ex. instead of ${logDir}\log-${shortdate}.log then it should be ${logDir}/log-${shortdate}.log.
If still having issues then try to activate the NLog InternalLogger and check the output https://github.com/NLog/NLog/wiki/Internal-Logging

Log in a file only if the database fails?

I have a scenario where I want to log in a file only if the database fails for some reason.
Is it possible to achieve that using NLog ?
Yes, you could use the FallbackGroup target for that. In the fallback group you should configure the database and file target.
e.g.
<target xsi:type="FallbackGroup" name="all" returnToFirstOnSuccess="true">
<target name="target1" xsi:type="Database" ... />
<target name="target2" xsi:type="File" ... />
</target>
<rules>
<logger name="*" minlevel="Trace" writeTo="all" />
</rules>
See https://github.com/NLog/NLog/wiki/FallbackGroup-target

NLog config rule not taking affect

I have the following nlog.config file for my project. When I debug locally, it works as expected, that Hangfire messages are being filtered to only show Warn and above. However on our staging server (IIS 8.5) nlog seems to ignore the rule and just logs everything (including Info) to elmah:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<add assembly="NLog.Elmah"/>
</extensions>
<targets>
<target xsi:type="Elmah" name="elmahWithLogLevelAsType" layout="${message}" LogLevelAsType="true"/>
</targets>
<rules>
<logger name="Hangfire.*" minlevel="Warn" writeTo="elmahWithLogLevelAsType" final="true" />
<logger name="*" minlevel="Info" writeTo="elmahWithLogLevelAsType" />
</rules>
</nlog>
Even if I remove the Hangfire.* rule and change the catchall to minlevel="Warn" it still logs Info items.
Think you are running two different versions of NLog.
This will capture all log-events with warning (and above levels):
<logger name="Hangfire.*" minlevel="Warn" writeTo="elmahWithLogLevelAsType" final="true" />
This means all log-events with info or below will try the next rule:
<logger name="*" minlevel="Info" writeTo="elmahWithLogLevelAsType" />
Try this configuration instead:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<add assembly="NLog.Elmah"/>
</extensions>
<targets>
<target xsi:type="Elmah" name="elmahWithLogLevelAsType" layout="${message}" LogLevelAsType="true"/>
</targets>
<rules>
<logger name="Hangfire.*" minlevel="Warn" writeTo="elmahWithLogLevelAsType" final="true" />
<logger name="Hangfire.*" maxLevel="Warn" final="true" /> <!-- BlackHole -->
<logger name="*" minlevel="Info" writeTo="elmahWithLogLevelAsType" />
</rules>
</nlog>

NLog: Does the FormControl target really exist?

According to the documentation, NLog offers a FormControl target that will write log messages into the Text property of a control on a Windows Form. However, when I add a FormControl target to my configuration, I get an exception telling me that no target exists named "FormControl". I did download the NLog.Windows.Forms package and include a reference to the DLL in my project.
Here's the configuration:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
throwExceptions="true">
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<!--
<target xsi:type="File" name="FileTarget" fileName="${basedir}/NLogger_4_1_2.log"
layout="${date} ${uppercase:${level}} ${message}" />
-->
<target name="AsyncTarget" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target xsi:type="File" name="FileTarget1" fileName="${basedir}/NLogger_4_1_2.log"
layout="${date} ${uppercase:${level}} ${message}" />
</target>
<target xsi:type="File" name="ReportTarget" fileName="${basedir}/NLogger_4_1_2_report.log"
layout="${date} ${uppercase:${level}} ${message}" />
<target xsi:type="FormControl"
name="FormControlTarget"
layout="${message}"
append="true"
controlName="TextBox1"
formName="Form1" />
</targets>
<rules>
<logger name="FileLogger" minlevel="Trace"
writeTo="AsyncTarget" />
<logger name="ReportLogger" minlevel="Trace"
writeTo="ReportTarget" />
<logger name="FormLogger" minlevel="Trace"
writeTo="FormControlTarget" />
</rules>
</nlog>
I found this question in 2022 trying to get this working in VS2022. The answer is you need the NLog.Windows.Forms NuGet package installed.
And it is recommended to update NLog.config to include NLog.Windows.Forms-assembly in <extensions>:
<?xml version="1.0" encoding="utf-8" ?>
<nlog>
<extensions>
<add assembly="NLog.Windows.Forms"/>
</extensions>
...
</nlog>

NLog Not Writing

I have added NLog to my project and in the development environment, it works fine.
I created a Setup file to deploy my application. The NLog.config file did not show up as a dependency in the Setup project. So, I added it as a file and it is present in the same directory as the exe file and App.config when deployed.
It does not do any logging. I don't know why. Here is the config file:
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variable name="day" value="${date:format=dd}" />
<variable name="month" value="${date:format=MM}" />
<variable name="year" value="${date:format=yyyy}" />
<variable name="verbose" value="${longdate} | ${level} | ${message} | ${exception:format=tostring,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}" />
<targets>
<target name="logfile" xsi:type="File" fileName="${basedir}/Logs/${year}${month}${day}.log" layout="${verbose}" />
</targets>
<rules>
<logger name="*" minlevel="Error" writeTo="logfile" />
</rules>
</nlog>
Any help would be great. Cheers!
Does NLog.config have the property "Copy to Output Directory" set as "Copy always"? https://stackoverflow.com/a/8881521/438760
Put your NLog configuration within the yourapp.exe.config file. Like so:
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog>
<variable name="day" value="${date:format=dd}" />
...
<targets>
<target name="logfile" xsi:type="File" .../>
</targets>
<rules>
<logger name="*" minlevel="Error" writeTo="logfile" />
</rules>
</nlog>
</configuration>
I'm guessing the double xml version statements (line 1 and 2) was a copy / paste issue....
Probably a dumb question, but you have the minLevel set to Error. Are you actually encountering errors that would be logged, or have you tried lowering this to info or debug?
For me, the reason my NLog stopped logging was different to the above suggestions.
During updating the packages, something must have automatically added an nlog section to the bottom of my Web.config. It may have been ApplicationInsights. Obviously this took preference and, this caused it to stop checking my Nlog.config file.
Once I removed the section from my web.config it started magically reading from my nlog.config file again. I took care to take the extentions, targets and rules from web.config and ensure they were placed neatly in my nlog.config file instead.

Resources