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

Bap*_*ier 5 c# nlog asp.net-core-mvc .net-core asp.net-core

让我们假设我有两个项目。

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

第二个是 API 所依赖的类库,它直接依赖NLog于其日志记录。它包含这样的调用:

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

    public void DoStuff()
    {
        if (_failed) Logger.Error("oh no");
    }
}
Run Code Online (Sandbox Code Playgroud)

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


如何让我的库日志显示在 API 的日志输出中?我希望他们会被nlog.config自动抓住,但他们似乎没有。

dot*_*tep 7

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

    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 确保您已正确复制文件。在配置 NLog.config 中也正确设置了 MinLevel。

  3. 确保你有 .NET Core ClassLibrary(只是为了确保它加载成功)

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

这是 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>();
        }
    
    Run Code Online (Sandbox Code Playgroud)
  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");
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

现在它也可以正常工作。


Chr*_*att 6

类库永远不应该依赖于特定的日志记录实现。相反,您应该使用一种抽象,称为Facade。该Microsoft.Extensions.Logging库就是这样一个门面,你可以利用,但有其他人一样Common.Logging。无论如何,需要使用日志记录的类应该注入这个抽象的日志记录外观。例如:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

总而言之,您的类库仅取决于您的日志记录外观,这允许它一般调用诸如LogError. 使用您的库的应用程序设置了其实际的具体日志记录实现,然后由外观在后台使用该库进行日志记录。