How to prevent variable substitution in a SharpDevelop project template - sharpdevelop

I am authoring a project template for SharpDevelop 4.1 and one of the files in this template is an XML config file which contains NLog configuration. The problem is that NLog layouts and variable substitution for the SharpDevelop template itself use the same syntax. Namely the ${time} in the layout is the problem:
<target xsi:type="File" name="file" layout="${time} ${level} ${logger} ${message}" fileName="${ProjectName}.log" />
It is intended to be output into the resulting file as is, however, the SharpDevelop template expansion is replacing it with the time the template is expanded:
<target xsi:type="File" name="file" layout="10:37 AM ${level} ${logger} ${message}" fileName="TestProject.log" />
I still need the ${ProjectName} substitution. How can I prevent or work-around the ${time} substitution?

After looking through SharpDevelop's source code in the StringParser class, it appears there is no escape mechanism for tags.
But I can work around it by modifying the NLog layout renderer so it no longer matches the SharpDevelop tag but still has the same effect in NLog:
<target xsi:type="File" name="file" layout="${time:universalTime=False} ${level} ${logger} ${message}" fileName="${ProjectName}.log" />

Related

Keep last 7 days in nlog

I want to keep last 7 days of files using nlog, but for some reason the following configuration in target=LogToShare is keeping only the latest 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">
<variable name="WorkflowLoggingDirectory" value="${specialfolder:folder=LocalApplicationData}/Logs" />
<variable name="LogSharedFolder" value="\\myserver\logs" />
<rules>
<logger name="WorkflowLogging" writeTo="LogToShare" />
<logger name="WorkflowLogging" writeTo="WorkflowLogFiles" final="true" />
<logger minLevel="Info" writeTo="EventLog" />
</rules>
<targets>
<target type="File"
name="LogToShare"
layout="${time} ${level} ${message}"
fileName="${LogSharedFolder}\${machinename}_${shortdate}.log"
archiveFileName="${LogSharedFolder}\${machinename}_${shortdate}.{#}.log"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="7"
keepFileOpen="true"
openFileCacheTimeout="5"
concurrentWrites="true"
encoding="utf-8"
writeBom="true" />
<target type="File" name="WorkflowLogFiles" fileName="${WorkflowLoggingDirectory}/${shortdate}_Execution.log" layout="${time} ${level} ${message}" keepFileOpen="true" openFileCacheTimeout="5" concurrentWrites="true" encoding="utf-8" writeBom="true" />
<target type="EventLog" name="EventLog" layout="${processname} ${assembly-version} ${newline}${message}" source="UiPath" log="Application" />
</targets>
</nlog>
The files in \\myserver\logs that are kept are only the files from the current day:
machine1_2020-08-09.log
machine2_2020-08-09.log
machine3_2020-08-09.log
machine4_2020-08-09.log
Tomorrow, the files that I will get are:
machine1_2020-08-10.log
machine2_2020-08-10.log
machine3_2020-08-10.log
machine4_2020-08-10.log
And the files from 2020-08-09 will be removed.
I'm using NLog v4.3.9. How can I keep the last 7 days of log?
When using NLog 4.5 (or newer) then you can do this:
<target type="File"
name="LogToShare"
layout="${time} ${level} ${message}"
fileName="${LogSharedFolder}/${machinename}_${shortdate}.log"
maxArchiveFiles="7"
keepFileOpen="true"
openFileCacheTimeout="5"
concurrentWrites="true"
encoding="utf-8"
writeBom="true" />
When using older NLog versions, then you can try this:
<target type="File"
name="LogToShare"
layout="${time} ${level} ${message}"
fileName="${LogSharedFolder}/${machinename}_${date:format=yyyy-MM-dd}.log"
archiveFileName="${LogSharedFolder}/${machinename}_{#}.log"
archiveDateFormat="yyyy-MM-dd"
archiveNumbering="Date"
archiveEvery="Year"
maxArchiveFiles="7"
keepFileOpen="true"
openFileCacheTimeout="5"
concurrentWrites="true"
encoding="utf-8"
writeBom="true" />
Explanation of why the extra parameters are needed:
archiveFileName - Using {#} allows the archive cleanup to generate proper file wildcard.
archiveDateFormat - Must match the ${date:format=} of the fileName (So remember to correct both date-formats, if change is needed)
archiveNumbering=Date - Configures the archive cleanup to support parsing of filenames as dates.
archiveEvery=Year - Activates the archive cleanup, but also the archive file operation. Because the configured fileName automatically ensures the archive file operation, then we don't want any additional archive operations (Ex. avoiding generating extra empty files at midnight).
maxArchiveFiles - How many archive files to keep around.

NLog - Daily Log file - how to add a summary when it's triggered or new log file is created

I have the config setup for daily logging. (I assume the following is correct). How can add a 'summary' when the new log file is created. I'd like to add a daily 'count' to the last line in the log file for the day. Is this possible? How do I know when the new log is triggered?
<variable name="logDirectory" value="C:/Logs/" />
<targets async="true">
<target xsi:type="File"
name="ErrorLog"
filename="${logDirectory}PDF.log"
archiveFileName="log.{#}.log"
archiveNumbering="Date"
archiveEvery="Day"
archiveDateFormat="yyyyMMdd" />
NLog FileTarget has support for Footer-layout and Header-Layout.
If you need special statistics then you probably need to write your owned custom layout-renderer.
<nlog>
<targets>
<target name="ErrorLog" xsi:type="File"
header="----------------- Logging started on ${longdate} ------------------"
footer="----------------- Logging finished on ${longdate} -----------------"
filename="${logDirectory}PDF.log"
archiveFileName="log.{#}.log"
archiveNumbering="Date"
archiveEvery="Day"
archiveDateFormat="yyyyMMdd" />
</targets>
<rules>
<logger name="*" minlevel="Error" writeTo="ErrorLog" />
</rules>
</nlog>

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? ;)

