使用 NLog 配置写入 ApplicationData 文件夹 API
Writing to the ApplicationData folder with NLog Configuration API
我有一个与 WCF 服务捆绑在一起的桌面应用程序。两者都是使用 .NET 4.7.2 构建的。应用程序和服务彼此共享一个安装目录,并且它们都使用 NLog 4.5.8 进行日志记录。它们各自使用 NLog 的方式的唯一区别是应用程序使用 NLog.config 文件来设置其日志记录属性,而服务使用 NLog Configuration API.
请注意,我为服务使用 NLog 配置 API 的原因是因为该服务似乎拒绝使用应用程序使用的 NLog.config 文件,即使它位于同一个文件中目录为他们两个。除非我使用 NLog 配置 API.
对其进行配置,否则它根本不会记录
无论如何,NLog 配置似乎一切正常 API;但是,我无法像使用 NLog.config 文件时那样将其定位到用于日志文件存储的 ApplicationData 文件夹。
在NLog.config文件中,ApplicationData文件夹可以如下定位:
<target xsi:type="File"
name="infoLogFile"
layout="${longdate}|${level:uppercase=true}|${callsite}|${logger:shortName=true}: ${message}"
fileName="${specialfolder:ApplicationData}\Program\file.log"
keepFileOpen="false"
archiveFileName="${specialfolder:ApplicationData}\Program\file_${shortdate}.{##}.log"
archiveNumbering="Sequence"
archiveEvery="Day"
maxArchiveFiles="30"
/>
我使用 NLog 配置 API 设置了我的 FileTarget,如下所示:
var infoFileTarget = new FileTarget("infoFileTarget")
{
Layout = @"${longdate}|${level:uppercase=true}|${callsite}|${logger:shortName=true}: ${message}",
FileName = "${specialfolder:ApplicationData}/Program/file.log",
KeepFileOpen = false,
ArchiveFileName = "${specialfolder:ApplicationData}/Program/file_${shortdate}.{##}.log",
ArchiveNumbering = ArchiveNumberingMode.Sequence,
ArchiveEvery = FileArchivePeriod.Day,
MaxArchiveFiles = 30,
};
config.AddTarget(infoFileTarget);
不幸的是,这不起作用。
但是,将 FileName/ArchiveFileName 设置为以下两项都有效:
FileName = "${basedir}/Program/file.log", // this works
或
FileName = "C:/Users/<USERNAME>/AppData/Roaming/Program/file.log, // this works
似乎以 ApplicationData 文件夹为目标应该可行,但我一定遗漏了一些东西。有使用 NLog 经验的人知道我如何让它工作吗?
在此先感谢您的帮助!
This nlog bug 表示 specialfolder
不适用于 dot net core。
解决方法似乎是:
<variable name="logFolder"
value="${environment:variable=APPDATA:whenEmpty=${environment:variable=HOME}}/Log" />
如果您认为 ${specialfolder:ApplicationData}
(或其他布局)不起作用,您可以将其记录到文件中。例如
<target xsi:type="File"
name="infoLogFile"
layout="${longdate}|my application data folder: ${specialfolder:ApplicationData}"
fileName="c:\temp\test.log"
/>
我认为 C:/Users/<USERNAME>/AppData/Roaming/Program/file.log
中的用户名可能出乎意料。
旁注:
${specialfolder}
在完整的 .NET 框架和 .NET Standard 2 中受支持,在 .NET Standard 1 中不受支持。NLog 使用 Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
检索文件夹。
我做了更多的挖掘,事实证明我的问题确实发生了,因为 Environment.SpecialFolder.ApplicationData
指的是一个不同的位置,当被本地系统帐户下的 Windows 服务 运行 引用时而不是由于 NLog 中的错误。我的解决方法是选择登录到 Environment.SpecialFolder.CommonApplicationData
文件夹,因为当 Windows 服务引用时该位置不会改变。
我用 this reference 提出了我的解决方案。
我有一个与 WCF 服务捆绑在一起的桌面应用程序。两者都是使用 .NET 4.7.2 构建的。应用程序和服务彼此共享一个安装目录,并且它们都使用 NLog 4.5.8 进行日志记录。它们各自使用 NLog 的方式的唯一区别是应用程序使用 NLog.config 文件来设置其日志记录属性,而服务使用 NLog Configuration API.
请注意,我为服务使用 NLog 配置 API 的原因是因为该服务似乎拒绝使用应用程序使用的 NLog.config 文件,即使它位于同一个文件中目录为他们两个。除非我使用 NLog 配置 API.
对其进行配置,否则它根本不会记录无论如何,NLog 配置似乎一切正常 API;但是,我无法像使用 NLog.config 文件时那样将其定位到用于日志文件存储的 ApplicationData 文件夹。
在NLog.config文件中,ApplicationData文件夹可以如下定位:
<target xsi:type="File"
name="infoLogFile"
layout="${longdate}|${level:uppercase=true}|${callsite}|${logger:shortName=true}: ${message}"
fileName="${specialfolder:ApplicationData}\Program\file.log"
keepFileOpen="false"
archiveFileName="${specialfolder:ApplicationData}\Program\file_${shortdate}.{##}.log"
archiveNumbering="Sequence"
archiveEvery="Day"
maxArchiveFiles="30"
/>
我使用 NLog 配置 API 设置了我的 FileTarget,如下所示:
var infoFileTarget = new FileTarget("infoFileTarget")
{
Layout = @"${longdate}|${level:uppercase=true}|${callsite}|${logger:shortName=true}: ${message}",
FileName = "${specialfolder:ApplicationData}/Program/file.log",
KeepFileOpen = false,
ArchiveFileName = "${specialfolder:ApplicationData}/Program/file_${shortdate}.{##}.log",
ArchiveNumbering = ArchiveNumberingMode.Sequence,
ArchiveEvery = FileArchivePeriod.Day,
MaxArchiveFiles = 30,
};
config.AddTarget(infoFileTarget);
不幸的是,这不起作用。
但是,将 FileName/ArchiveFileName 设置为以下两项都有效:
FileName = "${basedir}/Program/file.log", // this works
或
FileName = "C:/Users/<USERNAME>/AppData/Roaming/Program/file.log, // this works
似乎以 ApplicationData 文件夹为目标应该可行,但我一定遗漏了一些东西。有使用 NLog 经验的人知道我如何让它工作吗?
在此先感谢您的帮助!
This nlog bug 表示 specialfolder
不适用于 dot net core。
解决方法似乎是:
<variable name="logFolder"
value="${environment:variable=APPDATA:whenEmpty=${environment:variable=HOME}}/Log" />
如果您认为 ${specialfolder:ApplicationData}
(或其他布局)不起作用,您可以将其记录到文件中。例如
<target xsi:type="File"
name="infoLogFile"
layout="${longdate}|my application data folder: ${specialfolder:ApplicationData}"
fileName="c:\temp\test.log"
/>
我认为 C:/Users/<USERNAME>/AppData/Roaming/Program/file.log
中的用户名可能出乎意料。
旁注:
${specialfolder}
在完整的 .NET 框架和 .NET Standard 2 中受支持,在 .NET Standard 1 中不受支持。NLog 使用 Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
检索文件夹。
我做了更多的挖掘,事实证明我的问题确实发生了,因为 Environment.SpecialFolder.ApplicationData
指的是一个不同的位置,当被本地系统帐户下的 Windows 服务 运行 引用时而不是由于 NLog 中的错误。我的解决方法是选择登录到 Environment.SpecialFolder.CommonApplicationData
文件夹,因为当 Windows 服务引用时该位置不会改变。
我用 this reference 提出了我的解决方案。