升级NLog 5后两个日志目标无法写入同一文件的解决咨询
NLog 5多File Target写入同一日志文件的配置方案
我有一个基于.NET Framework 4.5的控制台Demo程序,使用NLog 4.6.8时,两个File Target可以正常写入同一日志文件。但升级至NLog 5.2.3并移除已弃用的NLog.Config包后,仅MessageOnlyLogger能写入日志文件,另一个目标因文件被占用无法写入。内部日志显示文件被其他进程占用,请问是否可配置NLog 5实现多目标写入同一日志文件?
相关代码与配置
Program.cs代码
using NLog; using System; namespace NLogDemo { class Program { private static NLog.Logger LOG = LogManager.GetCurrentClassLogger(); private static NLog.Logger MESSAGEONLYLOG = LogManager.GetLogger("MessageOnlyLogger"); static void Main(string[] args) { MESSAGEONLYLOG.Debug(" "); MESSAGEONLYLOG.Debug(new string('*', 110)); LOG.Debug("Application Starting"); MESSAGEONLYLOG.Debug(new string('*', 110)); LOG.Debug("This is a debug message"); LOG.Info("This is an info message"); LOG.Error("This is an error message"); MESSAGEONLYLOG.Debug(new string('-', 110)); LOG.Debug("Application Closing"); MESSAGEONLYLOG.Debug(new string('-', 110)); Console.WriteLine(); Console.WriteLine("Press any key to exit"); Console.ReadKey(); } } }
app.config配置
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" /> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <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="false" internalLogLevel="Debug" internalLogFile="nlog-internal.log"> <targets> <target name="logfile" xsi:type="File" layout="${longdate} | ${level} | ${callsite} | ${message} ${exception:format=tostring}" fileName="demo.log" /> <target name="messageonlylog" xsi:type="File" layout="${message}" fileName="demo.log" /> <target name="console" xsi:type="Console" layout="${message} ${exception:format=tostring}" /> </targets> <rules> <logger name="MessageOnlyLogger" minlevel="Debug" writeTo="messageonlylog" final="true" /> <logger name="*" minlevel="Debug" writeTo="logfile" /> <logger name="*" minlevel="Debug" writeTo="console" /> </rules> </nlog> </configuration>
解决方案
NLog 5调整了文件访问的默认行为,要实现多File Target写入同一文件,可通过以下两种方式配置:
方案1:给File Target添加共享配置
修改两个File Target,添加shared="true"和concurrentWrites="true"属性,显式开启文件共享与并发写入支持:
<targets> <target name="logfile" xsi:type="File" layout="${longdate} | ${level} | ${callsite} | ${message} ${exception:format=tostring}" fileName="demo.log" shared="true" concurrentWrites="true" /> <target name="messageonlylog" xsi:type="File" layout="${message}" fileName="demo.log" shared="true" concurrentWrites="true" /> <target name="console" xsi:type="Console" layout="${message} ${exception:format=tostring}" /> </targets>
shared="true":允许多个NLog目标或进程同时访问日志文件concurrentWrites="true":启用并发写入逻辑,避免写入冲突
方案2:使用单个File Target+条件Layout(更推荐)
直接使用单个File Target,通过条件Layout根据Logger名称区分输出格式,从根源上避免文件占用冲突:
<targets> <target name="combinedlog" xsi:type="File" fileName="demo.log"> <!-- 根据Logger名称选择对应输出格式 --> <layout type="When"> <when condition="contains('${logger}', 'MessageOnlyLogger')" layout="${message}" /> <when condition="true" layout="${longdate} | ${level} | ${callsite} | ${message} ${exception:format=tostring}" /> </layout> </target> <target name="console" xsi:type="Console" layout="${message} ${exception:format=tostring}" /> </targets> <rules> <!-- 所有日志统一写入同一个文件Target和控制台 --> <logger name="*" minlevel="Debug" writeTo="combinedlog,console" /> </rules>
这种方式无需多个Target竞争文件资源,是NLog官方推荐的多格式输出到同一文件的实现方式。
内容的提问来源于stack exchange,提问作者Simon Elms
相关产品推荐
相关产品推荐

