如何通过NLog配置实现内联、作用域、上下文属性的优先级覆盖?
实现NLog属性覆盖优先级(上下文→作用域→内联)
可以通过修改NLog配置实现你要的覆盖逻辑,核心是关闭自动重复属性后缀,并利用NLog内置的属性优先级顺序:
步骤1:关闭重复属性自动加后缀
在NLog配置文件的<nlog>根节点添加allowDuplicateProperties="false",这样当存在同名属性时,NLog不会生成带数字后缀的新属性,而是用后加载的属性覆盖之前的。
NLog的属性加载顺序固定为:
- 全局上下文属性(GlobalDiagnosticsContext)→ 作用域属性(ScopeContext)→ 日志事件内联属性(EventProperties)
这正好匹配你的需求:内联属性覆盖作用域属性,作用域属性覆盖上下文属性。
步骤2:配置日志目标(结构化/非结构化通用)
不管是支持结构化日志的目标(如JsonLayout)还是普通文本目标,只需确保配置中启用属性包含即可:
示例配置(NLog.config)
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" allowDuplicateProperties="false"> <!-- 日志规则 --> <rules> <logger name="*" minlevel="Trace" writeTo="console, jsonFile" /> </rules> <!-- 目标配置 --> <targets> <!-- 控制台目标(非结构化输出) --> <target name="console" xsi:type="Console"> <layout> ${longdate} ${level} | ${message} | ${all-event-properties} </layout> </target> <!-- JSON文件目标(结构化输出) --> <target name="jsonFile" xsi:type="File" fileName="logs/app.log.json"> <layout type="JsonLayout" includeAllProperties="true"> <attribute name="timestamp" layout="${longdate}" /> <attribute name="level" layout="${level}" /> <attribute name="message" layout="${message}" /> </layout> </target> </targets> </nlog>
验证效果
调用DoWithScope方法时,内联的myProperty会覆盖作用域中的同名属性,最终日志中只会保留内联属性的值,不会出现myProperty_1这类后缀属性。
如果需要针对特定属性做精细控制(比如部分属性不遵循覆盖逻辑),可以在布局中手动指定优先级,例如:
<attribute name="myProperty" layout="${event-properties:myProperty:whenEmpty=${scope-properties:myProperty:whenEmpty=${gdc:myProperty}}}" />
这种方式会优先取内联属性,不存在则取作用域属性,最后取上下文属性,适合单独配置的场景。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

