.NET Core 和 ASP.NET Core 中的日誌框架

前言:

本文使用的 .NET Core SDK 3.1 版本。
本文將主要介紹ASP.NET Core自帶的日誌 Microsoft.Extensions.Logging 程序包的使用,
主要演示如何在 ASP.NET Core Web 應用程序控制檯應用程序 中使用 Microsoft.Extensions.Logging 程序包。

首先我創建了兩個項目,一個 ASP.NET Core Web 應用程序 ,另一個是 .NET Core 的 控制檯應用程序
由於ASP.NET Core Web 框架已經自帶了日誌包,所以不用再引入。
在控制檯應用程序中引入如下包:

	PM> Install-Package Microsoft.Extensions.Configuration.Json -Version 3.1.2
	PM> Install-Package Microsoft.Extensions.Logging -Version 3.1.2
	PM> Install-Package Microsoft.Extensions.Logging.Console -Version 3.1.2
	PM> Install-Package Microsoft.Extensions.Logging.Debug -Version 3.1.2
	PM> Install-Package Microsoft.Extensions.Logging.EventLog -Version 3.1.2

其中 Microsoft.Extensions.Logging 和核心包,Console 是在控制檯中顯示日誌記錄的包,
剩餘的 Debug 可以在Visual Studio中的輸出欄中顯示日誌記錄,EventLog 可以將日誌記錄到系統(Windows)的日誌記錄中。

日誌消息模板:
推薦使用日誌模板 logger.LogInformation("Getting item {Id}", 1);,日誌模板在不輸出時將不會消耗字符串拼接的資源。

一、在控制檯應用程序中使用日誌框架

以下介紹控制檯應用程序中使用日誌框架

1) 日誌的簡單使用

首先上代碼:

#region Main Function
	// 創建日誌工廠對象
    var loggerFactory = LoggerFactory.Create(builder =>
    {
        builder
            .AddFilter("ConsoleLoggingTest.Program", LogLevel.Warning)
            .AddFilter((provider, category, logLevel) =>
            {
                if (provider == "Microsoft.Extensions.Logging.Console" && 
                	logLevel == LogLevel.Warning)
                {
                    return false;
                }
                return true;
            })
            .AddConsole(configure => { configure.IncludeScopes = true; })
            .AddDebug()
            .AddEventLog();
    });
    // 創建 Logger 對象
    var logger_1 = loggerFactory.CreateLogger("ConsoleLoggingTest.Program");
    var logger_2 = new Logger<Program>(loggerFactory);
    // 記錄日誌
	logger_1.LogInformation(eventId: 1, message: "info log");
    logger_1.LogWarning(2, "warn log");
    var ex = new Exception("error log");
    logger_1.LogError(3, ex, "warn log");
    // 記錄日誌-作用域
    using (logger_2.BeginScope("ScopeId: {scopeId}", Guid.NewGuid()))
    {
        logger_2.LogInformation("LogInformation");
        logger_2.LogWarning("LogInformation");
        logger_2.LogError("LogInformation");
    }
#endregion

我們先直接運行看一下,控制檯得到的結果是:
日誌簡單使用Img

在以上代碼中,我們首先使用了 LoggerFactory.Create() 方法進行創建LoggerFactory實例,
並用 ILoggingBuilderLoggerFactory進行進行了配置,
其中配置的內容有:
     1. 使用 ILoggingBuilder.AddFilter() 配置日誌過濾添加到工廠,對名爲 ConsoleLoggingTest.Program 的日誌進行過濾,只記錄日誌等級大於等於LogLevel.Warning的日誌。
     2. 使用 ILoggingBuilder.AddConsole() 配置控制檯記錄添加到工廠,配置後將能在控制檯看到日誌的記錄。
     3. 使用 ILoggingBuilder.AddDebug() 配置調試記錄添加到工廠,配置後將能夠在調試時在Visual Studio的Debug窗口看到日誌。
     4. 使用 ILoggingBuilder.AddEventLog() 配置事件記錄添加到工廠,配置後能夠在系統(Windows)的系統日誌中看到,Linux本人沒有測試。

然後創建了兩個Logger對象,我當前 Main函數 所在的 Program 類的 namespaceConsoleLoggingTest
所以在這裏 logger_1 和 logger_2 兩個不同的寫法,其實他們是一樣的,
如果你開了 反編譯源碼,跟蹤進 loggerFactory.CreateLogger 你會發現返回的其實還是一個 new Logger<T> 實例。

隨後是記錄日誌,
記錄日誌時,message 參數是主要參數,還可以選填 eventId 對日誌進行標註快速定位到日誌的位置。
由於設置了 ConsoleLoggingTest.Program 的記錄的日誌等級不能小於 LogLevel.Warning,所以我們看不到內容爲 info log 的日誌。

