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.
Related
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) (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 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
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.
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" />