1. 程式人生 > 實用技巧 >.NET Core3.0 日誌 logging-最好用的日誌集合介紹

.NET Core3.0 日誌 logging-最好用的日誌集合介紹

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

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

內建日誌記錄提供程式

ASP.NETCore 提供以下提供程式:

  • 控制檯-可以在控制檯檢視日誌輸出

  • 除錯-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)的使用。