You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法读取含点的appsettings.json键,NLog配置遇异常

NLog读取appsettings.json中含点的日志级别配置异常

问题背景

在NLog.Config中使用${configsetting}布局渲染器读取appsettings.json的日志级别配置时,普通名称(如Microsoft)能正常读取,但名称包含点的配置项(如Microsoft.Hosting.Lifetime)无法正确读取值。

环境配置示例

appsettings.json

"Logging": {
    "LogLevel": {
      "Default": "Error",
      "Microsoft": "Information",
      "Microsoft.Hosting.Lifetime": "Error"
    }
}

正常工作的NLog规则(读取普通名称)

<logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel.Microsoft}" writeTo="logfile,Loggly" />

无法工作的NLog规则(读取含点的名称)

<logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel.Microsoft.Hosting.Lifetime}" writeTo="logfile,Loggly" />

已尝试的无效方法

  • 使用单引号包裹:
    <logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel'.Microsoft.Hosting.Lifetime'}" writeTo="logfile,Loggly" />
    <logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel.'Microsoft.Hosting.Lifetime'}" writeTo="logfile,Loggly" />
    
  • 使用反斜杠转义点:
    <logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel.Microsoft\.Hosting\.Lifetime}" writeTo="logfile,Loggly" />
    
  • 使用斜杠替代点:
    <logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel.Microsoft/.Hosting/.Lifetime}" writeTo="logfile,Loggly" />
    
  • 使用方括号包裹:
    <logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel'.[Microsoft.Hosting.Lifetime]'}" writeTo="logfile,Loggly" />
    

编辑1:部分解决但规则不符合预期

尝试转义点(Microsoft\\.Hosting\\.Lifetime)后,配置能读取但日志规则行为不符合预期:

当前NLog.Config配置

<logger name="Microsoft.Hosting.Lifetime*" minlevel="${configsetting:item=Logging.LogLevel.Microsoft\\.Hosting\\.Lifetime}" writeTo="logfile,Loggly" />
<logger name="Microsoft.Hosting.Lifetime*" maxlevel="${configsetting:item=Logging.LogLevel.Microsoft\\.Hosting\\.Lifetime}" writeTo="void" final="true" />
<logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel.Microsoft}" writeTo="logfile,Loggly" />       
<logger name="Microsoft*" maxlevel="${configsetting:item=Logging.LogLevel.Microsoft}" writeTo="void" final="true"/>
<logger name="*" minlevel="${configsetting:item=Logging.LogLevel.Default}" writeTo="logfile,Loggly" />

当前appsettings.json配置

"Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Error",
          "Microsoft.Hosting.Lifetime": "Information"
        }
}

预期与实际差异

  • 预期:Microsoft.Hosting.Lifetime的Information及以下级别日志被导向void目标
  • 实际:仅Error及以下级别被导向void,推测读取的是Microsoft的日志级别值

NLog内部日志片段

2022-08-25 13:09:30.7512 Warn Logger: Microsoft.Hosting.Lifetime configured with duplicate output to target: FileTarget(Name=logfile). LoggingRule with NamePattern='Microsoft*' and Level=Error has been skipped.
2022-08-25 13:09:30.7512 Warn Logger: Microsoft.Hosting.Lifetime configured with duplicate output to target: FileTarget(Name=logfile). LoggingRule with NamePattern='*' and Level=Fatal has been skipped.
2022-08-25 13:09:30.7512 Debug Targets configured when LogLevel >= Trace for Logger: Microsoft.Hosting.Lifetime
2022-08-25 13:09:30.7512 Debug Logger Microsoft.Hosting.Lifetime [Trace] => void
2022-08-25 13:09:30.7678 Debug Logger Microsoft.Hosting.Lifetime [Debug] => void
2022-08-25 13:09:30.7678 Debug Logger Microsoft.Hosting.Lifetime [Info] => logfile Loggly void
2022-08-25 13:09:30.7678 Debug Logger Microsoft.Hosting.Lifetime [Warn] => logfile Loggly void
2022-08-25 13:09:30.7678 Debug Logger Microsoft.Hosting.Lifetime [Error] => logfile Loggly void
2022-08-25 13:09:30.7678 Debug Logger Microsoft.Hosting.Lifetime [Fatal] => logfile Loggly

解决方案

核心问题:配置路径解析与规则优先级

  1. 正确读取含点的配置项:
    NLog的configsetting渲染器在处理带点的键名时,需要明确告知渲染器这是单个键而非嵌套路径。推荐两种写法:

    • 用单引号包裹完整路径,同时转义键内的点:
      ${configsetting:item='Logging.LogLevel.Microsoft\.Hosting\.Lifetime'}
      
    • 使用jsonpath参数直接指定JSON路径,逻辑更清晰:
      ${configsetting:jsonpath=Logging.LogLevel.'Microsoft.Hosting.Lifetime'}
      
  2. 修正日志规则逻辑:
    原规则的问题在于minlevel和maxlevel的组合逻辑,以及规则执行顺序。要实现“指定级别及以下导向void”,需调整规则顺序和级别匹配方式:

    <!-- 先处理Microsoft.Hosting.Lifetime:将Information及以下级别导向void,终止后续规则 -->
    <logger name="Microsoft.Hosting.Lifetime*" maxlevel="${configsetting:jsonpath=Logging.LogLevel.'Microsoft.Hosting.Lifetime'}" writeTo="void" final="true" />
    <!-- 允许Microsoft.Hosting.Lifetime高于目标级别的日志输出 -->
    <logger name="Microsoft.Hosting.Lifetime*" minlevel="${configsetting:jsonpath=Logging.LogLevel.'Microsoft.Hosting.Lifetime'}:above" writeTo="logfile,Loggly" />
    
    <!-- 处理其他Microsoft前缀日志 -->
    <logger name="Microsoft*" maxlevel="${configsetting:item=Logging.LogLevel.Microsoft}" writeTo="void" final="true" />
    <logger name="Microsoft*" minlevel="${configsetting:item=Logging.LogLevel.Microsoft}:above" writeTo="logfile,Loggly" />
    
    <!-- 全局规则 -->
    <logger name="*" minlevel="${configsetting:item=Logging.LogLevel.Default}" writeTo="logfile,Loggly" />
    

    解释:

    • :above后缀表示“高于指定级别”,例如目标级别是Information时,minlevel=Information:above会匹配Warn及以上级别
    • 先执行maxlevel的void规则并标记final,确保符合条件的日志不会进入后续规则
  3. 验证配置读取:
    开启NLog内部日志确认配置读取状态:

    <internalLogFile="nlog-internal.log" internalLogLevel="Debug" />
    

    查看日志中是否有类似ConfigSettingParser Found value 'Information' for path 'Logging.LogLevel.Microsoft.Hosting.Lifetime'的条目,确认配置读取正确。


内容的提问来源于stack exchange,提问作者Bala teja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 20:27:30