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

如何在NLog中实现作用域标题、缩进及时长统计?

NLog实现作用域生命周期日志与缩进格式

需求说明

需要在NLog中实现以下日志效果:

  • 每个作用域创建时输出带创建时间的标题
  • 作用域结束时输出包含持续时长的收尾信息
  • 根据作用域深度对日志内容自动缩进
  • 不希望自行包装BeginScope的IDisposable,优先使用NLog原生功能实现

代码示例

using (_logger.BeginScope("Starting processing"))
{
    _logger.LogInformation("Algorithm1 Initialized");
    _logger.LogInformation("Algorithm2 Initialized");

    using (_logger.BeginScope("Algorithm 1 running"))
    {
        for (int i=0; i<5; i++)
            _logger.LogInformation($"Algorithm1 progress {i}");
    }

    using (_logger.BeginScope("Algorithm 2 running"))
    {
        for (int i = 0; i < 5; i++)
            _logger.LogInformation($"Algorithm2 progress {i}");
    }
}

期望输出

Starting processing (Started: XX:XX:XX.XXX)
        Algorithm1 Initialized
        Algorithm2 Initialized  
        Algorithm 1 running (Started: XX:XX:XX.XXX)
            Algorithm1 progress 0
            Algorithm1 progress 1
            Algorithm1 progress 2
            Algorithm1 progress 3
            Algorithm1 progress 4
        Algorithm 1 running finished in 00:00:10
        Algorithm 2 running (Started: XX:XX:XX.XXX)
            Algorithm2 progress 0
            Algorithm2 progress 1
            Algorithm2 progress 2
            Algorithm2 progress 3
            Algorithm2 progress 4
        Algorithm 2 running finished in 00:00:10
    Starting processing finished in 00:00:XX

实现方案

1. NLog配置文件设置

通过NLog原生布局渲染器实现需求,关键用到:

  • ${scopeindent}:根据作用域深度生成缩进(默认每个层级4个空格,可自定义)
  • ${scopetiming}:输出作用域的生命周期信息,包含开始时间和持续时长
  • ${scopemessage}:获取当前作用域的消息内容

完整NLog.config配置示例

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <targets>
    <target name="console" xsi:type="Console">
      <!-- 普通日志格式:缩进 + 日志内容 -->
      <layout type="CompositeLayout">
        <layout type="SimpleLayout" text="${scopeindent}" />
        <layout type="SimpleLayout" text="${message}" />
      </layout>
      <!-- 作用域开始/结束的专用格式 -->
      <scope-activity-layout type="CompositeLayout">
        <layout type="SimpleLayout" text="${scopeindent}" />
        <layout type="SimpleLayout" text="${scopemessage}" />
        <!-- 作用域开始时追加启动时间 -->
        <layout type="SimpleLayout" text="${when:when='${scopetiming:format=Started}' != '':inner= (Started: ${date:format=HH\\:mm\\:ss.fff})}" />
        <!-- 作用域结束时追加持续时长 -->
        <layout type="SimpleLayout" text="${when:when='${scopetiming:format=Elapsed}' != '':inner= finished in ${scopetiming:format=hh\\:mm\\:ss}}" />
      </scope-activity-layout>
    </target>
  </targets>

  <rules>
    <!-- 输出普通业务日志 -->
    <logger name="*" minlevel="Info" writeTo="console" />
    <!-- 启用作用域活动日志,自动输出开始/结束事件 -->
    <logger name="*" minlevel="Trace" writeTo="console" scope="Activity" />
  </rules>
</nlog>

2. 关键配置说明

  • scope-activity-layout:专门处理作用域的创建和结束事件,NLog会在调用BeginScope时自动输出启动信息,在作用域Dispose时自动输出结束信息(包含时长)
  • ${scopeindent}:自动根据当前作用域层级生成缩进,可通过${scopeindent:indentSize=2}自定义每个层级的缩进字符数
  • ${scopetiming}:通过format参数区分场景,Started返回启动时间,Elapsed返回持续时长,搭配${when}渲染器实现条件输出
  • 作用域活动日志规则:必须添加scope="Activity"的日志规则,确保NLog捕获并输出作用域生命周期事件

3. 代码调整说明

无需修改原有业务代码,保持BeginScope的原生调用即可。NLog会自动处理作用域的开始/结束日志输出,同时为普通日志自动添加对应层级的缩进。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:10:30