只有累積,沒有奇蹟

2019年5月13日 星期一

[NETCore] 在 ASP.NET Core Web API 中使用 Serilog

前言
近期專案都在嘗試 Serilog,對於使用上有點小小心得,因此整理這篇文章分享 Serilog 在 ASP.NET Core API 上的使用與設定,也接續之前 Serilog 的系列介紹文 : 傳送門 的實際應用心得,希望可以幫到有需要的朋友若有問題或是錯誤的地方歡迎提出來一起討論或是給予指導

ASP.NET Core logging
首先先建立新的 ASP.NET Core Web Application 專案,開啟 Visual Studio 2019 選擇建立新專案,專案名稱輸入 SerilogWebAppLab,模板部分選擇 API,然後按下確定送出
新增完專案之後,可以看到專案中 program.cs 內建 CreateWebHostBuilder 方法,此方法會在 Application 啟動時,使用預設方法也會一併註冊內建 logging,接著我們來看一下內建 logging 輸出樣式,在 ValueController 中建構式加入 _Logger 並在 GET 方法中使用 log.Information、Warning 以及 Error
  1. public class ValuesController : ControllerBase
  2. {
  3. private readonly ILogger _logger;
  4.  
  5. public ValuesController(ILogger<ValuesController> logger)
  6. {
  7. _logger = logger;
  8. }
  9.  
  10. // GET api/values
  11. [HttpGet]
  12. public ActionResult<IEnumerable<string>> Get()
  13. {
  14. _logger.LogInformation("This is LogInformation");
  15. _logger.LogWarning("This is LogWarning");
  16. _logger.LogError("This is LogError");
  17.  
  18. return new[] { "value1", "value2" };
  19. }
  20. ...
執行專案按下 F5,輸出內容如下
從預設 logging 內容可以發現紀錄了除了自己紀錄的 log 之外資料,紀錄了 Application 以及 Request 的內容還有執行的時間,CreateWebHostBuilder 方法預設的情況下使用的 Config 為專案檔底下的 appsettings.json 及 appsettings.Development.json (依設定環境決定),之前有撰寫過一篇關於設定環境變數的文章,有興趣可以參考 : 傳送門。在此如果希望不啟用內建的 logging 紀錄資訊,可以在 CreateWebHostBuilder 方法中加上  config.ClearProviders()  刪除預設的 logging 提供者
  1. public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
  2. WebHost.CreateDefaultBuilder(args)
  3. .ConfigureLogging((hostingContext, config) =>
  4. {
  5. config.ClearProviders();
  6. })
  7. .UseStartup<Startup>();
在重新執行一次 Application,就會看到 Console output 僅剩三個 log。

Serilog
接著輪到今天的重頭戲 Serilog 登場,首先先透過 Nuget 下載 Serilog for .NET Core 套件
  1. Install-Package Serilog.AspNetCore
Serilog 核心負責紀錄 Log 事件的內容,要將 Log 輸出則是透過 Sink,如果想瞭解更多細節可以參考 結構化日誌 Serilog 初體驗,這裡就不在多加介紹,這裡範例是使用 Console 與寫入實體檔案作為輸出,因此需要另外透過 Nuget 下載相關套件 Sinks.Console 與 Sinks.File 兩種,如果有其他需
  1. Install-Package Serilog.Sinks.Console
  2. Install-Package Serilog.Sinks.File
下載完 Serilog 相關 Package,接著就是在 WebHost 啟動時設定 Serilog 資訊也就是 Program.cs 中的 main 方法加下以下代碼
  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. Log.Logger = new LoggerConfiguration()
  6. .MinimumLevel.Information()
  7. .WriteTo.Console()
  8. .WriteTo.File("logs/log_.txt", rollingInterval: RollingInterval.Day)
  9. .CreateLogger();
  10.  
  11. CreateWebHostBuilder(args).Build().Run();
  12. }
  13.  
  14. public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
  15. WebHost.CreateDefaultBuilder(args)
  16. .ConfigureLogging((hostingContext, config) =>
  17. {
  18. config.ClearProviders();
  19. })
  20. .UseStartup<Startup>();
  21. }
程式說明

  • MinimumLevel.Information : 定義 Log 輸出 Level 
  • WriteTo.Console : 設定使用 Console 輸出 
  • WriteTo.File : 設定使用 File 檔案輸出,輸出位置及檔名為 log & log_txt 
  • 上述是在 Program.cs 中加上 Serilog 設定組態設定,在 Serilog 中也支援使用 Config 檔案來設定的動作,如果想要透過定義檔則需要至 Nuget 下載 Settings library
    1. Install-Package Serilog.Settings.Configuration
    在 appSettings.json 加以下 config 定義內容,設定目的與內容與剛剛在 Program 寫 Log 方式相同
    1. {
    2. "Serilog": {
    3. "MinimumLevel": "Information",
    4. "WriteTo": [
    5. {
    6. "Name": "Console",
    7. "Args": {
    8. "outputTemplate": "{Timestamp:yyyy/MM/dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
    9. }
    10. },
    11. {
    12. "Name": "File",
    13. "Args": {
    14. "Path": "logs/log_.txt",
    15. "rollingInterval": "Day"
    16. }
    17. }
    18. ]
    19. }
    20. }
    在來修改 Program.cs 中的代碼,要調整新增 Configuration 時以檔案的內容為主
    1. public class Program
    2. {
    3. private static string _envName;
    4. public static void Main(string[] args)
    5. {
    6. var configuration = new ConfigurationBuilder()
    7. .SetBasePath(Directory.GetCurrentDirectory())
    8. .AddJsonFile("appsettings.json")
    9. .AddJsonFile($"appsettings.{_envName}.json", optional: true, reloadOnChange: true)
    10. .Build();
    11.  
    12. Log.Logger = new LoggerConfiguration()
    13. .ReadFrom.Configuration(configuration)
    14. .CreateLogger();
    15.  
    16. CreateWebHostBuilder(args).Build().Run();
    17. }
    18.  
    19. public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    20. WebHost.CreateDefaultBuilder(args)
    21. .ConfigureLogging((hostingContext, config) =>
    22. {
    23. config.ClearProviders();
    24. _envName = hostingContext.HostingEnvironment.EnvironmentName;
    25. })
    26. .UseStartup<Startup>();
    27. }
    configuration 部分代碼為定義設定檔的來源,也就是使用建立專案時內建的 appsettings.json,指定 Config 會隨不同環境取得不同的 appsettings.json,其中 CreateLogger 時用  ReadFrom.Configuation()  指定用 檔案內容指定取代原先落落長的代碼。
    下一步就需要在 Startup.cs 中的  ConfigureService()  新增 Serilog 至服務中,這裡使用的是內建的 DI Framework,如果用習慣 Autofac 的朋友也可以下載 autofac-serilog-integration
    1. public void ConfigureServices(IServiceCollection services)
    2. {
    3. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    4. services.AddLogging(loggingBuilder =>
    5. loggingBuilder.AddSerilog()
    6. );
    7. }
    以上設定 Serilgo 完畢,接著重新執行 Application 並觀察其輸出內容,可以看到 logging 紀錄內容已透過 Console 與檔案輸出如下
    也成功寫入檔案,預設會在指定檔名 File 後加上 日期,log_ 變成 log_20190101.txt 
    1. 2019-05-13 13:00:06.279 +08:00 [INF] User profile is available. Using 'C:\Users\marcustung\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
    2. 2019-05-13 13:00:08.112 +08:00 [INF] Request starting HTTP/1.1 GET https://localhost:5001/api/values
    3. 2019-05-13 13:00:08.178 +08:00 [INF] Executing endpoint 'SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab)'
    4. 2019-05-13 13:00:08.202 +08:00 [INF] Route matched with {action = "Get", controller = "Values"}. Executing action SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab)
    5. 2019-05-13 13:00:08.216 +08:00 [INF] Executing action method SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab) - Validation state: "Valid"
    6. 2019-05-13 13:00:08.221 +08:00 [INF] This is LogInformation
    7. 2019-05-13 13:00:08.222 +08:00 [WRN] This is LogWarning
    8. 2019-05-13 13:00:08.224 +08:00 [ERR] This is LogError
    9. 2019-05-13 13:00:08.230 +08:00 [INF] Executed action method SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 5.7992ms.
    10. 2019-05-13 13:00:08.240 +08:00 [INF] Executing ObjectResult, writing value of type 'System.String[]'.
    11. 2019-05-13 13:00:08.340 +08:00 [INF] Executed action SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab) in 131.7199ms
    12. 2019-05-13 13:00:08.344 +08:00 [INF] Executed endpoint 'SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab)'
    13. 2019-05-13 13:00:08.351 +08:00 [INF] Request finished in 245.3211ms 200 application/json; charset=utf-8
    成功紀錄 Log 在 Console 與 File 檔案,如果想要的輸出不只是檔案在 Serilog 提供多種 Provider,詳細可以參考官方網站所列的 Provided Sinks : 傳送門

    感想
    透過以上的說明,希望可以讓對 Serilog 有興趣的的朋友可以快速入門,之前也花了點時間介紹 Serilog 相關的入門 & 基本設定方式,若有興趣想了解細節的也可以了解看看,系列文連結 : 傳送門 :)

    參考
    Structured logging concepts in .NET Series
    Serilog series post
    Loggly in ASP.NET Core using Serilog

    Related Posts:

    • [NETCore] Polly 重試機制搭配 jitter 策略Jitter 策略 上一篇 [NETCore] 使用 Polly 實現重試 (Retry) 策略 分享了使用 Polly 的重試 API 幫助我們達到重試的功能,後續在尋找相關文件時看到重試時的一種策略 Jitter strategy,在高併發的情境下如果使用重試策略可能會影響到系統,若要解決用戶端因為同時間重試造成伺服器資源高峰的狀況,可以透過添加隨機時間來改善,另外在 Jitter: Making Things Bette… Read More
    • [.NETCore] ASP.NET Core - Logging 日誌初體驗 (二)前言 在上一篇文章介紹了在 ASP.Net Core 如何使用內建的 logging,以及 ILogger 與 ILoggerFactory 還有篩選記錄的方法,這篇再繼續介紹在 logging 中一些基本觀念與應用,如果有寫不清楚的地方可以搭配 MSDN 官網的 ASP.NET Core logging 一起服用,若有問題歡迎提出一起討論或是給予指導 LogLevel 紀錄 log 時候都會指定紀錄… Read More
    • [NETCore] 使用 Polly 實現重試 (Retry) 策略介紹 在開發時常常都會遇到串接其他 Server 或是第三方服務 API 的需求,當對方伺服器或是第三方服務發生問題時,或許可以在 Log 中看到回應的 HTTP 狀態碼是 404 (Not Found)、503(Service Unavailable)、504(Gateway Timeout)、500(Too Many Requests)...等當下無法正常執行的錯誤訊息,可能發生原因是因為對方 Server 不穩定,或是正在部署新版應用程式,… Read More
    • [NETCore] Polly 的超時 TimeOut 和 Wrap 策略介紹 Polly 是一套 .NET 處理瞬間故障的函式庫,提供開發人員用 Fluent API 方式及 Thread Safe 處理服務瞬間故障的策略,並提供重試(Retry)、斷路(Circuit-breaker)、超時(Timeout)、隔離(Bulkhead Isolation)、緩存(Cache)、回退(Fallback) 等機制,在上一篇 [NETCore] 使用 Polly 實現重試 (Retry) 策略 分享了 … Read More
    • [.NETCore] ASP.Net Core 使用 Big5 中文編碼 問題 在 .NET Framework 時要取得中文編碼可以使用  Encoding.GetEncoding("BIG5"),今天在練習專案時遇到類似的情境很直覺的在將 Code 套用在 .NET Core 上,沒想到竟然發生錯誤,這邊簡單紀錄遇到這問題該怎麼解決以及根本原因,有任何問題歡迎留言一起討論 解決方式  "ArgumentException: 'Big5' is not a support… Read More

    0 意見:

    張貼留言

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

    Design by Anders Noren | Blogger Theme by NewBloggerThemes.com