.NET Core Logging Api 基础知识

.NET Core SDK 是一个轻量级 SDK,它包含构建应用程序所需的一组最少的功能。我们可以为应用程序所需的其他功能安装 NuGet 软件包。为此,Microsoft 提供 .NET API 作为 .NET 扩展(.NET Extensions)。

.NET 扩展(.NET Extensions)是一组开源的跨平台 API,用于常见的编程模式和实用程序,如依赖注入、日志记录和应用程序配置。本项目中的大多数 API 都适用于许多 .NET 平台,如 .NET Core、.NET Framework、Xamarin 等。虽然在 ASP.NET Core 应用程序,这些 API 没有耦合到 ASP.NET Core 应用模型。它们可以在控制台应用程序、WinForms 和 WPF 等中使用。

所有扩展都包含在 Microsoft.Extensions 命名空间下。您可以在 nuget.org/packages 中找到所有内置和第三方扩展。

Logging API(日志 Api)包含在 Microsoft.Extensions.Logging 包中。Logging API 不能独立工作。它与一个或多个 Logging 提供程序一起使用,这些日志提供程序将日志存储或显示到特定介质,如 ConsoleDebugTraceListeners 等。

因此,在基于 .NET Core 的应用程序中实现日志记录有两个重要的构建块:

  • 日志 API(Logging API)
  • 日志记录提供程序(Logging Providers)

下图阐述了 .NET Core 日志:

如上图所示,Microsoft.Extensions.Logging 中的日志 API 适用于基于.NET Core 的应用程序,无论是 ASP.NET Core 或 EF 核心。您只需将日志 API 与一个或多个日志提供程序一起使用,即可在任何基于 .NET Core 的应用程序中实现日志记录。


日志 API

如前所述,Microsoft 在 Microsoft.Extensions.Logging(作为 NuGet 包提供)包中提供了日志 API 作为扩展。

Microsoft.Extensions.Logging 包括日志记录所需的类和接口。最重要的是 ILoggerILoggerFactoryILogger Provider 接口和 LoggerFactory 类。

下图显示了日志类之间的关系。

让我们概括一下上面的每一个类。


ILoggerFactory

ILoggerFactory 是用于创建适当的 ILogger 类型实例以及添加 ILoggerProvider 实例的工厂接口。

  1. public interface ILoggerFactory : IDisposable
  2. {
  3. ILogger CreateLogger(string categoryName);
  4. void AddProvider(ILoggerProvider provider);
  5. }

Logging API 包括实现 ILoggerFactory 接口的内置 LoggerFactory 类。我们可以使用它添加 ILoggerProvider 类型的实例,并检索指定类别的 ILogger 实例。有关详细信息,请访问 ILoggerFactoryLoggerFactory


ILoggerProvider

ILoggerProvider 管理并创建由日志类别指定的适当日志。

  1. public interface ILoggerProvider : IDisposable
  2. {
  3. ILogger CreateLogger(string categoryName);
  4. }

我们可以通过实现 ILoggerProvider 接口来创建自己的日志记录提供程序。有关详细信息,请访问 ILoggerProvider


ILogger

ILogger 接口包括用于记录到底层存储的方法。有许多扩展方法使日志记录变得容易。有关更多信息,请访问 ILogger

  1. public interface ILogger
  2. {
  3. void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter);
  4. bool IsEnabled(LogLevel logLevel);
  5. IDisposable BeginScope<TState>(TState state);
  6. }

Logging Providers

Logging Providers 日志记录提供程序将日志显示或存储到特定介质,例如控制台、调试事件、事件日志、跟踪侦听器等。 Microsoft 提供各种日志记录提供程序作为 NuGet 包。

下表列出了重要的日志记录提供程序。

Logging Provider 的 NuGet 包输出目标
Microsoft.Extensions.Logging.Console Console
Microsoft.Extensions.Logging.AzureAppServicesAzure App Services 'Diagnostics logs' and 'Log stream' features
Microsoft.Extensions.Logging.DebugDebugger Monitor
Microsoft.Extensions.Logging.EventLog Windows Event Log
Microsoft.Extensions.Logging.EventSource EventSource/EventListener
Microsoft.Extensions.Logging.TraceSourceTrace Listener

Microsoft 还与各种日志框架团队(包括 NLogSerilogLoggrLog4Net 等第三方)合作,以扩展与 Microsoft.Extension.logging 兼容的提供程序列表。以下是一些第三方日志记录提供程序:

日志记录提供程序描述
elmah.io Provider for the Elmah.Io service
Loggr Provider for the Logger service
NLog Provider for the NLog library
Serilog Provider for the Serilog library

让我们以 Microsoft.Extension.Logging.Console 包为例,它在 Console 上显示日志。


Console Logging Provider

让我们看看如何使用控制台提供程序的 NuGet 包在控制台上显示日志。

Microsoft.Extensions.Logging.Console 包包含将日志输出发送到控制台的日志类。

