如何在NLog中为外部包日志绑定对应项目的日志规则及级别
问题描述
当前项目的NLog日志规则配置如下:
{ "logger": "Alpha.*", "minLevel": "${configsetting:item=Alpha.LogLevel}", "ruleName": "Alpha", "writeTo": "fileTarget, consoleTarget" }, { "logger": "Beta.*", "minLevel": "${configsetting:item=Beta.LogLevel}", "ruleName": "Beta", "writeTo": "fileTarget, consoleTarget" }
引入AB.Common.Exception这类外部包后,希望外部包的日志能归属到调用它的项目对应的日志规则(例如Alpha项目调用的AB包日志,需遵循Alpha的日志级别,而非Beta的)。此前添加的全局规则"logger": "*"无法实现按调用项目区分日志级别的需求,需调整配置方案。
方法1:通过调用方命名空间匹配规则
利用NLog的CallerNamespace过滤器,针对外部包日志添加基于调用项目命名空间的判断,让不同项目调用的外部日志分别对应各自的日志级别:
修改后的NLog配置示例:
{ "logger": "Alpha.*", "minLevel": "${configsetting:item=Alpha.LogLevel}", "ruleName": "Alpha", "writeTo": "fileTarget, consoleTarget" }, { "logger": "Beta.*", "minLevel": "${configsetting:item=Beta.LogLevel}", "ruleName": "Beta", "writeTo": "fileTarget, consoleTarget" }, { "logger": "AB.Common.*", "minLevel": "${configsetting:item=Alpha.LogLevel}", "ruleName": "Alpha_AB", "writeTo": "fileTarget, consoleTarget", "filters": [ { "type": "ConditionBasedFilter", "condition": "contains('${caller:Namespace}','Alpha.')", "action": "Log" }, { "type": "ConditionBasedFilter", "condition": "not contains('${caller:Namespace}','Alpha.')", "action": "Ignore" } ] }, { "logger": "AB.Common.*", "minLevel": "${configsetting:item=Beta.LogLevel}", "ruleName": "Beta_AB", "writeTo": "fileTarget, consoleTarget", "filters": [ { "type": "ConditionBasedFilter", "condition": "contains('${caller:Namespace}','Beta.')", "action": "Log" }, { "type": "ConditionBasedFilter", "condition": "not contains('${caller:Namespace}','Beta.')", "action": "Ignore" } ] }
- 核心逻辑:针对
AB.Common.*命名空间的日志,分别创建两条规则,通过${caller:Namespace}获取调用方的命名空间,判断是否属于Alpha或Beta项目,匹配成功则使用对应项目的日志级别。 - 注意事项:需确保NLog配置中启用调用方信息收集,可在目标配置或全局配置里添加
includeCallerInformation="true"。
方法2:结合日志上下文标记实现动态级别
通过代码给外部包的调用上下文添加标记,再在NLog配置中根据标记动态匹配对应项目的日志级别,扩展性更强:
1. 代码层面(以C#为例)
在Alpha项目初始化或调用外部包前,添加上下文标记:
// Alpha项目中设置上下文 NLog.MappedDiagnosticsLogicalContext.Set("ProjectTag", "Alpha");
在Beta项目中执行同样操作:
// Beta项目中设置上下文 NLog.MappedDiagnosticsLogicalContext.Set("ProjectTag", "Beta");
2. NLog配置修改
{ "logger": "Alpha.*", "minLevel": "${configsetting:item=Alpha.LogLevel}", "ruleName": "Alpha", "writeTo": "fileTarget, consoleTarget" }, { "logger": "Beta.*", "minLevel": "${configsetting:item=Beta.LogLevel}", "ruleName": "Beta", "writeTo": "fileTarget, consoleTarget" }, { "logger": "AB.Common.*", "minLevel": "${configsetting:item=${mdlc:item=ProjectTag}.LogLevel}", "ruleName": "AB_ByProject", "writeTo": "fileTarget, consoleTarget" }
- 核心逻辑:利用
MappedDiagnosticsLogicalContext(MDLC)传递调用项目的标记,在NLog规则中通过${mdlc:item=ProjectTag}获取标记,动态拼接对应的配置项名称(如Alpha.LogLevel),实现日志级别随调用项目动态变化。 - 优势:无需为每个外部包创建多条规则,适合多外部包、多项目的场景。
内容的提问来源于stack exchange,提问作者Irinniada
相关产品推荐
相关产品推荐