NLog - Having Performance issues and logs are always writing to one file rather than multiple file

I have my nlog confiiguration as below
<?xml version="1.0" encoding="UTF-8"?>
<nlog throwExceptions="true">
<targets>
<target name="file" type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target type="BufferingWrapper" name="file" bufferSize="120">
<target type="File" fileName="${basedir}/logs/MyApplicationLog.log" layout="${longdate} ${exception:format=tostring} ${message} ${newline}" archiveFileName="${basedir}/archives/MyApplicationLogArchive/MyApplicationLog_{##}.log" archiveEvery="Day" archiveNumbering="Rolling" maxArchiveFiles="7" keepFileOpen="true" openFileCacheTimeout="30" />
</target>
</target>
<target name="MyApplicationHandlerLog" type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target type="BufferingWrapper" name="file" bufferSize="120">
<target type="File" fileName="${basedir}/logs/MyApplicationHandlerLog.log" layout="${longdate} ${exception:format=tostring} ${message} ${newline}" archiveFileName="${basedir}/archives/MyApplicationHandlerLogArchive/MyApplicationHandlerLog_{##}.log" archiveEvery="Day" archiveNumbering="Rolling" maxArchiveFiles="7" keepFileOpen="true" openFileCacheTimeout="30" />
</target>
</target>
<target name="MyApplicationHandlerMetrics" type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target type="BufferingWrapper" name="file" bufferSize="120">
<target type="File" fileName="${basedir}/logs/MyApplicationHandlerMetrics.log" layout="${longdate} ${exception:format=tostring} ${message} ${newline}" archiveFileName="${basedir}/archives/MyApplicationHandlerMetricsArchive/MyApplicationHandlerMetrics_{##}.log" archiveEvery="Day" archiveNumbering="Rolling" maxArchiveFiles="7" keepFileOpen="true" openFileCacheTimeout="30" />
</target>
</target>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="file" />
<logger name="MyApplicationHandlerLog" minlevel="Info" writeTo="MyApplicationHandlerLog" />
<logger name="MyApplicationHandlerMetrics" minlevel="Info" writeTo="MyApplicationHandlerMetrics" />
</rules>
</nlog>
I am facing multiple issues listed below - need your help to sort them.
Perfomance issues - I have enabled KeepFileOpen in the targets which improved the performance drastically.But have read somewhere that we need to set openFileCacheTimeout as well to make the performance optimistic. Is this true? or will it screw the performance if both are set?
Not Writing the logs to multiple files as in the rules - But is not working as expected.All logs getting written to MyApplicationHandlerMetrics
Archiving works as expected - "No issues I am facing at the moment"
Greatly appreciated if any suggestion can be given to improve the performance as my system deals with 140 messages/second
Thanks,
Vinod
Performance issues. Yes performance will be better using KeepFileOpen=true. openFileCacheTimeout will help NLog versions older than 4.4.2 to recover from file-problems. Use a timeout of 10 mins and no performance hit will be seen.
Pretty sure that it is a problem at your end, and not an issue in NLog. Have you checked the Internal Log ? Maybe start with a simple configuration that works, and extend from there?
Great
Well NLog ver. 4.4.2 can handle over 200.000 messsages/second, when using a SSD-disk.

NLog try another target when main target failed to log

I'm using NLog in my project, and one of the requirement is that if the log to a given file fails (for whatever reason), I must write the log in the event viewer.
How can I achieve that in the configuration file of NLog ?
Thanks in advance !
Ok, I found out how to do it.
The key is to use FallbackGroup as type of a target, and place the targets in correct order inside.
Example:
<target xsi:type="FallbackGroup" name="f" returnToFirstOnSuccess="true">
<target xsi:type="File"
name="f"
fileName="${basedir}/logs/${processname}-${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
<target xsi:type="EventLog"
name="eventLog"
layout="${longdate} ${uppercase:${level}} ${message}"
source="MySource"
log="Application" />
</target>
This has solved my problem.

Resources