SlowCheetah not transforming root XML element with multiple attributes - slowcheetah

I'm trying to add a SlowCheetah release transformation for my NLog.config file. The NLog.Release.config looks as follows:
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="true"
internalLogLevel="Off"
internalLogFile="c:\temp\nlog-internal.log"
xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"
xdt:Transform="Replace">
<extensions>
<!--<add assembly="NLog.Targets.RabbitMQ" />-->
</extensions>
<targets async="true">
<!--<target xsi:type="Console" name="console" error="false" layout="${time:format=HH:mm:ss} ${logger}: ${message} ${exception:format=ToString}"/>-->
</targets>
<rules>
<!--<logger name="*" minlevel="Trace" writeTo="console"/>-->
</rules>
</nlog>
Here, I'm trying to replace the whole contents of the file using xdt:Transform="Replace" on the root element. However, I'm getting the following error on build with Visual Studio 2015:
C:\Projects\WebSite\Properties\SlowCheetah\SlowCheetah.Transforms.targets(184,5):
error : Could not write Destination file: Object reference not set to
an instance of an object.
I did a few experiments, and found out that this error goes away if I remove all the attributes from the root nlog element (autoReload, throwExceptions, etc). But I need to replace the whole file, including all those attributes.
Why can't SlowCheetah perform this transformation? How can I make it transform the whole file, including all the attributes on the root element?

Related

Configuration NLog.config file for using on Azure portal

I've applied ASP.NET core 3.1 in my web application and I've used NLog for logging.
In local host I set the internalLogFile and fileName like this
internalLogFile="E:\Archives\Projects\Alpha\Alpha.Web.App\internal_logs\internallog.txt"
fileName="E:/Archives/Projects/Alpha/Alpha.Web.App/logs/${shortdate}_logfile.txt"
in nlog.config file. How can I set the paths for using in Azure?
<?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="Trace"
internalLogFile="E:\Archives\Projects\Alpha\Alpha.Web.App\internal_logs\internallog.txt">
<targets>
<target name="logfile" xsi:type="File"
fileName="E:/Archives/Projects/Alpha/Alpha.Web.App/logs/${shortdate}_logfile.txt"
layout="${longdate} ${level:uppercase=true} ${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
nlog.config file is in this path:
https://{appname}.scm.azurewebsites.net/dev/wwwroot/nlog.config
I have used ${basedir} and changed values of internalLogFile and fileName to
internalLogFile="${basedir}/internal_logs/internallog.txt">
and
fileName="${basedir}/logs/${shortdate}_logfile.txt"
Now I access to these files in bin folder in my project.

Can layout render(s) be used for FileName(s)?

Can layout render(s) (processname to be exact) be used for FileName(s)?
Note,
the internalLogFile (and INTERNAL.log value)
and
fileName="${processname}.NLog.${shortdate}.PeanutButter.log"
values below.
<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile="${processname}.NLog.INTERNAL.log"
internalLogLevel="Trace" >
<!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File" name="target1" fileName="${processname}.NLog.${shortdate}.PeanutButter.log"
layout="${date}|${level:uppercase=true}|${logger}|${environment-user:userName=true:domain=true}|****|${message} ${exception:format=toString,Data}|${all-event-properties}" />
<target xsi:type="Console" name="target2"
layout="${date}|${level:uppercase=true}|${logger}|${message} ${exception:format=toString,Data}|${all-event-properties}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="*" minlevel="Trace" writeTo="target1,target2" />
</rules>
</nlog>
With the above, I'm getting a file created:
${processname}.NLog.INTERNAL.log
(literally, that is the filename)
and no files at all named:
*PeanutButter.log
where * is a wild card search.
Imported packages below.
<ItemGroup>
<PackageReference Include="NLog" Version="4.6.8" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.1" />
</ItemGroup>
Can layout render(s) (processname to be exact) be used for FileName(s)?
Filetarget
Yes, it's fully supported for the file target.
See this simple example from the Filetarget docs:
Per-level log files
Single File target can be used to write to multiple files at once.
The following configuration will cause log entries for each log level
to be written to a separate file, so you will get:
Trace.log
Debug.log
Info.log
Warn.log
Error.log
Fatal.log
<target name="file" xsi:type="File"
layout="${longdate} ${logger} ${message}${exception:format=ToString}"
fileName="${basedir}/${level}.log" />
Internal logger
${processname}.NLog.INTERNAL.log
(literally, that is the filename)
It's not supported for the internal logger filename!
From the Internalloger docs
internalLogFile
Note: only a few layouts are supported, as the internal log needs to be as stable as possible.
NLog 4.6+: Supported renderers (without options): ${currentdir}, ${basedir}, ${tempdir}
NLog 4.6+: Environment Variables are also supported: e.g. %appdata%
If the internal logger would fail because of (complicated) layout renderers, where should it log that then? ;)

I dont want nlog to create log file for every millisec

Im using the following config . This creates log file for every milli sec.
I want only one log file per execution and it should be time stamped
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="logfile" xsi:type="File" fileName="C:\log\log- ${date:format=dd/MM/yyyy HH\:mm\:ss}.txt"></target>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
The only way to do this is to set the fileName programmatically.
E.g.
var logfileTarget = NLog.LogManager.Configuration.FindTargetByName<FileTarget>("logfile");
logfileTarget.FileName = "filename_with_date_and_ext"; //you can use layout renderers here.
See API docs
Have submitted a PR for the processinfo-layout-renderer, so it can output process-start-time in the wanted format. But it only supports local-time
fileName="C:\log\log-${processinfo:property=StartTime:format=yyyy-MM-dd_HHmmss}.log"

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.

Configuring NLog E-Mail Message Body Output

I am using NLog v2 Beta to log a VB.NET .DLL which creates and sends messages to a third party service. I have it working perfectly when logging to a file, but now want it to also e-mail me the errors it catches automatically. The following is the relevant bit of my NLog.config file:
<?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">
<targets>
<target name="papercut" xsi:type="BufferingWrapper" bufferSize="100">
<target xsi:type="PostFilteringWrapper" defaultFilter="level >= LogLevel.Debug">
<target xsi:type="Mail"
name="papercut"
subject="Your app has errors"
to="ToAddress#Domain.com"
from="FromAddress#Domain.com"
smtpServer="127.0.0.1"
smtpPort="25"
body={longdate}|{message} />
</target>
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="papercut" />
</rules>
</nlog>
By default it will just list the logged message in the e-mail body. I want to preceed this with the date / time logged, so have been playing around with the body= part to no avail (it either doesn't evaluate the variables properly or crashes NLog). Can somebody please give me a pointer as to how to configure NLog to do this?
seems like you are missing $ in the body configuration and that might be the reason that NLog is crashing..
body = "${longdate}| ${message}"
more info regarding Mail target
https://github.com/NLog/NLog/wiki/Mail-target
also you can enable logging for NLog errors itself as below..
<nlog
xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwExceptions="true"
internalLogFile="Nloglog.log"
internalLogLevel="Warn"
>
.....
</nlog>

Resources