asp.net core 3.1 日志記錄 Logging


Ilogger:包括實際執行記錄日志操作的方法。
IloggerProvider:用於創建 ILogger 對象。
IloggerFactory:通過 ILoggerProvider 對象創建 ILogger 對象。

ILogger接口

要記錄日志,需要使用 ILogger 接口

public interface ILogger
{
	//開始邏輯操作范圍。
	IDisposable BeginScope<TState>(TState state);
	//檢查是否已啟用給定 logLevel。
	bool IsEnabled(LogLevel logLevel);
	//寫入日志項。
	void Log<TState> (Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId 		eventId, TState state, Exception exception, Func<TState,Exception,string> formatter);
}

日志級別

Log 方法的第一個參數指明了這條信息的級別,日志級別即其重要程度。ASP.NET Core 日志系統定義了 6 個級別

LogLevel “值” 方法 描述
Trace 0 LogTrace 包含最詳細的消息。 這些消息可能包含敏感的應用數據。 這些消息默認情況下處於禁用狀態,並且不應在生產中啟用。
調試 1 LogDebug 用於調試和開發。 由於量大,請在生產中小心使用。
信息 2 LogInformation 跟蹤應用的常規流。 可能具有長期值。
警告 3 LogWarning 對於異常事件或意外事件。 通常包括不會導致應用失敗的錯誤或情況。
錯誤 4 LogError 表示無法處理的錯誤和異常。 這些消息表示當前操作或請求失敗,而不是整個應用失敗。
嚴重 5 LogCritical 需要立即關注的失敗。 例如數據丟失、磁盤空間不足。
6 指定日志記錄類別不應寫入任何消息。

​ 除了指定日志級別以外,還需要指定 EventId、一個返回值類型為字符串的委托,該委托的意義在於根據指定的狀態以及異常返回要輸出的日志信息。從上面的代碼中可以看出,直接使用 Log 方法來記錄日志會非常麻煩。為此 ILogger 接口提供了若干個擴展方法,用來更方便地記錄指定級別的日志,它們包括 LogTrace、LogDebug、LogInformation、LogWarning、LogError 和 LogCritical,這幾個方法分別對應上面所提到的各個級別。因此,上面的代碼可以改寫為:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }
    
    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

在Startup記錄日志

​ 當 ASP.NET Core 應用程序運行時,日志組件會被添加到其依賴注入容器中,因此只要在合適的位置將 ILogger 對象注入進來,即可使用它來記錄日志。

public class Startup
{
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
    {
                app.Run(async (context) =>
                {
                    logger.LogInformation("這是一條測試日志");
                    await context.Response.WriteAsync("Hello, world");
                });
    }
}

在 Startup 類的 Configure 方法中,通過方法注入將ILogger<Startup> 作為該方法的參數注入進來

​ ILogger 接口有一個派生接口 ILogger<out TCategoryName>,其中泛型類型 TCategoryName 表示日志類別名稱,它可以是任何類型,通常情況下,它的值應為當前所在類,如上面的 Startup 類。當注入 ILogger 時,必須為其指定泛型類型。

日志事件 ID

​ 在日志的輸出結果中,日志類別后有一個用中括號括起來的數字,該數字為事件標識符(Event Id) ,它的值是一個數字,默認值為 0。合理地使用這個數字能夠幫助開發者對日志進一步分類,比如,某種操作的 Id 是1000,另一類操作的 Id 是 1002。注意,Event Id 的顯示格式由 Provider定義,上述顯示形式是由 ConsoleProvider(即控制台日志提供程序)定義的;在其他 Provider 中則不然,例如,DebugProvider 不顯示 Event Id。要設置 Event Id,我們只要使用 LogInformation 方法的另一個重載形式即可。

每個日志都可指定一個事件 ID 。 示例應用使用 MyLogEvents 類來定義事件 ID:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

​ 事件 ID 與一組事件相關聯。 例如,與在頁面上顯示項列表相關的所有日志可能是 1001。

​ 日志記錄提供程序可將事件 ID 存儲在 ID 字段中,存儲在日志記錄消息中,或者不進行存儲。 調試提供程序不顯示事件 ID。 控制台提供程序在類別后的括號中顯示事件 ID:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

一些日志記錄提供程序將事件 ID 存儲在一個字段中,該字段允許對 ID 進行篩選。

內置日志記錄提供程序

public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
	var builder = new WebHostBuilder();
	…
    builder.ConfigureLogging((hostingContext, logging) =>
    {
        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
        logging.AddConsole();
        logging.AddDebug();
        logging.AddEventSourceLogger();
    })
	…
}

​ CreateDefaultBuilder 方法默認添加了 3 個日志提供程序,如果不需要默認所添加的這些日志提供程序,可以調用 ILoggerProvider 接口的 ClearProviders 方法,然后再添加所需要的日志提供程序。

  • 控制台
    向控制台窗口輸出日志
  • 調試
    向開發環境(IDE)的調試窗口輸出日志,它會調用System.Diagnostics.Debug 類的 WriteLine 方法向外輸出。
  • EventSource
    向事件跟蹤器輸出日志。
  • EventLog
    向 Window Event Log 輸出日志,僅支持 Windows 操作系統。
  • AzureAppServicesFile 和 AzureAppServicesBlob
    僅在 Azure 中使用,當應用程序部署到 Azure Web服務中后, Azure App Service 日志提供程序自動會添加進來。
  • ApplicationInsights
    提供程序包將日志寫入 Azure Application Insights。 Application Insights 是一項服務,可監視 Web 應用並提供用於查詢和分析遙測數據的工具。 如果使用此提供程序,則可以使用 Application Insights 工具來查詢和分析日志。

