只有累積,沒有奇蹟

2019年3月8日 星期五

[.NETCore] ASP.NET Core - Logging 日誌初體驗 (二)

前言
在上一篇文章介紹了在 ASP.Net Core 如何使用內建的 logging,以及 ILogger 與 ILoggerFactory 還有篩選記錄的方法,這篇再繼續介紹在 logging 中一些基本觀念與應用,如果有寫不清楚的地方可以搭配 MSDN 官網的 ASP.NET Core logging 一起服用,若有問題歡迎提出一起討論或是給予指導

LogLevel
紀錄 log 時候都會指定紀錄的等級  LogLevel 在 ASP.NET Core 提供六個等級,每個等級都具有代表其意義,舉例來說在開發 API 接口時會使用 info 紀錄 Request 的參數資訊,找不到 id 資料時可能會用  warning 方法,當執行異常時會用 Error 記錄其 exception 內容;LogLevel 列舉如下
public enum LogLevel
{
    Trace = 0,
    Debug = 1,
    Information = 2,
    Warning = 3,
    Error = 4,
    Critical = 5, 
    None = 6
}
列舉值代表等級高越需要記錄 (除了 None ),MSDN 也有列出相關說明這裡就不在多介紹
舉個實際簡單的範例 API 應用,在下面範例中會建立 Information、Warning 與 Error紀錄
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
    _logger.LogInformation("輸入的參數 id : {id}", id);
    if (id == 0)
    {
        _logger.LogWarning("參數 id 為 0, 方法不支援也找不到資料唷");
    }

    try
    {
        // to do something
    }
    catch (Exception e)
    {
        _logger.LogError("發生異常 !");
    }
}

Configuration
介紹完 LogLevel 之後接著提到 logging 的設定,還記得在介紹要使用 Logging 時會在 configureServices 加上下列代碼  
builder.AddConfiguration(Configuration.GetSection("Logging"))
這裡的  "Logging"  讀取的設定檔內容來源之一是 appsettings.Development.json 設定的內容,檔案位置可以在 ASP.NET Core 專案檔根目錄找到,開啟檔案內容如下
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}
可以發現 Logging 底下有 Default、System、Microsoft 三個屬性,分別可以設定其對應的 LogLevel 紀錄層級,在上面介紹 LogLevel 時有提到每個層級都有對應自己的層級值,此設定值也會影響到寫到 output 視窗或是搭配 log 套件的紀錄數量,這句話有點抽象舉例會比較好懂。舉例來說當今天設定檔 LogLevel 設定 Information 時,會排除 Information 層級以下的紀錄層級比 information 低的 log 就不會出現,換句話說也就是不會輸出 Debug 和 trace 的 log 紀錄。
知道輸出層級會有影響我們可以直接改 LogLevel 設定看看兩者差異,或許會對上述說明更容易了解些。為了避免過多資訊影響到判斷,因此測試前先在 ConfigureServices 加上過濾掉 Microsoft Log 相關紀錄,讓輸出資料單純些
.AddFilter("Microsoft", LogLevel.Warning);
接著在到 ValueController 的建構子加上 debug 紀錄
public ValuesController(ILoggerFactory logger)
{
    _logger = logger.CreateLogger("MyDemoProject");
    _logger.LogDebug("ValuesController logger done");
} 
在 appsettings.json 預設 Default  LogLevel 是 debug 當測試時會輸出下列資料
NETCoreLogging> Now listening on: http://127.0.0.1:19603
NETCoreLogging> Application started. Press Ctrl+C to shut down.
NETCoreLogging> dbug: MyDemoProject[0]
NETCoreLogging>       ValuesController logger done
NETCoreLogging> dbug: MyDemoProject[0]
NETCoreLogging>       ValuesController logger done
NETCoreLogging> info: MyDemoProject[0]
NETCoreLogging>       輸入參數 id : 7777
NETCoreLogging> dbug: MyDemoProject[0]
NETCoreLogging>       To do something start 
可以看到輸出 LogLevel 包含了 dbug 和 info 紀錄資訊,接著我們調整 appsettings.Development.json 中的 Default LogLevel為 information,在重新看輸出
NETCoreLogging> Now listening on: http://127.0.0.1:23663
NETCoreLogging> Application started. Press Ctrl+C to shut down.
NETCoreLogging> info: MyDemoProject[0]
NETCoreLogging>       輸入參數 id : 7777 
從輸出 Log 可以發現 debug 的紀錄都消失了,驗證上述所說的,調整 LogLevel 為 information 之後會排除層級以下的紀錄並不會輸出。可以透過 json 設定在開發環境輸出較多 Log 資料方便 debug 使用;在正式環境時輸出必要的 Log 層級資訊。

載入 config
如果想確認專案啟動時 config 正常載入,可以再 Configuration.GetSection("Logging") 加上中斷點確認

EventID
在每次紀錄 log 時候可以記錄指定的   EventID ,可以從 ILogger 所提供的 API 看到 log.LoginInfomatrion 提供多載的方法可以傳入指定的 EventID 值,在輸出時會將 EventID 值帶到輸出的 ClassName 用括弧 [] 顯示事件代碼,以下範例是自訂 APILoggingEventID 與使用方式
public class APILoggingEventID
{
    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 GetItemNotFound = 4000;
    public const int UpdateItemNotFound = 4001;

    public const int GetDataFromThirdParty = 8001;
}

[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
    _logger.LogInformation(APILoggingEventID.GetItem, "輸入的參數 id : {id}", id);

    try
    {
        // to do something
        _logger.LogDebug(APILoggingEventID.GetDataFromThirdParty, "Json Text balala");
    }
    catch (Exception ex)
    {
        _logger.LogError(APILoggingEventID.GetItemNotFound, ex, "發生異常 ! GetById({ID}) NOT FOUND", id);
    }

    return "value";
}
測試完畢之後輸出結果如下,紀錄的都會加上 EventID 結果為  MyDemoProject[1000] 
NETCoreLogging> dbug: MyDemoProject[4000]
NETCoreLogging>       ValuesController logger done
NETCoreLogging> info: MyDemoProject[1002]
NETCoreLogging>       輸入參數 id : 7777
NETCoreLogging> dbug: MyDemoProject[8001]
NETCoreLogging>       Json Text balala

後記
分享了兩篇在介紹 .NET Core logging 機制與寫一些簡單的 Sample Code 說明使用方式,自己心得對於 logging 更加了解,提供統一撰寫日誌的機制且可以搭配第三方元件輸出使用上覺得蠻容易上手的,不用在 代碼中寫很多 log.info 之類的代碼,也可以讓代碼看起來更加乾淨與增加易讀性,這些都算是基礎且簡單的應用,之後若有遇到不錯的使用方式會在分享出來,也希望有錯誤或是更好的寫法歡迎給予指教,Happy Coding !!!

參考
ASP.NET Core 中的記錄
ASP.NET Core 源码学习之 Logging[1]:Introduction
.NET Core下的日志(1):记录日志信息
ASP.NET Core 所使用的 Logging


0 意見:

張貼留言

Copyright © m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com