使用NLog配置API写入ApplicationData文件夹

时间:2018-08-08 15:41:29

标签: c# nlog

我有一个与WCF服务捆绑在一起的桌面应用程序。两者都是使用.NET 4.7.2构建的。应用程序和服务彼此共享一个安装目录,并且它们都使用NLog 4.5.8进行日志记录。它们各自使用NLog的唯一区别是,应用程序使用NLog.config文件来设置其日志记录属性,而服务使用NLog Configuration API

请注意,我为服务使用NLog配置API的原因是因为该服务似乎拒绝使用应用程序使用的NLog.config文件,即使该文件与两个应用程序位于同一目录中也是如此。除非我使用NLog Configuration API对其进行配置,否则它根本不会记录日志。

无论如何,NLog Configuration 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经验的人有任何想法如何使它起作用吗?

预先感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

如果您认为${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中的用户名可能是意外的。

旁注:

完整的.NET Framework和.NET Standard 2(而不是.NET standard 1)支持

${specialfolder}。NLog正在使用Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)来检索文件夹。

答案 1 :(得分:2)

我做了一些进一步的挖掘,结果发现我的问题实际上是在发生,因为Environment.SpecialFolder.ApplicationData是指在LocalSystem帐户下运行的Windows Service引用的另一个位置,而不是由于NLog中的错误。我的解决方法是选择登录Environment.SpecialFolder.CommonApplicationData文件夹,因为Windows服务引用该位置时该位置不会更改。

我用this reference提出了解决方案。

答案 2 :(得分:0)

This nlog bug提示specialfolder在点网核心上不起作用。

解决方法似乎是:

<variable name="logFolder"
 value="${environment:variable=APPDATA:whenEmpty=${environment:variable=HOME}}/Log" />