如何使用文件记录器将 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}
.
这个问题类似于 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}
.