NLog 5 中有没有办法让两个 NLog 目标写入同一个日志文件?在 NLog 4.6.8 下是可能的,但在将我的应用程序升级到 NLog 5 后,我发现它不再起作用,至少在当前配置下是这样。
这是一个旧的演示 .NET Framework 4.5 控制台应用程序,使用 NLog 4.6.8 编写并包含 NLog.Config 4.6.8。通过此设置,控制台应用程序可以正常工作,两个目标都写入同一文件。
这是 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>
这是写入 demo.log 文件的输出:
**************************************************************************************************************
2023-08-30 14:47:33.1975 | Debug | NLogDemo.Program.Main | Application Starting
**************************************************************************************************************
2023-08-30 14:47:33.2235 | Debug | NLogDemo.Program.Main | This is a debug message
2023-08-30 14:47:33.2235 | Info | NLogDemo.Program.Main | This is an info message
2023-08-30 14:47:33.2235 | Error | NLogDemo.Program.Main | This is an error message
--------------------------------------------------------------------------------------------------------------
2023-08-30 14:47:33.2235 | Debug | NLogDemo.Program.Main | Application Closing
--------------------------------------------------------------------------------------------------------------
您可以看到 MessageOnlyLogger 已写入水平分隔符,并且当前类记录器已写入日志消息,其中包括时间戳、日志记录级别等。
当我升级到 NLog 5.2.3 时,我看到 NLog.Config 已被弃用,并且 这个 Stackoverflow 答案 说可以安全删除,所以我卸载了 NLog.Config 包。现在,当我运行应用程序时,只有 MessageOnlyLogger 写入日志文件。写入 demo.log 的输出如下:
**************************************************************************************************************
**************************************************************************************************************
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
nlog-internal.log 显示 NLog 无法创建第二个文件附加程序,因为该文件已被另一个进程使用(请参阅 15:04:27.7702 处的警告消息):
2023-08-30 15:04:27.6422 Info Configuration initialized.
2023-08-30 15:04:27.6482 Debug Targets configured when LogLevel >= Debug for Logger: NLogDemo.Program
2023-08-30 15:04:27.6482 Debug Logger NLogDemo.Program [Debug] => logfile console
2023-08-30 15:04:27.6482 Debug Logger NLogDemo.Program [Info] => logfile console
2023-08-30 15:04:27.6482 Debug Logger NLogDemo.Program [Warn] => logfile console
2023-08-30 15:04:27.6482 Debug Logger NLogDemo.Program [Error] => logfile console
2023-08-30 15:04:27.6482 Debug Logger NLogDemo.Program [Fatal] => logfile console
2023-08-30 15:04:27.6482 Debug Targets configured when LogLevel >= Debug for Logger: MessageOnlyLogger
2023-08-30 15:04:27.6482 Debug Logger MessageOnlyLogger [Debug] => messageonlylog
2023-08-30 15:04:27.6482 Debug Logger MessageOnlyLogger [Info] => messageonlylog
2023-08-30 15:04:27.6482 Debug Logger MessageOnlyLogger [Warn] => messageonlylog
2023-08-30 15:04:27.6482 Debug Logger MessageOnlyLogger [Error] => messageonlylog
2023-08-30 15:04:27.6592 Debug Logger MessageOnlyLogger [Fatal] => messageonlylog
2023-08-30 15:04:27.7152 Debug FileTarget(Name=messageonlylog): Preparing for new file: 'C:\C#\DemoCode\Logging\NLogDemo_SimpleUpgraded\NLogDemo\bin\Debug\demo.log'
2023-08-30 15:04:27.7252 Debug FileTarget(Name=messageonlylog): Creating file appender: 'C:\C#\DemoCode\Logging\NLogDemo_SimpleUpgraded\NLogDemo\bin\Debug\demo.log'
2023-08-30 15:04:27.7452 Debug Watching file-filter 'demo.log' in directory: C:\C#\DemoCode\Logging\NLogDemo_SimpleUpgraded\NLogDemo\bin\Debug
2023-08-30 15:04:27.7632 Debug FileTarget(Name=logfile): Preparing for new file: 'C:\C#\DemoCode\Logging\NLogDemo_SimpleUpgraded\NLogDemo\bin\Debug\demo.log'
2023-08-30 15:04:27.7632 Debug FileTarget(Name=logfile): Creating file appender: 'C:\C#\DemoCode\Logging\NLogDemo_SimpleUpgraded\NLogDemo\bin\Debug\demo.log'
2023-08-30 15:04:27.7702 Warn FileTarget(Name=logfile): Failed to create file appender: C:\C#\DemoCode\Logging\NLogDemo_SimpleUpgraded\NLogDemo\bin\Debug\demo.log Exception: System.IO.IOException: The process cannot access the file 'C:\C#\DemoCode\Logging\NLogDemo_SimpleUpgraded\NLogDemo\bin\Debug\demo.log' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
at NLog.Internal.FileAppenders.BaseFileAppender.TryCreateFileStream(Boolean allowFileSharedWriting, Int32 overrideBufferSize)
at NLog.Internal.FileAppenders.BaseFileAppender.CreateFileStream(Boolean allowFileSharedWriting, Int32 overrideBufferSize)
at NLog.Internal.FileAppenders.SingleProcessFileAppender..ctor(String fileName, ICreateFileParameters parameters)
at NLog.Internal.FileAppenders.SingleProcessFileAppender.Factory.NLog.Internal.FileAppenders.IFileAppenderFactory.Open(String fileName, ICreateFileParameters parameters)
at NLog.Internal.FileAppenders.FileAppenderCache.CreateAppender(String fileName, Int32 freeSpot)
有没有办法配置 NLog 5 来处理两个目标写入同一文件?还是已经不可能了?
问题不是删除
NLog.config
-nuget-package。
NLog v5 包括 几项重大更改,其中之一是将 FileTarget.KeepFileOpen 更改为
true
。
要让 2 个不同的 FileTarget 指向同一个文件,则必须显式配置
keepFileOpen="false"
<?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}"
keepFileOpen="false"
fileName="demo.log" />
<target
name="messageonlylog"
xsi:type="File"
layout="${message}"
keepFileOpen="false"
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>