下图说明了日志 API 如何与控制台日志提供程序一起工作。

如上图所示,ConsoleLogger 实现了 ILogger,而 ConsoleLoggingProvider 实现了 ILloggingProviderConsoleLoggerExtensions 类包括扩展方法 AddConsole(),它将控制台记录器添加到 LoggerFactory

现在,让我们看看如何在 .NET Core 控制台应用程序中的控制台上显示日志。

首先,在 Visual Studio 2019(或更高版本)中使用 Console App(.NET Core)模板创建新的控制台应用程序。

现在,您需要安装 Microsoft.Extensions.Logging 的 NuGet 包。您可以使用 NuGet Package Manager 或在 Package Manager 控制台中执行以下命令来安装它。

PM> Install-Package Microsoft.Extensions.Logging

现在,您需要安装自己选择的日志记录提供程序。在这里,我们将在控制台上发送日志,因此,请安装 Microsoft.Extensions.Logging.Console 包可以使用 NPM,也可以在 Visual Studio 的包管理器控制台中执行以下命令。

PM> Install-Package Microsoft.Extensions.Logging.Console

成功安装以上两个包后,现在可以在 .NET Core 控制台应用程序中实现日志记录,如下所示。

  1. namespace DotnetCoreConsoleApp
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. ILoggerFactory loggerFactory = new LoggerFactory(
  8. new[] { new ConsoleLoggerProvider((_, __) => true, true) }
  9. );
  10. //or
  11. //ILoggerFactory loggerFactory = new LoggerFactory().AddConsole();
  12. ILogger logger = loggerFactory.CreateLogger<Program>();
  13. logger.LogInformation("This is log message.");
  14. }
  15. }
  16. }

结果为:

  1. info: DotnetCoreConsoleApp.Program[0]
  2. This is log message.

在上面的实例中,我们创建了 LoggerFactory 类的一个对象,并将其分配给 ILoggerFactory 类型变量,如下所示。

  1. ILoggerFactory loggerFactory = new LoggerFactory(
  2. new[] { new ConsoleLoggerProvider ((_, __) => true, true) }
  3. );

LoggerFactory 可以包含一个或多个日志记录提供程序,可用于同时记录到多个介质。 LoggerFactory 的构造函数接受不同记录器提供程序对象的数组作为 new[] { }。我们希望在控制台上显示日志,因此需要创建控制台记录器提供程序 ConsoleLoggerProvider 的对象。

ConsoleLoggerProvider 有 4 个构造函数。使用允许 lambda 表达式 (Func<>) 进行日志过滤和includeScope Boolean的表达式。这里,我们不想过滤任何信息,因此lambda表达式将始终返回 (, _) => true,如下所示。

  1. new ConsoleLoggerProvider((_, __) => true, true)

然后,我们可以使用 LoggerFactory 的这个对象来创建一个记录器,使用它我们可以实际记录信息、错误、警告、跟踪、调试等。LoggerFactory.CreateLogger<Program>() 创建特定于 Program 类 的记录器,以便记录器显示带有上下文信息的消息,例如 DotnetCoreConsoleApp.Program[0]

大多数日志记录提供程序都包含 ILoggerFactory 的扩展方法,这是将提供程序添加到日志记录程序工厂的快捷方式。例如,要向 LoggerFactory 添加控制台记录器提供程序,只需调用 LoggerFactory.AddConsole() 扩展方法,其参数与 ConsoleLoggerProvider 相同,如下所示。

  1. public ILoggerFactory loggerFactory = new LoggerFactory().AddConsole();

这比手动创建记录器提供程序更可读和可维护。上述记录器工厂将显示与上述相同的输出。


Log Levels(日志级别)

日志级别指示日志消息的重要性或严重性。内置日志提供程序包括用于指示日志级别的扩展方法。

下表列出了 .NET Core 中的日志级别。

日志级别严重程度扩展方法描述
Trace 0 LogTrace() 日志消息仅用于开发人员的跟踪目的。
Debug 1 LogDebug() 记录用于短期调试的消息。
Information 2 LogInformation() 记录应用程序流的消息。
Warning 3 LogWarning() 记录应用程序流中异常或意外事件的消息。
Error 4 LogError() 记录错误消息。
Critical 5 LogCritical() 记录需要立即注意的故障消息。

我们可以使用扩展方法来指示日志消息的级别,如下所示。

  1. namespace DotnetCoreConsoleApp
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. ILoggerFactory loggerFactory = new LoggerFactory().AddConsole((_, __) => true);
  8. ILogger logger = loggerFactory.CreateLogger<Program>();
  9. logger.LogInformation("Logging information.");
  10. logger.LogCritical("Logging critical information.");
  11. logger.LogDebug("Logging debug information.");
  12. logger.LogError("Logging error information.");
  13. logger.LogTrace("Logging trace");
  14. logger.LogWarning("Logging warning.");
  15. }
  16. }
  17. }

结果如下: