在运行时更新NLog目标文件名

Kri*_*s-I 22 c# logging nlog

在我的应用程序中,我每天处理数千个文档.我想,在某些情况下,一些日志,一个按文档记录.然后我想要一个特定的目标在运行时更改输出文件名(和只有文件名).

在网络上我发现如何通过编程来创建目标我只想通过编程更新文件名.我试过下面的代码.我收到的错误是"无法找到LayoutRender'logDirectory'.

任何的想法 ?

谢谢,

var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");
target.FileName = "${logDirectory}/file2.txt";

LoggingConfiguration config = new LoggingConfiguration();
var asyncFileTarget = new AsyncTargetWrapper(target);
config.AddTarget("logfile", asyncFileTarget);

LogManager.Configuration = config;
Run Code Online (Sandbox Code Playgroud)

配置文件是:

  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <variable name="logDirectory" value="C:/MyLogs"/>
    <targets>
      <target name="logfile" xsi:type="File" layout="${date:format=dd/MM/yyyy HH\:mm\:ss.fff}|${level}|${stacktrace}|${message}" fileName="${logDirectory}/file.txt" />
    </targets>

    <rules>
      <logger name="*" minlevel="Info" writeTo="logfile" />
    </rules>    
  </nlog>
Run Code Online (Sandbox Code Playgroud)

Ton*_*ony 23

尝试ReconfigExistingLoggers方法:

var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");
target.FileName = "${logDirectory}/file2.txt";
LogManager.ReconfigExistingLoggers();
Run Code Online (Sandbox Code Playgroud)

如文档中所述:

循环访问GetLogger先前返回的所有记录器.并重新计算其目标和筛选器列表.在以编程方式修改配置以确保已正确配置所有记录器之后很有用.

编辑:

尝试使用自定义布局渲染器:NLog配置文件从web.config获取配置设置值


Bad*_*ack 5

如果您使用NLog Async(<targets async="true">),则Tony的解决方案似乎无效。我必须使用包装器目标来获取我的FileTarget,否则会出现很多错误。我正在使用NLog 2.1。

if (LogManager.Configuration != null && LogManager.Configuration.ConfiguredNamedTargets.Count != 0)
{
    Target target = LogManager.Configuration.FindTargetByName("yourFileName");
    if (target == null)
    {
        throw new Exception("Could not find target named: " + "file");
    }

    FileTarget fileTarget = null;
    WrapperTargetBase wrapperTarget = target as WrapperTargetBase;

    // Unwrap the target if necessary.
    if (wrapperTarget == null)
    {
        fileTarget = target as FileTarget;
    }
    else
    {
        fileTarget = wrapperTarget.WrappedTarget as FileTarget;
    }

    if (fileTarget == null)
    {
        throw new Exception("Could not get a FileTarget from " + target.GetType());
    }

    fileTarget.FileName = "SetFileNameHere";
    LogManager.ReconfigExistingLoggers();
}
Run Code Online (Sandbox Code Playgroud)

这也不会更改配置文件,只会更改运行时值。因此,我还使用以下代码将配置文件手动编辑为新值:

var nlogConfigFile = "NLog.config";
var xdoc = XDocument.Load(nlogConfigFile);
var ns = xdoc.Root.GetDefaultNamespace();
var fTarget = xdoc.Descendants(ns + "target")
         .FirstOrDefault(t => (string)t.Attribute("name") == "yourFileName");
fTarget.SetAttributeValue("fileName", "SetFileNameHere");
xdoc.Save(nlogConfigFile);
Run Code Online (Sandbox Code Playgroud)


Rol*_*sen 5

如果不需要在运行时更改LogDirectory,则可以执行以下操作:

target.FileName = "${var:logDirectory}\\file2.txt");
Run Code Online (Sandbox Code Playgroud)

如果需要在运行时修改logDirectory,请使用GDC:

https://github.com/NLog/NLog/wiki/Gdc-layout-renderer

NLog.GlobalDiagnosticsContext.Set("logDirectory","C:\Temp\");
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下布局:

target.FileName = "${gdc:item=logDirectory}\\file2.txt";
Run Code Online (Sandbox Code Playgroud)