​ 與 ILoggingBuilder 一樣,ILoggerFactory 在添加 ASP.NET Core 內置的日志提供程序時,也可以使用 AddConsole 和 AddDebug 等擴展方法來添加日志提供程序。

第三方日志記錄提供程序

適用於 ASP.NET Core 的第三方日志記錄框架:

某些第三方框架可以執行語義日志記錄(又稱結構化日志記錄)

使用第三方框架類似於使用以下內置提供程序之一:

  1. 將 NuGet 包添加到你的項目。
  2. 調用日志記錄框架提供的 ILoggerFactory 擴展方法。

有關詳細信息,請參閱各提供程序的相關文檔。 Microsoft 不支持第三方日志記錄提供程序。

ILoggerFactory

ILoggerFactory 接口用於創建 ILogger 類型的對象。

public interface ILoggerFactory : IDisposable
{
    //將 ILoggerProvider 添加到日志記錄系統。
	void AddProvider(ILoggerProvider provider);
	//創建一個新的 ILogger 實例。該方法的參數 categoryName 為類日志的類別名稱,它主要用來為日志指定分類名稱
	ILogger CreateLogger(string categoryName);
}

要顯式指定類別,請調用 ILoggerFactory.CreateLogger

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }
}

分組和過濾

分組

參考:日志作用域

​ 對於一組邏輯上相關的操作,將其日志信息分為一組是很有意義的,這需要使用 Scope 來實現。ILogger 接口有一個方法即BeginScope<TState>(TState state)用於創建 Scope,其中 TState 指明要創建 Scope 的標識符,它可以為任何類型的數據,一般情況下,使用字符串來指明。BeginScope<TState> 方法的返回值類型為 IDisposable,因此可以使用 using 語句塊來創建 Scope,代碼如下所示。

using (logger.BeginScope("獲取數據"))
{
    logger.LogInformation("准備獲取數據");
    …
    if (data == null)
    {
    logger.LogError("數據不存在");
    }
}

​ 要在 Scope 中輸出日志,除了需要創建 Scope 外,還要在ILoggerProvider 對象中啟用這一功能。在添加日志提供程序時可以指定該ILoggerProvider 的一些選項。

​ 例如,對於 ControlProvider,只要設置ConsoleLoggerOptions 的 IncludeScopes 屬性為 true,即可為其啟用Scope 功能,它的默認值為 false。

1.下列代碼為控制台提供程序啟用作用域:

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.ClearProviders();
                //ConsoleLoggerOptions的 IncludeScopes = true
                logging.AddConsole(options => options.IncludeScopes = true); 
                logging.AddDebug();
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

2.【推薦】以下 JSON 為控制台提供程序啟用范圍:

{
  "Logging": {
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "IncludeScopes": true, // Required to use Scopes.
      "LogLevel": {
        "Microsoft": "Warning",
        "Default": "Information"
      }
    },
    "LogLevel": {
      "Default": "Debug"
    }
  }
}

輸出

info: LoggingTest.Startup[0]
        => 獲取數據
        准備獲取數據
fail: LoggingTest.Startup[0]
        => 獲取數據
        數據不存在

過濾

​ 可以通過設置最低日志級別來進行日志過濾,當這樣設置后,所有低於指定日志級別的日志都不會被處理,也不會顯示。例如,如果設置最低日志級別為 LogLevel.Information,那么 Debug 和 Trace 級別的日志都不會顯示。

1.SetMinimumLevel

​ 要設置最低日志級別,同樣需要在 ConfigureLogging 方法中進行配置,此時只要調用 ILoggingBuilder 接口的 SetMinimumLevel 方法即可。

Host.CreateDefaultBuilder(args)
.ConfigureLogging(builder =>
{
builder.ClearProviders();
builder.AddConsole(loggerOptions => loggerOptions.IncludeScopes = true);
builder.SetMinimumLevel(LogLevel.Information);
})
.UseStartup<Startup>();

LogLevel.None

​ 除了之前提到的那些級別以外,還有一個值是 None,該值高於其他所有值。如果指定這個值為最低級別,那么所有的日志都不會輸出。

2.AddFilter

​ 除了設置最低日志級別外,ILoggerBuilder 接口還提供了 AddFilter 方法,該方法包括多個重載,它能夠指定更復雜的條件,並只顯示滿足條件的日志。在以下方法中,將顯示 LoggeringTest.Startup 類別中,等於並高於Information 級別的日志。

Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
    logging.AddConsole().AddFilter("LoggingTest.Startup", LogLevel.Information);
})

加載JSON的Logging配置

​ 默認情況下,在 appsettings.json 文件中包含了對日志的配置信息,要將日志配置加載並應用到程序的日志系統中,可以調用AddConfiguration 方法

Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) =>
{
    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
...
})
.UseStartup<Startup>();

​ 在 appsettings.json 配置文件的「Logging」一節則默認包含了關於記錄日志的統一配置,如 LogLevel 配置項用於設置對指定類別的日志的最低輸出級別,凡是在該類別中低於指定級別的日志將不會被輸出。除了設置統一配置外,還可以為每一種日志提供程序提供具體的輸出配置,只要在「Logging」一節為其增加相應的配置即可,如下例添加了對 Console 類型日志提供程序的配置。

{
    "Logging": {
            "Console": {
                "IncludeScopes": true,
                "LogLevel": {
                "Microsoft.AspNetCore.Mvc.Razor": "Error",
                "Default": "Information"
                }
            },
            "LogLevel": {
                "Default": "Debug"
            }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM