如何在我的 ASP.NET 核心 MVC 应用程序中记录来自 class 库的 NLog 调用?

How to log NLog calls from a class library in my ASP.NET Core MVC app?

假设我有两个项目。

第一个是 ASP.NET 核心 MVC 项目,它依赖 NLog.Extensions.Logging 进行日志记录。这很棒;我可以在我的控制器上使用依赖注入来获得一个 ILogger 实例,并且 nlog.config 文件包含我的 NLog 配置。

第二个是 class 库,API 依赖它,它直接依赖 NLog 进行日志记录。它包含这样的调用:

public class SampleClass
{
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

    public void DoStuff()
    {
        if (_failed) Logger.Error("oh no");
    }
}

这些 classes 是用一些反身魔法实例化的,我不能使用依赖注入 来替换它们的记录器。您也可以将它们视为某种模型,无法在启动时实例化。


如何让我的图书馆的日志显示在 API 的日志输出中? 我希望它们被 nlog.config 自动,但他们似乎不是。

  1. 您不需要单独的配置文件。 如果您的 ASP.net MVC 核心项目有 nlog.config 并且它在构建过程中成功复制,那么相同的配置将在

    时加载
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
    
  2. 确保您已正确复制文件。在配置 NLog.config.

  3. 中也正确设置了 MinLevel
  4. 确保你有 .NET Core ClassLibrary(只是为了确保它加载成功)

  5. 在你的情况下,你也可以使用依赖注入,但它是不同的故事。

这是 NLog 的完整示例

  1. 您需要获取 NLog 和 NLog.Web.AspnetCore 包

  2. 在Program.cs

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
         return  WebHost.CreateDefaultBuilder(args)
                    .ConfigureLogging(logging =>
                    {
                        logging.ClearProviders();
                        logging.SetMinimumLevel(LogLevel.Trace);
                    }).UseNLog()
                .UseStartup<Startup>();
        }
    
  3. 现在在 ClassLibrary 项目中只需添加 NLog 的引用。 注意:这里确保 ILogger 来自 Microsoft.Extensions.Logging 而不是来自 NLog.

    public class Class1
    {
        //private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        private ILogger<Class1> _logger = null;
        public Class1(ILogger<Class1> logger)
        {
            this._logger = logger;
        }
    
        public void DoStuff()
        {
            var _failed = true;
            if (_failed) _logger.LogError("oh no");
        }
    }
    

现在它也可以正常工作了。

Class 库不应该依赖于特定的日志记录实现。相反,您应该使用抽象,称为 facadeMicrosoft.Extensions.Logging 库是您可以使用的此类外观之一,但还有其他类似 Common.Logging 的外观。无论如何,需要使用日志记录的 classes 应该被注入这个抽象的日志外观。例如:

public class SampleClass
{
    private readonly ILogger _logger;

    public SampleClass(ILogger<SampleClass> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public void DoStuff()
    {
        if (_failed) _logger.LogError("oh no");
    }
}

然后,在您的 Web 应用程序或任何其他使用您的 class 库的具体应用程序中,这是您实际设置日志记录实现的地方,并通过您的 DI 容器注册它以注入到您的记录立面。

总而言之,您的 class 库仅依赖于您的日志外观,这允许它一般地调用 LogError 之类的东西。使用您的库的应用程序设置其实际的具体日志记录实现,然后由 facade 在后台使用它来记录库的日志记录。