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

ASP.NET Core 6中通过DI获取NLog日志实例异常问题

ASP.NET Core 6中NLog依赖注入实例日志级别异常问题解决

问题现象

  • Program.cs中直接创建的NLog日志实例可正确识别Debug/Trace级别,正常写入日志文件
  • 控制器通过构造函数注入的ILogger<HomeController>实例,始终显示Debug、Trace级别未启用,无法写入配置文件
  • 项目使用NLog.Extensions.Logging和NLog.Web.AspNetCore 5.2.1版本,旧版拆分Program.cs/Startup.cs的项目可正常工作
  • 已尝试指定NLog配置节名称、开启NLog内部日志,问题未解决

相关代码

Program.cs 原代码

var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Info("Service Init");
logger.Info($"  Log Level - Debug: {logger.IsEnabled(NLog.LogLevel.Debug)} Trace: {logger.IsEnabled(NLog.LogLevel.Trace)}");

try
{
  var builder = WebApplication.CreateBuilder(args);

  builder.Logging.ClearProviders();
  //builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
  builder.Host.UseNLog();

  builder.Services.AddControllersWithViews();

  var app = builder.Build();

  app.UseStaticFiles();
  app.UseRouting();

  app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");

  app.Run();
}
catch (Exception exc)
{
  logger.Error(exc, "Stopped program because of exception");
  throw;
}
finally
{
  NLog.LogManager.Shutdown();
}

控制器构造函数

public HomeController(ILogger<HomeController> logger)
{
    _logger = logger;
}

控制器日志代码

_logger.Info($"Log Level - Debug: {_logger.IsEnabled(NLog.LogLevel.Debug)} Trace: {_logger.IsEnabled(NLog.LogLevel.Trace)}");

NLog内部日志片段

2023-01-08 08:58:50.5328 Debug ScanAssembly('NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c')
2023-01-08 08:58:50.6446 Debug ScanAssembly('NLog.Web.AspNetCore, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c')
2023-01-08 08:58:50.6610 Trace Assembly 'NLog.Web.AspNetCore, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c' will be hidden in callsite stacktrace
2023-01-08 08:58:50.9908 Debug Hide assemblies for callsite
2023-01-08 08:58:50.9914 Debug ScanAssembly('NLog.Extensions.Logging, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c')
2023-01-08 08:58:50.9914 Trace Assembly 'NLog.Extensions.Logging, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c' will be hidden in callsite stacktrace
2023-01-08 08:58:50.9914 Trace Assembly 'Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' will be hidden in callsite stacktrace
2023-01-08 08:58:50.9914 Trace Assembly 'Microsoft.Extensions.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' will be hidden in callsite stacktrace
2023-01-08 08:58:51.0219 Trace ParseNLogConfig

问题原因

  1. ASP.NET Core 6的WebApplicationBuilder模式下,builder.Host.UseNLog()默认不会复用提前通过LogManager.Setup()加载的配置,导致DI容器中的日志实例使用默认配置而非自定义配置
  2. 未设置Microsoft Logging的最小级别,默认日志过滤层会拦截Debug/Trace级别的日志,即使NLog配置了对应级别也无法输出

解决方案

1. 调整Program.cs初始化顺序并启用最小日志级别

修改后的Program.cs代码:

try
{
  var builder = WebApplication.CreateBuilder(args);

  // 清除默认日志提供器,设置最小级别为Trace
  builder.Logging.ClearProviders();
  builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
  // 让Host加载NLog配置,整合到DI容器
  builder.Host.UseNLog();

  // 获取Host初始化后的NLog实例
  var logger = NLog.LogManager.GetCurrentClassLogger();
  logger.Info("Service Init");
  logger.Info($"  Log Level - Debug: {logger.IsEnabled(NLog.LogLevel.Debug)} Trace: {logger.IsEnabled(NLog.LogLevel.Trace)}");

  builder.Services.AddControllersWithViews();

  var app = builder.Build();

  app.UseStaticFiles();
  app.UseRouting();

  app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");

  app.Run();
}
catch (Exception exc)
{
  var logger = NLog.LogManager.GetCurrentClassLogger();
  logger.Error(exc, "Stopped program because of exception");
  throw;
}
finally
{
  NLog.LogManager.Shutdown();
}

2. 确保NLog配置文件启用Debug/Trace级别

如果使用appsettings.json配置NLog,确保rules中包含Trace级别:

"NLog": {
  "targets": {
    "file": {
      "type": "File",
      "fileName": "${basedir}/logs/${shortdate}.log",
      "layout": "${longdate} ${level} ${message} ${exception}"
    }
  },
  "rules": [
    {
      "logger": "*",
      "minLevel": "Trace",
      "writeTo": "file"
    }
  ]
}

如果使用nlog.config配置,确保规则中minlevel设置为Trace:

<?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">

  <targets>
    <target name="file" xsi:type="File" 
            fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${level} ${message} ${exception}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="file" />
  </rules>
</nlog>

说明

  • 将NLog初始化移到WebApplicationBuilder配置之后,确保UseNLog()正确加载配置并注入到DI容器中
  • 启用builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace),避免Microsoft日志框架过滤Debug/Trace日志
  • 移除提前调用LogManager.Setup()的代码,防止配置冲突导致DI实例无法获取正确配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:10:31