隨後是日誌的作用域,
我們用日誌的作用域可以清楚的在日誌中找到關聯的上下文,不會和其他的日誌混淆。

2) 日誌與容器提供程序結合使用

首先上代碼:

#region appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "Console": {
      "LogLevel": {
        "Default": "Information",
        "ConsoleLoggingTest.Program": "Warning"
      }
    }
  }
}
#endregion

#region MyService
    public class MyService
    {
        ILogger<MyService> _logger_1;
        ILogger _logger_2;

        public MyService(ILogger<MyService> logger, ILoggerFactory loggerFactory)
        {
            _logger_1 = logger;
            _logger_2 = loggerFactory.CreateLogger("loggerFactoryTest"); ;
        }

        public void Show()
        {
            _logger_1.LogInformation("Show _logger_1");
            _logger_2.LogInformation("Show _logger_2");
        }
    }
#endregion

#region Main Function
    // 從文件中讀取配置
    IConfigurationBuilder configBuilder = new ConfigurationBuilder();
    configBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    var config = configBuilder.Build();
    
    // 構造一個容器
    IServiceCollection serviceCollection = new ServiceCollection();
    //用工廠模式注入將配置對象註冊到容器管理
    serviceCollection.AddSingleton<IConfiguration>(p => config);
    // 將實例直接注入進去,容器將不會管理 config 的生命週期
    // serviceCollection.AddSingleton<IConfiguration>(config);
    
    // 日誌記錄服務添加到容器管理
    serviceCollection.AddLogging(builder =>
    {
        builder.AddConfiguration(config.GetSection("Logging"));
        builder.AddConsole();
    });
    
    serviceCollection.AddTransient<MyService>();
    // 將容器 Build 出來
    IServiceProvider service = serviceCollection.BuildServiceProvider();
    var order = service.GetService<MyService>();
    order.Show();
    
    var logger_1 = service.GetService<ILogger<Program>>();
    ILoggerFactory loggerFactory = service.GetService<ILoggerFactory>();
    var logger_2 = loggerFactory.CreateLogger<Program>();
    var logger_3 = loggerFactory.CreateLogger("ConsoleLoggingTest.Program");
    
    logger_1.LogInformation("log logger_1");
    logger_1.LogWarning("log logger_1");
    logger_2.LogInformation("log logger_2");
    logger_2.LogWarning("log logger_1");
    logger_3.LogInformation("log logger_3");
    logger_3.LogWarning("log logger_1");
#endregion

我們先直接運行看一下,控制檯得到的結果是:
日誌與容器提供程序結合使用Img
我們直接看 Main函數 的代碼,
在前三行中我們從文件中讀取配置,隨後的代碼構建一個容器並將配置注入進容器。

然後將日誌記錄添加到容器管理
使用 IServiceCollection.AddLogging() 將日誌添加到容器,並對容器進行配置,
     1. 使用 AddConfiguration() 方法給日誌添加配置,指定的是配置的根節點下面的Logging節點。
     2. 使用 AddConsole() 方法將使得日誌能夠在控制檯進行展示。

然後我們將事先已經寫好的 MyService 注入到容器中,並將容器 Build 出來,
隨後用容器創建一個 MyService ,並直接調用 show() 方法,我們可以在 MyService 中看到如何使用以來注入來實例創建日誌對象。

隨後直接通過容器創建了日誌對象,並打印日誌,在打印的日誌中我們可以看到,
由於我們給日誌添加了 "ConsoleLoggingTest.Program": "Warning" 配置, LogInformation 並沒有打印出來。

二、在 ASP.NET Core Web 應用程序中使用日誌框架

在Web程序中使用日誌框架

#region
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                // 刪除所有的日誌提供程序
                logging.ClearProviders();
                logging.AddConsole(options => options.IncludeScopes = true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
#endregion

在Web程序中使用日誌框架時,如果我們不想用默認配置,可以使用 ClearProviders() 方法使之前的所有配置都失效。
然後在後面自定義配置,如代碼,我啓動控制檯記錄器並開啓基於作用域的日誌記錄。
在使用時,

#region MyService
    public class MyService
    {
        ILogger<MyService> _logger_1;
        ILogger _logger_2;

        public MyService(ILogger<MyService> logger, ILoggerFactory loggerFactory)
        {
            _logger_1 = logger;
            _logger_2 = loggerFactory.CreateLogger("loggerFactoryTest"); ;
        }

        public void Show()
        {
            _logger_1.LogInformation("Show _logger_1");
            _logger_2.LogInformation("Show _logger_2");
        }
    }
#endregion


參考文檔

.NET Core 和 ASP.NET Core 中的日誌記錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章