简体   繁体   English

.NET Standard 类库中的日志消息

[英]Log messages from .NET Standard class library

I have a solution with an ASP.NET Core (2.1.5) Web API project which references a couple of .NET Standard 2.0 class libraries projects.我有一个包含 ASP.NET Core (2.1.5) Web API 项目的解决方案,该项目引用了几个 .NET Standard 2.0 类库项目。

I want to implement some logging to my application and I have already done this for the Web API project using NLog (in fact, it can be any provider implementing ILogger).我想为我的应用程序实现一些日志记录,并且我已经使用NLog为 Web API 项目完成了这项工作(实际上,它可以是任何实现 ILogger 的提供程序)。 To do this, I defined in Program.cs a static field which is initialized during the runtime and configured it with using WebHostBuilderExtensions.ConfigureLogging :为此,我在Program.cs 中定义了一个静态字段,该字段在运行时初始化并使用WebHostBuilderExtensions.ConfigureLogging对其进行配置:

using Microsoft.Extensions.Logging;

public class Program
{
    private static readonly Logger logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
    // other content ...
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    var webHost = WebHost.CreateDefaultBuilder(args)
        .UseStartup(typeof(Startup).GetTypeInfo().Assembly.FullName)
        .ConfigureLogging(builder =>
        {
            builder.ClearProviders();
            builder.SetMinimumLevel(LogLevel.Information);
        })
        .UseNLog();
    // other content ...
}   

This allows me to use DI of ILogging in every class inside my ASP.NET Core application whenever I need it:这使我可以在需要时在 ASP.NET Core 应用程序中的每个类中使用ILogging 的DI:

using Microsoft.Extensions.Logging;

public class Startup
{
    public IConfiguration Configuration { get; }
    private readonly ILogger<Startup> _logger;

    public Startup(IConfiguration configuration, ILogger<Startup> logger)
    {
        Configuration = configuration;
        _logger = logger;
    }
}

But now I am totally confused with setting up a logging for my class libraries.但是现在我完全对为我的类库设置日志感到困惑。 One of the options I can imagine is to use the DI mechanism to allow my libraries to call the same ILogger interface like this:我可以想象的选项之一是使用 DI 机制来允许我的库调用相同的ILogger接口,如下所示:

using Microsoft.Extensions.Logging;

public class MyLibraryClass
{
    private ILogger<MyLibraryClass> _logger;

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

    public void SomeLibraryMethod()
    {
        _logger.LogInformation("Some library method logging here...);
    }
}

But that looks to be quite awkward as I need to inject this dependency for all my libraries classes where I need logging (so to say, to all classes).但这看起来很尴尬,因为我需要为我需要记录的所有库类(可以说,所有类)注入此依赖项。

I also think of some static class for each library project where this dependency is injected just once and so that the static class can act as a wrapper around ILogger .我还为每个库项目考虑了一些静态类,其中此依赖项仅注入一次,以便静态类可以充当ILogger的包装器。 Or even to move NLog from the WebAPI project to one of the libraries (or even make a separate library) and use it call this library from all other projects.或者甚至将 NLog 从 WebAPI 项目移动到其中一个库(甚至创建一个单独的库)并使用它从所有其他项目调用这个库。 But as advised here , it is better to have a separate instance of ILogger for each class to filter different loggers.但正如这里所建议的,最好为每个类都有一个单独的ILogger实例来过滤不同的记录器。 Or maybe it is enough to create static loggers for a certain project?或者也许为某个项目创建静态记录器就足够了?

My another concern is that such static wrappers around ILogger would require from me to define my own interface to work with log messages.我的另一个担忧是 ILogger 的此类静态包装器需要我定义自己的接口来处理日志消息。 But ILogger is itselt a well-designed interface and such attitude seems to be some kind of double work.ILogger本身就是一个精心设计的界面,这种态度似乎是某种双重工作。

I have looked through a lot of step-by-step guides but most of them describe how to configure logging just for one ASP.NET Core web application (or most probably, I used wrong search keywords).我已经浏览了很多分步指南,但其中大部分都描述了如何仅为一个 ASP.NET Core Web 应用程序配置日志记录(或者很可能,我使用了错误的搜索关键字)。 Anyway, I am stuck at this moment and don't know the correct way to make my libraries use the same logging provider and file as for my main WebAPI application.无论如何,我此时卡住了,不知道让我的库使用与我的主 WebAPI 应用程序相同的日志记录提供程序和文件的正确方法。 Maybe, there are any well-known practices that I have missed?也许,我错过了一些众所周知的做法?

I don't think it's awkward Microsoft.Extensions.Logging.ILogger is a common interface that most logging libraries implement. 我不认为这很尴尬Microsoft.Extensions.Logging.ILogger是大多数日志库实现的通用接口。

Using a singleton in this scenario would tie you to a specific logging library which is maybe fine for small project or POC projects, but imagine sharing your library across teams or publishing it. 在这种情况下使用单例会将您绑定到特定的日志库,这对于小型项目或POC项目来说可能很好,但想象一下跨团队共享您的库或发布它。 It is much more convenient to expect an interface. 期望接口更方便。

As for, how to inject your logging library of choice to your class library, you don't really have to worry about it as it is taken care of by the DI system. 至于如何将您选择的日志库注入您的类库,您不必担心它,因为它由DI系统负责。

You just need to declare your class as a constructor dependency in one of your web project classes. 您只需要在一个Web项目类中将您的类声明为构造函数依赖项。

I think your Library project classes should have Microsoft.Extensions.Logging.ILogger injected in their CTOR like ILogger<T> logger = null .我认为您的库项目类应该在其 CTOR 中注入Microsoft.Extensions.Logging.ILogger ,如ILogger<T> logger = null It is the responsibility of the project consuming it to configure the Logging providers like it is done OOTB by ASP.NET Generic Host in DotNet Core Apps.使用它的项目有责任配置日志提供程序,就像由 DotNet Core Apps 中的 ASP.NET 通用主机完成的 OOTB 一样。 In case some one forgets to do it it won't throw an error(DI resolution error) as default value is null.如果有人忘记这样做,它不会抛出错误(DI 解析错误),因为默认值为 null。

Be sure to use it like logger?.LogDebug() with null check.确保像logger?.LogDebug()一样使用它并进行空检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM