.NET Core3.0 日誌 logging

  • 2019 年 10 月 31 日
  • 筆記

多年的經驗,日誌記錄是軟體開發的重要組成部分。沒有日誌記錄機制的系統不是完善的系統。在開發階段可以通過debug附件進程進行交互調試,可以檢測到一些問題,但是在上線之後,日誌的記錄起到至關重要的作用。它可使我們在系統出現問題之後,排查錯誤提供依據。

.NET Core3.0內置多種日誌記錄程式,並且有第三方提供的日誌記錄程式框架如:log4net,NLog,Serilog,elmah.io等。後面會介紹前三種日誌框架如何與.NETcore3.0結合起來進行使用。

內置日誌記錄提供程式

ASP.NET Core 提供以下提供程式:

  • 控制台-可以在控制台查看日誌輸出

  • 調試-vs工具 -》開始調試-》輸出窗口進行查看日誌輸出

  • EventSource-可使用PerfView 實用工具收集和查看日誌

  • EventLog-》僅在windows系統下可以使用事件查看器查看日誌

  • TraceSource

  • AzureAppServicesFile

  • AzureAppServicesBlob

  • ApplicationInsights

創建使用日誌

通用主機的應用程式和非主機應用程式使用的方式也是不同的。因為通用主機內部封裝了 依賴注入、logging、配置、IHostedService的實現;並且默認配置了控制台,調試,EventSource以及EventLog(僅當在windows上運行時)提供程式。源碼如下

.ConfigureLogging((hostingContext, logging) =>              {                  var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);                    // IMPORTANT: This needs to be added *before* configuration is loaded, this lets                  // the defaults be overridden by the configuration.                  if (isWindows)                  {                      // Default the EventLogLoggerProvider to warning or above                      logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);                  }                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));                  logging.AddConsole();                  logging.AddDebug();                  logging.AddEventSourceLogger();                    if (isWindows)                  {                      // Add the EventLogLoggerProvider on windows machines                      logging.AddEventLog();                  }              })

  • 通用主機

添加提供程式

可自行選擇提供程式來替換默認提供程式。在CreateHostBuilder時候 調用ClearProviders(),然後添加所需的提供程式。我們創建一個api項目為例

public static IHostBuilder CreateHostBuilder(string[] args) =>              Host.CreateDefaultBuilder(args)                   .ConfigureLogging(logging =>                   {                       logging.ClearProviders();//去掉默認添加的日誌提供程式                       logging.AddConsole();                       logging.AddDebug();                       logging.AddEventSourceLogger();                       logging.AddEventLog();                       //logging.AddTraceSource();                     })                  .ConfigureWebHostDefaults(webBuilder =>                  {                      webBuilder.UseStartup<Startup>();                  })

創建日誌

在 Web 應用或託管服務中,由依賴關係注入 (DI) 獲取 ILogger。

private readonly ILogger<WeatherForecastController> _logger;          public WeatherForecastController(ILogger<WeatherForecastController> logger)          {              _logger = logger;                //可以顯示指定類別名稱ILoggerFactory logger              //logger.CreateLogger("WebApi.Controllers.WeatherForecastController");          }

[HttpGet]          public IEnumerable<WeatherForecast> Get()          {              //內置日誌              _logger.LogTrace(1000, "log Trace msg");  //              _logger.LogDebug(1001, "log Debug msg"); //              _logger.LogInformation(1002, "log Information msg"); //              _logger.LogWarning(1003, "log Warning msg"); //              _logger.LogError(1004, "log Error msg"); //              _logger.LogCritical(1005, "log Critical msg"); //

各個端的運行輸出:

  • 非主機控制台

添加提供程式

在創建 LoggerFactory 時調用提供程式的 Add{provider name} 擴展方法:

 

var loggerFactory = LoggerFactory.Create(builder =>  {      builder          .AddFilter("Microsoft", LogLevel.Warning)          .AddFilter("System", LogLevel.Warning)          .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)          .AddConsole()          .AddEventLog();  });

創建日誌

在非主機控制台應用中,使用 LoggerFactory 來創建 ILogger。

ILogger logger = loggerFactory.CreateLogger<Program>();  logger.LogInformation("非主機模式輸出log message");

運行輸出

第三方日誌框架

log4net,NLog和Serilog這3種日誌記錄框架幾乎在.NET空間中佔主導地位,不需要太多介紹。看看最近6周的下載排名就知道了。如圖

log4net 在NET Core 3.0使用

引用Log4net到項目中,安裝NuGet包

Install-Package log4net -Version 2.0.8

在項目中添加log4net.config文件,右鍵改文件屬性-》複製到輸出目錄選擇-》始終複製
<log4net>    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">      <file value="loglog4net.log" />      <appendToFile value="true" />      <maximumFileSize value="50KB" />      <maxSizeRollBackups value="2" />        <layout type="log4net.Layout.PatternLayout">        <conversionPattern value="%date %level %message%newline" />      </layout>    </appender>      <root>      <level value="ALL" />      <appender-ref ref="RollingFile" />    </root>  </log4net>

在Startup文件中添加log4net配置的文件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)          {              if (env.IsDevelopment())              {                  app.UseDeveloperExceptionPage();              }              app.UseLog4net();     /// <summary>          /// 使用log4net配置          /// </summary>          /// <param name="app"></param>          /// <returns></returns>          public static IApplicationBuilder UseLog4net(this IApplicationBuilder app)          {              var logRepository = log4net.LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));              log4net.Config.XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config"));              return app;          }  上面兩步的準備完成之後,在Controllers中使用   private readonly ILog log;          public WeatherForecastController(ILogger<WeatherForecastController> logger)          {              this.log = LogManager.GetLogger(typeof(WeatherForecastController));          } [HttpGet]          public IEnumerable<WeatherForecast> Get()          {              //第三方日誌              log.Error("log4net erro msg"); //log4net

運行查看日誌文件

NLog 在NET Core 3.0使用

引用NLog到項目中,安裝NuGet包

Install-Package NLog.Web.AspNetCore -Version 4.9.0  Install-Package NLog -Version 4.6.7

添加配置文件nlog.config
<?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"        autoReload="true"        internalLogLevel="Info"        internalLogFile="internal-nlog.txt">      <!-- enable asp.net core layout renderers -->    <extensions>      <add assembly="NLog.Web.AspNetCore"/>    </extensions>      <!-- the targets to write to -->    <targets>      <!-- write logs to file  -->      <target xsi:type="File" name="allfile" fileName="nlog-all-${shortdate}.log"              layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />        <!-- another file log, only own logs. Uses some ASP.NET core renderers -->      <target xsi:type="File" name="ownFile-web" fileName="nlog-own-${shortdate}.log"              layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />    </targets>      <!-- rules to map from logger name to target -->    <rules>      <!--All logs, including from Microsoft-->      <logger name="*" minlevel="Trace" writeTo="allfile" />        <!--Skip non-critical Microsoft logs and so log only own logs-->      <logger name="Microsoft.*" maxlevel="Info" final="true" />      <!-- BlackHole without writeTo -->      <logger name="*" minlevel="Trace" writeTo="ownFile-web" />    </rules>  </nlog>

在Program.cs文件配置 Main方法添加
NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();

CreateHostBuilder方法添加

 .UseNLog() //NLog: Setup NLog for Dependency injection

使用  

[HttpGet]          public IEnumerable<WeatherForecast> Get()          {              //內置日誌              _logger.LogTrace(1000, "log Trace msg");  //              _logger.LogDebug(1001, "log Debug msg"); //              _logger.LogInformation(1002, "log Information msg"); //              _logger.LogWarning(1003, "log Warning msg"); //              _logger.LogError(1004, "log Error msg"); //              _logger.LogCritical(1005, "log Critical msg"); //

輸出

Serilog 在NET Core 3.0使用

引用Serilog到項目中,安裝NuGet包

Install-Package Serilog.AspNetCore -Version 3.1.0

在Program.cs文件進行Logger 初始化

Main方法添加

Log.Logger = new LoggerConfiguration()                  .Enrich.FromLogContext()                  .WriteTo.Console()// 配置日誌輸出到控制台                  .WriteTo.File("logserilog.txt", rollingInterval: RollingInterval.Day) //配置日誌輸出文件,生成周期每天                  .CreateLogger();              try              {                  Log.Information("Starting up");                  CreateHostBuilder(args).Build().Run();              }              catch (Exception ex)              {                  Log.Fatal(ex, "Application start-up failed");              }              finally              {                  Log.CloseAndFlush();              }

 將Serilog設置為日誌提供程式,只需在CreateHostBuilder方法後添加一句
 .UseSerilog();

注入logger到你的controllers
public WeatherForecastController(ILogger<WeatherForecastController> logger)          {              _logger = logger;//默認          [HttpGet]          public IEnumerable<WeatherForecast> Get()          {              //內置日誌              _logger.LogTrace(1000, "log Trace msg");  //              _logger.LogDebug(1001, "log Debug msg"); //              _logger.LogInformation(1002, "log Information msg"); //              _logger.LogWarning(1003, "log Warning msg"); //              _logger.LogError(1004, "log Error msg"); //              _logger.LogCritical(1005, "log Critical msg"); //

運行輸出:

小結:本文主要講解NET Core3.0內置的日誌提供程式和與第三方日誌框架(Log4net,Nlog,Serilog)的使用。