【问题标题】:Use a relative path in an NLog configuration file for a FileTarget在 NLog 配置文件中为 FileTarget 使用相对路径
【发布时间】:2020-12-18 15:13:10
【问题描述】:

我将 NLog 与 PowerShell 脚本一起使用,其中消息被记录到与脚本相关的目录中的文件中。

我希望能够在 Xml 配置文件中指定相对路径,但是这种语法不起作用:

<target name="logfile" xsi:type="File" fileName="./Logs/${logger}/${logger}.${date:format=yyyyMMdd}.${date:format=HHmmss}.log" createDirs="true" layout="${machinename}|${environment-user}|${logger}|${date:format=yyyy-MM-dd HH\:mm\:ss}|${level:uppercase=true}|${message}"/>

目前,我正在这样做:

$ScriptName = (Get-Item $PSCommandPath).Basename
$Here = Split-Path -Parent $MyInvocation.MyCommand.Path

# create logger
$Logger = [NLog.LogManager]::GetLogger($ScriptName)

# load Xml configuration file (in the same directory as script)
$Configuration = [NLog.Config.XmlLoggingConfiguration]::new("$Here/$ScriptName.NLog.config")    
[NLog.LogManager]::Configuration = $Configuration

# reconfigure the file target
$target = $Configuration.FindTargetByName("logfile")
$target.FileName = "$Here/Logs/$ScriptName/$ScriptName.$( (get-date).tostring('yyyyMMdd.HHmmss') ).log"
[NLog.LogManager]::ReconfigExistingLoggers()

有没有办法在 Xml 配置文件中使用相对路径?

【问题讨论】:

    标签: powershell nlog powershell-7.0


    【解决方案1】:

    您也可以使用 NLog-Config-Variables:

    <nlog>
        <variable name="ScriptDirectory" value="${currentdir}" />
    
        <targets>
           <target name="logfile" xsi:type="File" fileName="${var:ScriptDirectory}/Logs/${logger}/${logger}.${date:format=yyyyMMdd}.${date:format=HHmmss}.log" />
        </targets>
    
        <rules>
           <logger name="*" minLevel="Debug" writeTo="logfile" />
        </rules>
    </nlog>
    

    然后只需分配

    NLog.LogManager.Configuration.Variables["ScriptDirectory"] = absolutePath;
    

    那么您将不需要调整当前目录,这可能会产生不必要的副作用。

    【讨论】:

    • 这行得通。为什么需要var:?我已经使用了其他变量,而无需以这种方式对其进行限定。
    • @craig NLog 配置变量是特殊的。在没有var: 的情况下使用时,它们可以作为副本替换令牌,但完全是静态的。当与${var: 一起使用时,它们可以动态更新,但它们仅适用于 NLog Layout 类型的属性,例如 NLog FileTarget FileName-property。
    【解决方案2】:

    默认情况下,NLog FileTarget 将使用AppDomain.BaseDirectory 作为“根”,所有相对路径都相对于这个“根”。

    我猜对于 PowerShell 脚本,AppDomain.BaseDirectory 将是 PowerShell-Executable-Directory,而不是预期的当前目录。

    我想你会通过使用${currentdir}获得预期的目录:

    <target name="logfile" xsi:type="File" fileName="${currentdir:cached=true}/Logs/${logger}/${logger}.${date:format=yyyyMMdd}.${date:format=HHmmss}.log" />
    

    您也可以只写信给ConsoleTarget,然后使用默认的命令提示符逻辑将 powershell-stdout 的输出通过管道传输到所需的文件名。

    【讨论】:

    • 不幸的是,这不起作用。如果有办法在代码中设置 currentdir 值,那将有所帮助。设置[System.Io.Directory]::SetCurrentDirectory($Here) 可以将currentdir 设置为脚本文件夹。
    • @craig 在了解您想要脚本位置的目录而不是当前目录后添加了另一个答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多