如何使用文件记录器将 NLog 中的自定义静态字段记录到所有日志?

How do I log a custom static field in NLog to all logs using the File Logger?

这个问题类似于 How do I log a custom field in NLog to database? ,但在我的例子中,我想在每个日志中记录相同的值。通常这将是一个硬编码的组件标识符,例如MAC 地址,我们在开始时读取一次并希望自动插入到所有日志中。

如果我遵循引用的答案,我可以做如下事情: LogEventInfo theEvent = new LogEventInfo(logLevel, "", message); theEvent.Properties["ComponentID"] =MAC地址;`

log.Log(事件);

但我想避免为每个日志都执行此操作。有没有办法通过为文件记录器指定一个布局来自动获得这个值,也许有一个 nlog 参数,比如:

<parameter name="@ComponentID" layout="${ComponentID}"/>

然后我会在我的代码中的某处设置值

您可以包装 NLog class 并将您的 MAC 地址添加到所有日志中。

public class MyLogger
{
    public static string MacAddress { get; set; }

    private NLog.Logger _logger;

    public MyLogger() : this(null) { }

    public MyLogger(string name)
    {
        _logger = NLog.LogManager.GetLogger(name ?? "");
    }

    public void Log(LogLevel level, string message, Exception exception = null)
    {
        if (level >= Manager.Instance.MinLevel)
        {
            var info = new NLog.LogEventInfo(level, _logger.Name, "<" + MacAddress + "> " + message);
            if (exception != null)
            {
                info.Exception = exception;
            }
            _logger.Log(typeof(NLogLogger), info);
        }
    }

    public void Trace(string message, Exception exception = null)
    {
        this.Log(LogLevel.Trace, message, exception);
    }

    public void Debug(string message, Exception exception = null)
    {
        this.Log(LogLevel.Debug, message, exception);
    }

    public void Info(string message, Exception exception = null)
    {
        this.Log(LogLevel.Info, message, exception);
    }

    public void Warn(string message, Exception exception = null)
    {
        this.Log(LogLevel.Warn, message, exception);
    }

    public void Error(string message, Exception exception = null)
    {
        this.Log(LogLevel.Error, message, exception);
    }

    public void Fatal(string message, Exception exception = null)
    {
        this.Log(LogLevel.Fatal, message, exception);
    }
}

那么你可以设置:

MyLogger.MacAddress = "XXX";

您可以使用 NLog variable,但需要注意的是,如果更改 NLog 配置文件并启用自动重新加载功能,该值将被重置:

LogManager.Configuration.Variables["ComponentID"] = "MACADDRESS";

文档提到如果您要在运行时更改值,则应动态使用它 (${var:ComponentID}) 而不是静态使用 (${ComponentID})。

实际上有一个名为 Global Diagnostic Context 的布局渲染器,其用途正是您所需要的。即使在上述情况下,该值也会保留。

GlobalDiagnosticsContext.Set("ComponentID","MACADDRESS");

这样使用:${gdc:item=ComponentID}.