如何同步C#与NLog.config的deviceId变量并校验其值
统一C#与NLog.config中的deviceId变量并实现日志过滤
问题分析
你当前的C#代码和NLog.config里的deviceId是独立实体,NLog无法直接获取C#变量的值,导致配置里的过滤规则'${deviceId}' == '2'无法生效。需要将C#中的deviceId传递到NLog上下文,让配置文件能读取到这个变量。
解决方案步骤
1. 修改C#代码,传递deviceId到NLog上下文
使用NLog的MappedDiagnosticsLogicalContext(适配异步场景)将deviceId注入日志上下文,修改后的代码如下:
static void Main(string[] args) { Logger log = LogManager.GetCurrentClassLogger(); int deviceId; deviceId = 1; MappedDiagnosticsLogicalContext.Set("deviceId", deviceId); log.Debug(""); deviceId = 2; MappedDiagnosticsLogicalContext.Set("deviceId", deviceId); log.Debug(""); deviceId = 3; MappedDiagnosticsLogicalContext.Set("deviceId", deviceId); log.Debug(""); }
2. 修正NLog.config的过滤规则
原配置中<filters>节点位置错误,需嵌套在<logger>节点内部才能生效,同时调整变量读取方式:
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" autoReload="true" throwExceptions="false" internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> <variable name="myvar" value="myvalue"/> <targets> <target xsi:type="File" name="file" fileName="${basedir}/logs/${shortdate}.log" /> </targets> <rules> <logger name="*" minlevel="Trace" writeTo="file"> <filters> <!-- 匹配上下文里的deviceId等于2的日志 --> <when condition="'${mdlc:deviceId}' == '2'" action="Log" /> <!-- 忽略其他所有日志 --> <when condition="true" action="Ignore" /> </filters> </logger> </rules> </nlog>
${mdlc:deviceId}用于读取MappedDiagnosticsLogicalContext中的变量,若使用全局共享的GlobalDiagnosticsContext,则对应${gdc:deviceId}。
3. 验证效果
运行代码后,查看日志文件${basedir}/logs/${shortdate}.log,只会存在deviceId=2时生成的日志条目,其余两个deviceId的日志不会被写入。
额外说明
- 若要在日志消息中显示deviceId,可修改日志语句为
log.Debug("Device ID: {deviceId}", deviceId);,或直接使用上下文变量log.Debug("Device ID: ${mdlc:deviceId}");。 - 对于.NET Core/.NET 5+,也可使用
Logger.WithProperty("deviceId", deviceId).Debug("");传递变量,配置中用${event-properties:deviceId}读取。
内容的提问来源于stack exchange,提问作者tridjam
相关产品推荐
相关产品推荐

